diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 16:03:42 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 16:03:42 +0000 |
commit | 66cec45960ce1d9c794e9399de15c138acb18aed (patch) | |
tree | 59cd19d69e9d56b7989b080da7c20ef1a3fe2a5a /ansible_collections/cisco/mso/tests | |
parent | Initial commit. (diff) | |
download | ansible-66cec45960ce1d9c794e9399de15c138acb18aed.tar.xz ansible-66cec45960ce1d9c794e9399de15c138acb18aed.zip |
Adding upstream version 7.3.0+dfsg.upstream/7.3.0+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ansible_collections/cisco/mso/tests')
140 files changed, 36099 insertions, 0 deletions
diff --git a/ansible_collections/cisco/mso/tests/.gitignore b/ansible_collections/cisco/mso/tests/.gitignore new file mode 100644 index 00000000..ea1472ec --- /dev/null +++ b/ansible_collections/cisco/mso/tests/.gitignore @@ -0,0 +1 @@ +output/ diff --git a/ansible_collections/cisco/mso/tests/integration/inventory.networking b/ansible_collections/cisco/mso/tests/integration/inventory.networking new file mode 100644 index 00000000..f18b5c3d --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/inventory.networking @@ -0,0 +1,35 @@ +[mso] +lh-dmz1-pod1-mso-v224 ansible_host=173.36.219.29 ansible_connection=local mso_hostname=173.36.219.29 +lh-dmz1-pod1-mso-v311 ansible_host=173.36.219.11 ansible_connection=local mso_hostname=173.36.219.11 + +[mso:children] +ndo + +[ndo] +lh-dmz1-pod1-ndo-v371 ansible_host=173.36.219.30 ansible_connection=ansible.netcommon.httpapi ansible_network_os=cisco.nd.nd mso_hostname=173.36.219.30 + +[all:vars] +mso_username=ansible_github_ci +mso_password="sJ94G92#8dq2hx*K4qh" +ansible_user=ansible_github_ci +ansible_ssh_pass="sJ94G92#8dq2hx*K4qh" +ansible_network_os=cisco.mso.mso +ansible_httpapi_validate_certs=False +ansible_httpapi_use_ssl=True +apic_hostname=173.36.219.190 +apic_username=ansible_github_ci +apic_password="sJ94G92#8dq2hx*K4qh" +apic_site_id=101 +aws_apic_hostname=52.52.20.121 +aws_apic_username=ansible_github_ci +aws_apic_password="sJ94G92#8dq2hx*K4qh" +aws_site_id=20 +azure_apic_hostname=104.42.26.226 +azure_apic_username=ansible_github_ci +azure_apic_password="sJ94G92#8dq2hx*K4qh" +azure_site_id=10 +ansible_python_interpreter=/usr/bin/python3.9 +mso_remote_location=173.36.219.190 +mso_radius_server=173.36.219.128 +ansible_command_timeout=300 +ansible_connect_timeoout=300
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/network-integration.requirements.txt b/ansible_collections/cisco/mso/tests/integration/network-integration.requirements.txt new file mode 100644 index 00000000..1ecd96b2 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/network-integration.requirements.txt @@ -0,0 +1 @@ +requests-toolbelt
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/target-prefixes.network b/ansible_collections/cisco/mso/tests/integration/target-prefixes.network new file mode 100644 index 00000000..74f40ea7 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/target-prefixes.network @@ -0,0 +1,2 @@ +mso +ndo
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_backup/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_backup/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_backup/aliases @@ -0,0 +1,2 @@ +# No ACI MultiSite infrastructure, so not enabled +# unsupported diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_backup/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_backup/tasks/main.yml new file mode 100644 index 00000000..c8eb21f5 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_backup/tasks/main.yml @@ -0,0 +1,582 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Shreyas Srish (@shrsr) <ssrish@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") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Clear tenant + mso_tenant: + <<: *mso_info + tenant: Tenant1 + display_name: Test_Tenant + state: absent + +- name: Ensure remote location is present + cisco.mso.mso_remote_location: + <<: *mso_info + remote_location: ansible_test + remote_protocol: scp + remote_host: '{{ mso_remote_location }}' + remote_path: '{{ mso_remote_location_path | default("/tmp") }}' + authentication_type: password + remote_username: '{{ mso_remote_location_user | default(mso_username) }}' + remote_password: '{{ mso_remote_location_password | default(mso_password) }}' + state: present + +# Backup is not supported in MSO/NDO version < 3.2 +- name: Execute tasks only for MSO version < 3.2 + when: version.current.version is version('3.2', '<') + block: + - name: Query all backups + mso_backup: + <<: *mso_info + state: query + register: query_ansibleBackup_for_delete + + - name: Remove all backups + mso_backup: + <<: *mso_info + backup_id: '{{ item.id }}' + state: absent + loop: '{{ query_ansibleBackup_for_delete.current | list | sort(attribute="name", reverse=True) }}' + + # Create Backups + - name: Create ansibleBackup1 in check mode + mso_backup: + <<: *mso_info + backup: ansibleBackup1 + description: via Ansible + location_type: local + state: present + register: cm_add_ansibleBackup1 + check_mode: yes + + - name: Verify cm_add_ansibleBackup1 + assert: + that: + - cm_add_ansibleBackup1 is changed + + - name: Create ansibleBackup1 in normal mode + mso_backup: + <<: *mso_info + backup: ansibleBackup1 + description: via Ansible + location_type: local + state: present + register: nm_add_ansibleBackup1 + + - name: Create ansibleBackup2 in normal mode + mso_backup: + <<: *mso_info + backup: ansibleBackup2 + description: via Ansible + location_type: local + state: present + register: nm_add_ansibleBackup2 + + - name: Query ansibleBackup1 to check if it exists + mso_backup: + <<: *mso_info + backup: ansibleBackup1 + state: query + register: check_ansibleBackup1 + until: + - check_ansibleBackup1.current is defined + - check_ansibleBackup1.current[0] is defined + - check_ansibleBackup1.current[0].status.statusType == "success" + retries: 50 + delay: 10 + + - name: Verify nm_add_ansibleBackup1 + assert: + that: + - nm_add_ansibleBackup1 is changed + - check_ansibleBackup1.current[0].backupEntry.metadata.name is match("ansibleBackup1_[0-9a-zA-Z]*") + + - name: Query ansibleBackup2 to check if it exists + mso_backup: + <<: *mso_info + backup: ansibleBackup2 + state: query + register: check_ansibleBackup2 + until: + - check_ansibleBackup2.current is defined + - check_ansibleBackup2.current[0] is defined + - check_ansibleBackup2.current[0].status.statusType == "success" + retries: 50 + delay: 10 + + - name: Verify nm_add_ansibleBackup2 + assert: + that: + - nm_add_ansibleBackup2 is changed + - check_ansibleBackup2.current[0].backupEntry.metadata.name is match ("ansibleBackup2_[0-9a-zA-Z]*") + + - name: Create ansibleBackup3 in normal mode + mso_backup: + <<: *mso_info + backup: ansibleBackup3 + description: via Ansible + location_type: local + state: present + register: nm_add_ansibleBackup3 + + - name: Query ansibleBackup3 to check if it exists + mso_backup: + <<: *mso_info + backup: ansibleBackup3 + state: query + register: check_ansibleBackup3 + until: + - check_ansibleBackup3.current is defined + - check_ansibleBackup3.current[0] is defined + - check_ansibleBackup3.current[0].status.statusType == "success" + retries: 50 + delay: 10 + + - name: Verify nm_add_ansibleBackup3 + assert: + that: + - nm_add_ansibleBackup3 is changed + - check_ansibleBackup3.current[0].backupEntry.metadata.name is match ("ansibleBackup3_[0-9a-zA-Z]*") + + - name: Create ansibleBackup3 in normal mode again + mso_backup: + <<: *mso_info + backup: ansibleBackup3 + description: via Ansible + location_type: local + state: present + register: nm_add_ansibleBackup3_again + + - name: Query ansibleBackup3 to check if it exists again + mso_backup: + <<: *mso_info + backup: ansibleBackup3 + state: query + register: check_ansibleBackup3_again + until: + - check_ansibleBackup3_again.current is defined + - check_ansibleBackup3_again.current[0] is defined + - check_ansibleBackup3_again.current[0].status.statusType == "success" + retries: 50 + delay: 10 + + - name: Verify nm_add_ansibleBackup3_again + assert: + that: + - check_ansibleBackup3_again.current[0].backupEntry.metadata.name is match ("ansibleBackup3_[0-9a-zA-Z]*") + + - name: Create ansibleBackupRemote1 in normal mode + mso_backup: + <<: *mso_info + backup: ansibleBackupRemote1 + description: Remote via Ansible + location_type: remote + remote_location: ansible_test + state: present + register: nm_add_ansibleBackupRemote1 + + - name: Query ansibleBackupRemote1 to check if it exists + mso_backup: + <<: *mso_info + backup: ansibleBackupRemote1 + state: query + register: check_ansibleBackupRemote1 + until: + - check_ansibleBackupRemote1.current is defined + - check_ansibleBackupRemote1.current[0] is defined + - check_ansibleBackupRemote1.current[0].status.statusType == "success" + retries: 50 + delay: 10 + + - name: Verify check_ansibleBackupRemote1 + assert: + that: + - check_ansibleBackupRemote1.current[0].backupEntry.metadata.name is match ("ansibleBackupRemote1_[0-9a-zA-Z]*") + + - name: Create ansibleBackupRemote2 in normal mode in a known path + mso_backup: + <<: *mso_info + backup: ansibleBackupRemote2 + description: Remote via Ansible + location_type: remote + remote_location: ansible_test + remote_path: test + state: present + register: nm_add_ansibleBackupRemote2_known_path + + - name: Query ansibleBackupRemote2 to check if it exists + mso_backup: + <<: *mso_info + backup: ansibleBackupRemote2 + state: query + register: check_ansibleBackupRemote2 + until: + - check_ansibleBackupRemote2.current is defined + - check_ansibleBackupRemote2.current[0] is defined + - check_ansibleBackupRemote2.current[0].status.statusType == "success" + retries: 50 + delay: 10 + + - name: Verify check_ansibleBackupRemote2 + assert: + that: + - check_ansibleBackupRemote2.current[0].backupEntry.metadata.name is match ("ansibleBackupRemote2_[0-9a-zA-Z]*") + + - name: Create ansibleBackupMove in normal mode + mso_backup: + <<: *mso_info + backup: ansibleBackupMove + description: Local to Remote via Ansible + location_type: local + state: present + + - name: Query ansibleBackupMove to check if it exists + mso_backup: + <<: *mso_info + backup: ansibleBackupMove + state: query + register: check_ansibleBackupMove + until: + - check_ansibleBackupMove.current is defined + - check_ansibleBackupMove.current[0] is defined + - check_ansibleBackupMove.current[0].status.statusType == "success" + retries: 50 + delay: 10 + + # Move Backup test + - name: Move backup from local to remote location in check mode + mso_backup: + <<: *mso_info + remote_location: ansible_test + remote_path: test + backup: ansibleBackupMove + description: Local to Remote via Ansible + state: move + check_mode: yes + when: version.current.version is version('3', '>=') + register: move_backup_cm + + - name: Move backup from local to remote location in normal mode + mso_backup: + <<: *mso_info + remote_location: ansible_test + remote_path: test + backup: ansibleBackupMove + description: Local to Remote via Ansible + state: move + when: version.current.version is version('3', '>=') + register: move_backup_nm + + - name: Move a non existent backup from local location to remote + mso_backup: + <<: *mso_info + backup: non_existent_backup + remote_location: ansible_test + remote_path: test + state: move + when: version.current.version is version('3', '>=') + register: move_non_existent_backup + ignore_errors: yes + + - name: Move a ansibleBackup3 from local location to remote + mso_backup: + <<: *mso_info + backup: ansibleBackup3 + remote_location: ansible_test + remote_path: test + state: move + when: version.current.version is version('3', '>=') + register: move_ansibleBackup3 + ignore_errors: yes + + - name: Verify move function of backup + assert: + that: + - move_backup_cm is changed + - move_backup_nm is changed + - move_non_existent_backup.msg is match ("Backup 'non_existent_backup' does not exist") + - move_ansibleBackup3.msg is match ("Multiple backups with same name found. Existing backups with similar names{{':'}} ansibleBackup3_[0-9]*, ansibleBackup3_[0-9]*") + when: version.current.version is version('3', '>=') + + # Download Backup + - name: Create a directory if it does not exist + ansible.builtin.file: + path: './{{mso_hostname}}' + state: directory + mode: '0755' + + - name: Download backup in check mode + mso_backup: + <<: *mso_info + backup: ansibleBackup2 + destination: './{{mso_hostname}}' + state: download + register: download_ansibleBackup2_cm + check_mode: yes + + - name: Download backup + mso_backup: + <<: *mso_info + backup: ansibleBackup2 + destination: './{{mso_hostname}}' + state: download + register: download_ansibleBackup2 + + - name: Download non existent backup + mso_backup: + <<: *mso_info + backup: non_existent_backup + destination: './{{mso_hostname}}' + state: download + ignore_errors: yes + register: download_non_existent_backup + + - name: Download backup ansibleBackup3 + mso_backup: + <<: *mso_info + backup: ansibleBackup3 + destination: './{{mso_hostname}}' + state: download + ignore_errors: yes + register: download_ansibleBackup3 + + - name: Verify download of backup + assert: + that: + - download_ansibleBackup2_cm is changed + - download_ansibleBackup2 is changed + - download_non_existent_backup.msg is match ("Backup 'non_existent_backup' does not exist") + - download_ansibleBackup3.msg is match ("Multiple backups with same name found. Existing backups with similar names{{':'}} ansibleBackup3_[0-9]*, ansibleBackup3_[0-9]*") + + - name: Remove backup ansibleBackup2 for testing purpose + mso_backup: + <<: *mso_info + backup: ansibleBackup2 + state: absent + + # Find Backup + - name: Find backup + find: + paths: './{{mso_hostname}}' + patterns: "*.tar.gz" + register: backup_match + + # Upload Backup + - name: Upload a backup from local location in check mode + mso_backup: + <<: *mso_info + backup: "{{ backup_match.files[0].path }}" + state: upload + register: upload_backup_cm + check_mode: yes + + - name: Upload a backup from local location + mso_backup: + <<: *mso_info + backup: "{{ backup_match.files[0].path }}" + state: upload + register: upload_backup + + - name: Upload a non existent backup from local location + mso_backup: + <<: *mso_info + backup: non_existent_backup + state: upload + register: upload_non_existent_backup + ignore_errors: yes + + - name: Verify upload of backup + assert: + that: + - upload_backup is changed + - upload_backup_cm is changed + - upload_non_existent_backup.msg is match ("Backup file 'non_existent_backup' not found!") + + # Restore Backup + - name: Restore non existent backup + mso_backup: + <<: *mso_info + backup: non_existent_backup + state: restore + ignore_errors: yes + when: version.current.version is version('2.2.4e', '!=') + register: restore_non_existent_backup + + - name: Restore backup ansibleBackup3 + mso_backup: + <<: *mso_info + backup: ansibleBackup3 + state: restore + ignore_errors: yes + when: version.current.version is version('2.2.4e', '!=') + register: restore_ansibleBackup3 + + - name: Verify restore of backup + assert: + that: + - restore_non_existent_backup.msg is match ("Backup 'non_existent_backup' does not exist") + - restore_ansibleBackup3.msg is match ("Multiple backups with same name found. Existing backups with similar names{{':'}} ansibleBackup3_[0-9]*, ansibleBackup3_[0-9]*") + when: version.current.version is version('2.2.4e', '!=') + + - name: Add a new tenant + mso_tenant: + <<: *mso_info + tenant: Tenant1 + display_name: Test_Tenant + state: present + when: version.current.version is version('2.2.4e', '!=') + + - name: Restore backup in check mode + mso_backup: + <<: *mso_info + backup: ansibleBackup1 + state: restore + check_mode: yes + when: version.current.version is version('2.2.4e', '!=') + register: restore_cm + + - name: Verify retore in check mode + assert: + that: + - restore_cm is changed + when: version.current.version is version('2.2.4e', '!=') + + - name: Restore backup + mso_backup: + <<: *mso_info + backup: ansibleBackup1 + state: restore + when: version.current.version is version('2.2.4e', '!=') + + - name: Pause for 6 minutes after restore + pause: + minutes: 6 + + - name: Query Tenant1 + mso_tenant: + <<: *mso_info + tenant: Tenant1 + state: query + when: version.current.version is version('2.2.4e', '!=') + register: query_non_existent_tenant + + - name: Verify non existent Tenant + assert: + that: + - query_non_existent_tenant is not changed + - query_non_existent_tenant.current == {} + when: version.current.version is version('2.2.4e', '!=') + + # Query a Backup + - name: Query ansibleBackup3 + mso_backup: + <<: *mso_info + backup: ansibleBackup3 + state: query + register: query_ansibleBackup3 + + - name: Verify query_ansibleBackup3 + assert: + that: + - query_ansibleBackup3 is not changed + - query_ansibleBackup3.current | length == 2 + + # Query All + - name: Query All + mso_backup: + <<: *mso_info + state: query + register: query_all_backups + + - name: Verify query_all_backups + assert: + that: + - query_all_backups is not changed + - query_all_backups.current | selectattr("name", "match", "^ansibleBackup.*") | list | length == 7 + + # Remove Backup + - name: Remove ansibleBackup1 in check mode + mso_backup: + <<: *mso_info + backup: ansibleBackup1 + state: absent + check_mode: yes + register: cm_remove_ansibleBackup1 + + - name: Verify cm_remove_ansibleBackup1 + assert: + that: + - cm_remove_ansibleBackup1 is changed + + - name: Remove ansibleBackup1 in normal mode + mso_backup: + <<: *mso_info + backup: ansibleBackup1 + state: absent + register: nm_remove_ansibleBackup1 + + - name: Verify nm_remove_ansibleBackup1 + assert: + that: + - nm_remove_ansibleBackup1 is changed + + - name: Remove ansibleBackup1 in normal mode again + mso_backup: + <<: *mso_info + backup: ansibleBackup1 + state: absent + register: nm_remove_ansibleBackup1_2 + + - name: Verify nm_remove_ansibleBackup1_2 + assert: + that: + - nm_remove_ansibleBackup1_2 is not changed + + - name: Remove ansibleBackup3 in normal mode + mso_backup: + <<: *mso_info + backup: ansibleBackup3 + state: absent + ignore_errors: yes + register: nm_remove_ansibleBackup3 + + - name: Verify nm_remove_ansibleBackup3 + assert: + that: + - nm_remove_ansibleBackup3.msg is match ("Multiple backups with same name found. Existing backups with similar names{{':'}} ansibleBackup3_[0-9]*, ansibleBackup3_[0-9]*") + + - name: Query non_existent_backup + mso_backup: + <<: *mso_info + backup: nonExistentBackup + state: query + register: query_non_existent_backup + + - name: Verify query_non_existent_backup + assert: + that: + - query_non_existent_backup is not changed diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_backup_schedule/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_backup_schedule/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_backup_schedule/aliases @@ -0,0 +1,2 @@ +# No ACI MultiSite infrastructure, so not enabled +# unsupported diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_backup_schedule/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_backup_schedule/tasks/main.yml new file mode 100644 index 00000000..20c7bf3b --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_backup_schedule/tasks/main.yml @@ -0,0 +1,266 @@ +# Test code for the MSO modules +# Copyright: (c) 2022, 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: 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") }}' + +- name: Delete existing backup schedule + cisco.mso.mso_backup_schedule: + <<: *mso_info + state: absent + delegate_to: localhost + +- name: Ensure remote location is present + cisco.mso.mso_remote_location: + <<: *mso_info + remote_location: ansible_test + remote_protocol: scp + remote_host: '{{ mso_remote_location }}' + remote_path: '{{ mso_remote_location_path | default("/tmp") }}' + authentication_type: password + remote_username: '{{ mso_remote_location_user | default(mso_username) }}' + remote_password: '{{ mso_remote_location_password | default(mso_password) }}' + state: present + +# TESTS + +- name: Get empty backup schedule + cisco.mso.mso_backup_schedule: + <<: *mso_info + state: query + delegate_to: localhost + register: no_schedule + +- name: Verify empty backup schedule + assert: + that: + - no_schedule is not changed + - no_schedule.current == {} + +- name: Set backup schedule (check mode) + cisco.mso.mso_backup_schedule: + <<: *mso_info + frequency_unit: hours + frequency_length: 7 + remote_location: ansible_test + state: present + check_mode: yes + delegate_to: localhost + register: cm_schedule_create + +- name: Set backup schedule (normal mode) + cisco.mso.mso_backup_schedule: + <<: *mso_info + frequency_unit: hours + frequency_length: 7 + remote_location: ansible_test + state: present + delegate_to: localhost + register: nm_schedule_create + +# add date tests +- name: Verify success set backup schedule + assert: + that: + - cm_schedule_create is changed + - cm_schedule_create.current.intervalLength == 7 + - cm_schedule_create.current.intervalTimeUnit == "HOURS" + - cm_schedule_create.current.locationType == "remote" + - nm_schedule_create is changed + - nm_schedule_create.current.timeInterval.length == 7 + - nm_schedule_create.current.timeInterval.unit == "HOURS" + - nm_schedule_create.current.callbackWSRequest.methodBody.locationType == "remote" + - "'00:00:00' in nm_schedule_create.current.firstScheduledAt" + +- name: Adjust backup schedule (check mode) + cisco.mso.mso_backup_schedule: + <<: *mso_info + frequency_unit: days + frequency_length: 1 + remote_location: ansible_test + state: present + check_mode: yes + delegate_to: localhost + register: cm_schedule_adjust + +- name: Adjust backup schedule (normal mode) + cisco.mso.mso_backup_schedule: + <<: *mso_info + frequency_unit: days + frequency_length: 1 + remote_location: ansible_test + state: present + delegate_to: localhost + register: nm_schedule_adjust + +- name: Verify success set backup schedule + assert: + that: + - cm_schedule_adjust is changed + - cm_schedule_adjust.current.intervalLength == 1 + - cm_schedule_adjust.current.intervalTimeUnit == "DAYS" + - cm_schedule_adjust.current.locationType == "remote" + - nm_schedule_adjust is changed + - nm_schedule_adjust.current.timeInterval.length == 1 + - nm_schedule_adjust.current.timeInterval.unit == "DAYS" + - nm_schedule_adjust.current.callbackWSRequest.methodBody.locationType == "remote" + +- name: Get backup schedule + cisco.mso.mso_backup_schedule: + <<: *mso_info + state: query + delegate_to: localhost + register: schedule + +- name: Verify success get backup schedule + assert: + that: + - schedule is not changed + - nm_schedule_adjust.current.timeInterval.length == 1 + - nm_schedule_adjust.current.timeInterval.unit == "DAYS" + - nm_schedule_adjust.current.callbackWSRequest.methodBody.locationType == "remote" + +- name: Delete backup schedule (check mode) + cisco.mso.mso_backup_schedule: + <<: *mso_info + state: absent + check_mode: yes + delegate_to: localhost + +- name: Delete backup schedule (normal mode) + cisco.mso.mso_backup_schedule: + <<: *mso_info + state: absent + delegate_to: localhost + +- name: Get empty backup schedule + cisco.mso.mso_backup_schedule: + <<: *mso_info + state: query + delegate_to: localhost + register: no_schedule + +- name: Verify empty backup schedule + assert: + that: + - no_schedule is not changed + - no_schedule.current == {} + +- name: Set backup schedule incorrect time to parse (normal mode) + cisco.mso.mso_backup_schedule: + <<: *mso_info + start_time: no_time + frequency_unit: hours + frequency_length: 7 + remote_location: ansible_test + state: present + delegate_to: localhost + register: nm_schedule_incorrect_time + ignore_errors: yes + +- name: Set backup schedule incorrect date to parse (normal mode) + cisco.mso.mso_backup_schedule: + <<: *mso_info + start_date: no_date + frequency_unit: hours + frequency_length: 7 + remote_location: ansible_test + state: present + delegate_to: localhost + register: nm_schedule_incorrect_date + ignore_errors: yes + +- name: Set backup schedule incorrect date object create from start_date (normal mode) + cisco.mso.mso_backup_schedule: + <<: *mso_info + start_date: "2030-15-45" + frequency_unit: hours + frequency_length: 7 + remote_location: ansible_test + state: present + delegate_to: localhost + register: nm_schedule_incorrect_date_from_start_date + ignore_errors: yes + +- name: Set backup schedule incorrect date object create from start_time (normal mode) + cisco.mso.mso_backup_schedule: + <<: *mso_info + start_time: "2030:15:45" + frequency_unit: hours + frequency_length: 7 + remote_location: ansible_test + state: present + delegate_to: localhost + register: nm_schedule_incorrect_time_from_start_time + ignore_errors: yes + +- name: Verify error messages + assert: + that: + - nm_schedule_incorrect_time is failed + - nm_schedule_incorrect_time.msg.startswith("Failed to parse time format") + - nm_schedule_incorrect_date is failed + - nm_schedule_incorrect_date.msg.startswith("Failed to parse date format") + - nm_schedule_incorrect_date_from_start_date is failed + - nm_schedule_incorrect_date_from_start_date.msg.startswith("Failed to create datetime object") + - nm_schedule_incorrect_time_from_start_time is failed + - nm_schedule_incorrect_time_from_start_time.msg.startswith("Failed to create datetime object") + +- name: Set backup schedule full (normal mode) + cisco.mso.mso_backup_schedule: + <<: *mso_info + start_date: "2030-11-12" + start_time: "00:00:01" + frequency_unit: days + frequency_length: 1 + remote_location: ansible_test + remote_path: remote_add + state: present + delegate_to: localhost + register: nm_schedule_full + +- name: Verify success set backup schedule + assert: + that: + - nm_schedule_full is changed + - nm_schedule_full.current.timeInterval.length == 1 + - nm_schedule_full.current.timeInterval.unit == "DAYS" + - nm_schedule_full.current.callbackWSRequest.methodBody.locationType == "remote" + - nm_schedule_full.current.firstScheduledAt == "2030-11-12T00:00:01.000Z" + - nm_schedule_full.current.nextScheduleAt == "2030-11-13T00:00:01.000Z" + +- name: Delete backup schedule (normal mode) + cisco.mso.mso_backup_schedule: + <<: *mso_info + state: absent + delegate_to: localhost + +- name: Get empty backup schedule + cisco.mso.mso_backup_schedule: + <<: *mso_info + state: query + delegate_to: localhost + register: no_schedule + +- name: Verify empty backup schedule + assert: + that: + - no_schedule is not changed + - no_schedule.current == {}
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_dhcp_option_policy/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_dhcp_option_policy/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_dhcp_option_policy/aliases @@ -0,0 +1,2 @@ +# No ACI MultiSite infrastructure, so not enabled +# unsupported diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_dhcp_option_policy/tasks/main.yaml b/ansible_collections/cisco/mso/tests/integration/targets/mso_dhcp_option_policy/tasks/main.yaml new file mode 100644 index 00000000..af155ce3 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_dhcp_option_policy/tasks/main.yaml @@ -0,0 +1,298 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Lionel Hercot (@lhercot) <lhercot@cisco.com> +# Copyright: (c) 2020, Jorge Gomez (@jgomezve) <jgomezve@cisco.com> (based on mso_dhcp_relay_policy test case) + +# 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") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Execute tasks only for MSO version < 4.0 + when: version.current.version is version('4.0', '<') + block: + - name: Ensure tenant ansible_test exist + mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + state: present + register: ansible_tenant + + - name: Stop consuming DHCP Policy CLIENT_BD + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + bd: CLIENT_BD + vrf: + name: VRF1 + state: absent + ignore_errors: yes + + - name: Stop consuming DHCP Policy ansible_test_2 + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + bd: ansible_test_2 + state: absent + ignore_errors: yes + + - name: Stop consuming DHCP Policy ansible_test_multiple_dhcp + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + bd: ansible_test_multiple_dhcp + state: absent + ignore_errors: yes + + - name: Stop consuming DHCP Policy ansible_test_5 + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test_2") }}' + template: Template 5 + bd: ansible_test_5 + state: absent + ignore_errors: yes + + - name: Remove DHCP Option Policies + mso_dhcp_option_policy: + <<: *mso_info + dhcp_option_policy: '{{ item }}' + state: absent + loop: + - ansible_dhcp_option_1 + - ansible_dhcp_option_2 + - ansible_test_dhcp_policy_option1 + - ansible_test_dhcp_policy_option2 + - ansible_test_dhcp_policy_option3 + + # ADD DHCP Policy + - name: Add a new DHCP Option Policy 1 (check mode) + mso_dhcp_option_policy: &create_dhcp + <<: *mso_info + dhcp_option_policy: ansible_dhcp_option_1 + description: "My Test DHCP Policy 1" + tenant: ansible_test + state: present + check_mode: yes + register: dhcp_pol1_cm + + - name: Add a new DHCP Option Policy 1 (normal mode) + mso_dhcp_option_policy: + <<: *create_dhcp + register: dhcp_pol1_nm + + - name: Verify dhcp_pol1_cm and dhcp_pol1_nm + assert: + that: + - dhcp_pol1_cm is changed + - dhcp_pol1_nm is changed + - dhcp_pol1_cm.current.name == dhcp_pol1_nm.current.name == 'ansible_dhcp_option_1' + - dhcp_pol1_cm.current.desc == dhcp_pol1_nm.current.desc == 'My Test DHCP Policy 1' + - dhcp_pol1_cm.current.policySubtype == dhcp_pol1_nm.current.policySubtype == 'option' + - dhcp_pol1_cm.current.policyType == dhcp_pol1_nm.current.policyType == 'dhcp' + - dhcp_pol1_cm.current.tenantId == dhcp_pol1_nm.current.tenantId == ansible_tenant.current.id + + - name: Add a new DHCP Option Policy 1 again (check mode) + mso_dhcp_option_policy: + <<: *create_dhcp + check_mode: yes + register: dhcp_pol1_again_cm + + - name: Add a new DHCP Option Policy 1 again (normal mode) + mso_dhcp_option_policy: + <<: *create_dhcp + register: dhcp_pol1_again_nm + + - name: Verify dhcp_pol1_again_cm and dhcp_pol1_again_nm + assert: + that: + - dhcp_pol1_again_cm is not changed + - dhcp_pol1_again_nm is not changed + - dhcp_pol1_again_cm.current.name == dhcp_pol1_again_nm.current.name == 'ansible_dhcp_option_1' + - dhcp_pol1_again_cm.current.desc == dhcp_pol1_again_nm.current.desc == 'My Test DHCP Policy 1' + - dhcp_pol1_again_cm.current.policySubtype == dhcp_pol1_again_nm.current.policySubtype == 'option' + - dhcp_pol1_again_cm.current.policyType == dhcp_pol1_again_nm.current.policyType == 'dhcp' + - dhcp_pol1_again_cm.current.tenantId == dhcp_pol1_again_nm.current.tenantId == ansible_tenant.current.id + + - name: Add a new DHCP Option Policy 2 (normal mode) + mso_dhcp_option_policy: + <<: *create_dhcp + dhcp_option_policy: ansible_dhcp_option_2 + + - name: Change DHCP Option Policy 1 description (check mode) + mso_dhcp_option_policy: + <<: *create_dhcp + description: "My Changed Test DHCP Policy 1" + check_mode: yes + register: change_dhcp_pol1_cm + + - name: Change DHCP Option Policy 1 description (normal mode) + mso_dhcp_option_policy: + <<: *create_dhcp + description: "My Changed Test DHCP Policy 1" + register: change_dhcp_pol1_nm + + - name: Verify change_dhcp_pol1_cm and change_dhcp_pol1_nm + assert: + that: + - change_dhcp_pol1_cm is changed + - change_dhcp_pol1_nm is changed + - change_dhcp_pol1_cm.current.name == change_dhcp_pol1_nm.current.name == 'ansible_dhcp_option_1' + - change_dhcp_pol1_cm.current.desc == change_dhcp_pol1_nm.current.desc == 'My Changed Test DHCP Policy 1' + - change_dhcp_pol1_cm.current.policySubtype == change_dhcp_pol1_nm.current.policySubtype == 'option' + - change_dhcp_pol1_cm.current.policyType == change_dhcp_pol1_nm.current.policyType == 'dhcp' + - change_dhcp_pol1_cm.current.tenantId == change_dhcp_pol1_nm.current.tenantId == ansible_tenant.current.id + + # QUERY A DHCP OPTION POLICY + - name: Query DHCP Option Policy 1 (check mode) + mso_dhcp_option_policy: &query_dhcp + <<: *mso_info + dhcp_option_policy: ansible_dhcp_option_1 + state: query + check_mode: yes + register: dhcp_pol1_query_cm + + - name: Query DHCP Option Policy 1 (normal mode) + mso_dhcp_option_policy: + <<: *query_dhcp + register: dhcp_pol1_query_nm + + - name: Verify dhcp_pol1_query + assert: + that: + - dhcp_pol1_query_cm is not changed + - dhcp_pol1_query_nm is not changed + - dhcp_pol1_query_cm.current.name == dhcp_pol1_query_nm.current.name == 'ansible_dhcp_option_1' + - dhcp_pol1_query_cm.current.desc == dhcp_pol1_query_nm.current.desc == 'My Changed Test DHCP Policy 1' + - dhcp_pol1_query_cm.current.policySubtype == dhcp_pol1_query_nm.current.policySubtype == 'option' + - dhcp_pol1_query_cm.current.policyType == dhcp_pol1_query_nm.current.policyType == 'dhcp' + + # QUERY A NON-EXISTING DHCP OPTION POLICY + - name: Query non-existing DHCP Option Policy (normal mode) + mso_dhcp_option_policy: + <<: *mso_info + dhcp_option_policy: non_existing + state: query + register: quey_non_dhcp_pol + + - name: Verify quey_non_dhcp_pol + assert: + that: + - quey_non_dhcp_pol is not changed + + # QUERY ALL DHCP OPTION POLICIES + - name: Query all DHCP Option Policies (normal mode) + mso_dhcp_option_policy: + <<: *mso_info + state: query + register: dhcp_policies_query + + - name: Verify dhcp_policies_query + assert: + that: + - dhcp_policies_query is not changed + - dhcp_policies_query.current | length == 2 + + # REMOVE DHCP POLICY + - name: Remove DHCP Option Policy 1 (check mode) + mso_dhcp_option_policy: &remove_dhcp + <<: *mso_info + dhcp_option_policy: ansible_dhcp_option_1 + state: absent + check_mode: yes + register: dhcp_pol1_removed_cm + + - name: Remove DHCP Option Policy 1 (normal mode) + mso_dhcp_option_policy: + <<: *remove_dhcp + register: dhcp_pol1_removed_nm + + - name: Verify dhcp_policies_removed + assert: + that: + - dhcp_pol1_removed_cm is changed + - dhcp_pol1_removed_nm is changed + - dhcp_pol1_removed_cm.current == dhcp_pol1_removed_nm.current == {} + + # REMOVE DHCP POLICY AGAIN + - name: Remove DHCP Option Policy 1 again (check mode) + mso_dhcp_option_policy: + <<: *remove_dhcp + check_mode: yes + register: dhcp_pol1_removed_again_cm + + - name: Remove DHCP Option Policy 1 again (normal mode) + mso_dhcp_option_policy: + <<: *remove_dhcp + register: dhcp_pol1_removed_again_nm + + - name: Verify dhcp_pol1_removed_again + assert: + that: + - dhcp_pol1_removed_again_cm is not changed + - dhcp_pol1_removed_again_nm is not changed + - dhcp_pol1_removed_again_cm.current == dhcp_pol1_removed_again_nm.current == {} + - dhcp_pol1_removed_again_cm.previous == dhcp_pol1_removed_again_nm.previous == {} + + + # USE A NON-EXISTING TENANT + - name: Non Existing Tenant for DHCP Option Policy 3 (normal mode) + mso_dhcp_option_policy: + <<: *mso_info + dhcp_option_policy: ansible_dhcp_option_3 + description: "My Test DHCP Policy 3" + tenant: non_existing + state: present + ignore_errors: yes + register: nm_non_existing_tenant + + - name: Verify nm_non_existing_tenant + assert: + that: + - nm_non_existing_tenant is not changed + - nm_non_existing_tenant.msg == "Tenant 'non_existing' is not valid tenant name." + + # CLEAN UP + - name: Stop consuming DHCP Policy + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + bd: CLIENT_BD + vrf: + name: VRF1 + state: absent + ignore_errors: yes + + - name: Remove DHCP Option Policies + mso_dhcp_option_policy: + <<: *mso_info + dhcp_option_policy: '{{ item }}' + state: absent + loop: + - ansible_dhcp_option_1 + - ansible_dhcp_option_2
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_dhcp_option_policy_option/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_dhcp_option_policy_option/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_dhcp_option_policy_option/aliases @@ -0,0 +1,2 @@ +# No ACI MultiSite infrastructure, so not enabled +# unsupported diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_dhcp_option_policy_option/tasks/main.yaml b/ansible_collections/cisco/mso/tests/integration/targets/mso_dhcp_option_policy_option/tasks/main.yaml new file mode 100644 index 00000000..b41c4861 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_dhcp_option_policy_option/tasks/main.yaml @@ -0,0 +1,444 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Lionel Hercot (@lhercot) <lhercot@cisco.com> +# Copyright: (c) 2020, Jorge Gomez (@jgomezve) <jgomezve@cisco.com> (based on mso_dhcp_relay_policy test case) + +# 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") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Execute tasks only for MSO version < 4.0 + when: version.current.version is version('4.0', '<') + block: + - name: Remove options from DHCP Option Policy + mso_dhcp_option_policy_option: + <<: *mso_info + dhcp_option_policy: ansible_dhcp_option_1 + name: "{{ item }}" + state: absent + loop: + - ansibletest + - ansibletest2 + ignore_errors: yes + + - name: Stop consuming DHCP Policy + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + bd: CLIENT_BD + vrf: + name: VRF1 + state: present + ignore_errors: yes + + - name: Remove DHCP Relay Policy 1 + mso_dhcp_relay_policy: + <<: *mso_info + dhcp_relay_policy: '{{ item }}' + state: absent + loop: + - ansible_dhcp_relay_1 + - ansible_dhcp_relay_2 + + - name: Remove DHCP Option Policies + mso_dhcp_option_policy: + <<: *mso_info + dhcp_option_policy: '{{ item }}' + state: absent + ignore_errors: yes + loop: + - ansible_dhcp_option_1 + - ansible_dhcp_option_2 + + - name: Undeploy sites in schema 1 template 1 + mso_schema_template_deploy: + <<: *mso_info + template: Template 1 + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ item }}' + state: undeploy + ignore_errors: yes + loop: + - '{{ mso_site | default("ansible_test") }}' + - '{{ mso_site | default("ansible_test") }}_2' + - 'aws_{{ mso_site | default("ansible_test") }}' + - 'azure_{{ mso_site | default("ansible_test") }}' + + - name: Undeploy sites in schema 1 template 2 + mso_schema_template_deploy: + <<: *mso_info + template: Template 2 + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ item }}' + state: undeploy + ignore_errors: yes + loop: + - '{{ mso_site | default("ansible_test") }}' + - '{{ mso_site | default("ansible_test") }}_2' + - 'aws_{{ mso_site | default("ansible_test") }}' + - 'azure_{{ mso_site | default("ansible_test") }}' + + - name: Remove schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + + - name: Ensure tenant ansible_test exist + mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + state: present + register: tenant_ansible + + - name: Ensure schema 1 with Template 1 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template 1 + state: present + + - name: Add a new VRF + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF1 + state: present + + - name: Add BD + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + bd: CLIENT_BD + vrf: + name: VRF1 + state: present + + # ADD DHCP RELAY AND OPTION POLICY + - name: Add a new DHCP Option Policy 1 (Normal mode) + mso_dhcp_option_policy: + <<: *mso_info + dhcp_option_policy: ansible_dhcp_option_1 + description: "My Test DHCP Policy 1" + tenant: ansible_test + state: present + + - name: Add a new DHCP Relay Policy 1 (Normal mode) + mso_dhcp_relay_policy: + <<: *mso_info + dhcp_relay_policy: ansible_dhcp_relay_1 + description: "My Test DHCP Policy 1" + tenant: ansible_test + state: present + + # ADD OPTION TO DHCP OPTION POLICY + - name: Add Option to DHCP Option Policy (check mode) + mso_dhcp_option_policy_option: &create_option + <<: *mso_info + dhcp_option_policy: ansible_dhcp_option_1 + name: ansibletest + id: 1 + data: DHCP Data + state: present + check_mode: yes + register: dhcp_pol1_opt1_cm + + - name: Add Option to DHCP Option Policy (normal mode) + mso_dhcp_option_policy_option: + <<: *create_option + register: dhcp_pol1_opt1_nm + + - name: Verify dhcp_pol1_opt1 + assert: + that: + - dhcp_pol1_opt1_cm is changed + - dhcp_pol1_opt1_nm is changed + - dhcp_pol1_opt1_cm.current.name == dhcp_pol1_opt1_nm.current.name == 'ansibletest' + - dhcp_pol1_opt1_cm.current.id == dhcp_pol1_opt1_nm.current.id == '1' + - dhcp_pol1_opt1_cm.current.data == dhcp_pol1_opt1_nm.current.data == 'DHCP Data' + + - name: Add Option to DHCP Option Policy again (check mode) + mso_dhcp_option_policy_option: + <<: *create_option + check_mode: yes + register: dhcp_pol1_opt1_again_cm + + - name: Add Option to DHCP Option Policy again (normal mode) + mso_dhcp_option_policy_option: + <<: *create_option + register: dhcp_pol1_opt1_again_nm + + - name: Verify dhcp_pol1_opt1_again + assert: + that: + - dhcp_pol1_opt1_again_cm is not changed + - dhcp_pol1_opt1_again_nm is not changed + - dhcp_pol1_opt1_again_cm.current.name == dhcp_pol1_opt1_again_nm.current.name == 'ansibletest' + - dhcp_pol1_opt1_again_cm.current.id == dhcp_pol1_opt1_again_nm.current.id == '1' + - dhcp_pol1_opt1_again_cm.current.data == dhcp_pol1_opt1_again_nm.current.data == 'DHCP Data' + + - name: Change Option IP to DHCP Option Policy (check mode) + mso_dhcp_option_policy_option: + <<: *create_option + data: Changed DHCP Data + check_mode: yes + register: dhcp_pol1_opt1_change_cm + + - name: Change Option IP to DHCP Option Policy (normal mode) + mso_dhcp_option_policy_option: + <<: *create_option + data: Changed DHCP Data + register: dhcp_pol1_opt1_change_nm + + - name: Verify dhcp_pol1_opt1_change + assert: + that: + - dhcp_pol1_opt1_change_cm is changed + - dhcp_pol1_opt1_change_nm is changed + - dhcp_pol1_opt1_change_cm.current.name == dhcp_pol1_opt1_change_nm.current.name == 'ansibletest' + - dhcp_pol1_opt1_change_cm.current.id == dhcp_pol1_opt1_change_nm.current.id == '1' + - dhcp_pol1_opt1_change_cm.current.data == dhcp_pol1_opt1_change_nm.current.data == 'Changed DHCP Data' + + - name: Add 2nd Option to DHCP Option Policy (check mode) + mso_dhcp_option_policy_option: + <<: *create_option + name: ansibletest2 + check_mode: yes + register: dhcp_pol1_opt2_cm + + - name: Add 2nd Option to DHCP Option Policy (normal mode) + mso_dhcp_option_policy_option: + <<: *create_option + name: ansibletest2 + register: dhcp_pol1_opt2_nm + + - name: Verify dhcp_pol1_opt2 + assert: + that: + - dhcp_pol1_opt2_cm is changed + - dhcp_pol1_opt2_nm is changed + - dhcp_pol1_opt2_cm.current.name == dhcp_pol1_opt2_nm.current.name == 'ansibletest2' + - dhcp_pol1_opt2_cm.current.id == dhcp_pol1_opt2_nm.current.id == '1' + - dhcp_pol1_opt2_cm.current.data == dhcp_pol1_opt2_nm.current.data == 'DHCP Data' + + # QUERY OPTION FROM DHCP OPTION POLICY + - name: Query Option from DHCP Option Policy (check mode) + mso_dhcp_option_policy_option: &query_option + <<: *mso_info + dhcp_option_policy: ansible_dhcp_option_1 + name: ansibletest + state: query + register: dhcp_pol1_opt1_query_cm + + - name: Query Option from DHCP Option Policy (normal mode) + mso_dhcp_option_policy_option: + <<: *query_option + register: dhcp_pol1_opt1_query_nm + + - name: Query nonexisting Option from DHCP Option Policy + mso_dhcp_option_policy_option: + <<: *query_option + name: nonexisting + state: query + register: dhcp_pol1_opt1_query_non_existing + + - name: Query all Options from a DHCP Option Policy + mso_dhcp_option_policy_option: + <<: *mso_info + dhcp_option_policy: ansible_dhcp_option_1 + state: query + register: dhcp_pol1_query_all + + - name: Verify all query variables + assert: + that: + - dhcp_pol1_opt1_query_cm is not changed + - dhcp_pol1_opt1_query_nm is not changed + - dhcp_pol1_opt1_query_non_existing is not changed + - dhcp_pol1_query_all is not changed + - dhcp_pol1_opt1_query_cm.current.name == dhcp_pol1_opt1_query_nm.current.name == 'ansibletest' + - dhcp_pol1_opt1_query_cm.current.id == dhcp_pol1_opt1_query_nm.current.id == '1' + - dhcp_pol1_opt1_query_cm.current.data == dhcp_pol1_opt1_query_nm.current.data == 'Changed DHCP Data' + - dhcp_pol1_opt1_query_non_existing.current == {} + - dhcp_pol1_query_all.current | length == 2 + + # REMOVE OPTION FROM DHCP OPTION POLICY + - name: Remove Option from DHCP Option Policy (check mode) + mso_dhcp_option_policy_option: &delete_option + <<: *mso_info + dhcp_option_policy: ansible_dhcp_option_1 + name: ansibletest + state: absent + check_mode: yes + register: dhcp_pol1_opt1_del_cm + + - name: Remove Option from DHCP Option Policy (normal mode) + mso_dhcp_option_policy_option: + <<: *delete_option + register: dhcp_pol1_opt1_del_nm + + - name: Verify dhcp_pol1_opt1_del + assert: + that: + - dhcp_pol1_opt1_del_cm is changed + - dhcp_pol1_opt1_del_nm is changed + - dhcp_pol1_opt1_del_cm.current == dhcp_pol1_opt1_del_nm.current == {} + + - name: Remove Option from DHCP Option Policy again (check mode) + mso_dhcp_option_policy_option: + <<: *delete_option + check_mode: yes + register: dhcp_pol1_opt1_del_again_cm + + - name: Remove Option from DHCP Option Policy again (normal mode) + mso_dhcp_option_policy_option: + <<: *delete_option + register: dhcp_pol1_opt1_del_again_nm + + - name: Verify dhcp_pol1_opt1_again_del + assert: + that: + - dhcp_pol1_opt1_del_again_cm is not changed + - dhcp_pol1_opt1_del_again_nm is not changed + - dhcp_pol1_opt1_del_again_cm.current == dhcp_pol1_opt1_del_again_nm.current == {} + + - name: Remove Non-Existing Option + mso_dhcp_option_policy_option: + <<: *delete_option + name: nonexisting + register: dhcp_pol1_opt1_del_nm_non_existing + + - name: Verify dhcp_pol1_opt1_del_nm_non_existing + assert: + that: + - dhcp_pol1_opt1_del_nm_non_existing is not changed + - dhcp_pol1_opt1_del_nm_non_existing.current == {} + + # CONSUME DHCP POLICIES + - name: Get DHCP Relay Policy version + mso_dhcp_relay_policy: + <<: *mso_info + dhcp_relay_policy: ansible_dhcp_relay_1 + state: query + register: dhcp_relay_policy_version + + - name: Get DHCP Option Policy version + mso_dhcp_option_policy: + <<: *mso_info + dhcp_option_policy: ansible_dhcp_option_1 + state: query + register: dhcp_option_policy_version + + - name: Consume DHCP Policy + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + bd: CLIENT_BD + vrf: + name: VRF1 + dhcp_policy: + name: "{{ dhcp_relay_policy_version.current.name }}" + version: "{{ dhcp_relay_policy_version.current.version | int }}" + dhcp_option_policy: + name: "{{ dhcp_option_policy_version.current.name }}" + version: "{{ dhcp_option_policy_version.current.version | int }}" + state: present + register: bd_dhcp_policy + + - name: Stop consuming DHCP Policy + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + bd: CLIENT_BD + vrf: + name: VRF1 + state: present + register: bd_dhcp_policy + + # QUERY OPTION FROM non_existing DHCP OPTION POLICY + - name: Query Option from DHCP Option Policy (check mode) + mso_dhcp_option_policy_option: + <<: *mso_info + dhcp_option_policy: nonexisting + state: query + ignore_errors: yes + register: dhcp_non_existing + + - name: Verify dhcp_non_existing + assert: + that: + - dhcp_non_existing is not changed + - dhcp_non_existing.msg == "DHCP Option Policy 'nonexisting' is not a valid DHCP Option Policy name." + + # CLEAN UP + - name: Remove options from DHCP Option Policy + mso_dhcp_option_policy_option: + <<: *mso_info + dhcp_option_policy: ansible_dhcp_option_1 + name: "{{ item }}" + state: absent + loop: + - ansibletest + - ansibletest2 + ignore_errors: yes + + - name: Stop consuming DHCP Policy + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + bd: CLIENT_BD + vrf: + name: VRF1 + state: absent + ignore_errors: yes + + - name: Remove DHCP Relay Policy 1 + mso_dhcp_relay_policy: + <<: *mso_info + dhcp_relay_policy: '{{ item }}' + state: absent + loop: + - ansible_dhcp_relay_1 + - ansible_dhcp_relay_2 + + - name: Remove DHCP Option Policies + mso_dhcp_option_policy: + <<: *mso_info + dhcp_option_policy: '{{ item }}' + state: absent + ignore_errors: yes + loop: + - ansible_dhcp_option_1 + - ansible_dhcp_option_2
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_dhcp_relay_policy/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_dhcp_relay_policy/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_dhcp_relay_policy/aliases @@ -0,0 +1,2 @@ +# No ACI MultiSite infrastructure, so not enabled +# unsupported diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_dhcp_relay_policy/tasks/main.yaml b/ansible_collections/cisco/mso/tests/integration/targets/mso_dhcp_relay_policy/tasks/main.yaml new file mode 100644 index 00000000..d09beef0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_dhcp_relay_policy/tasks/main.yaml @@ -0,0 +1,270 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Jorge Gomez (@jgomezve) <jgomezve@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") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Execute tasks only for MSO version < 4.0 + when: version.current.version is version('4.0', '<') + block: + - name: Ensure tenant ansible_test exist + mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + state: present + register: ansible_tenant + + - name: Stop consuming DHCP Policy + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + bd: CLIENT_BD + vrf: + name: VRF1 + state: absent + ignore_errors: yes + + - name: Remove DHCP Relay Policy 1 + mso_dhcp_relay_policy: + <<: *mso_info + dhcp_relay_policy: '{{ item }}' + state: absent + loop: + - ansible_dhcp_relay_1 + - ansible_dhcp_relay_2 + - ansible_test_dhcp_policy1 + - ansible_test_dhcp_policy2 + - ansible_test_dhcp_policy3 + + # ADD DHCP Policy + - name: Add a new DHCP Relay Policy 1 (check mode) + mso_dhcp_relay_policy: &create_dhcp + <<: *mso_info + dhcp_relay_policy: ansible_dhcp_relay_1 + description: "My Test DHCP Policy 1" + tenant: ansible_test + state: present + check_mode: yes + register: dhcp_pol1_cm + + - name: Add a new DHCP Relay Policy 1 (normal mode) + mso_dhcp_relay_policy: + <<: *create_dhcp + register: dhcp_pol1_nm + + - name: Verify dhcp_pol1_cm and dhcp_pol1_nm + assert: + that: + - dhcp_pol1_cm is changed + - dhcp_pol1_nm is changed + - dhcp_pol1_cm.current.name == dhcp_pol1_nm.current.name == 'ansible_dhcp_relay_1' + - dhcp_pol1_cm.current.desc == dhcp_pol1_nm.current.desc == 'My Test DHCP Policy 1' + - dhcp_pol1_cm.current.policySubtype == dhcp_pol1_nm.current.policySubtype == 'relay' + - dhcp_pol1_cm.current.policyType == dhcp_pol1_nm.current.policyType == 'dhcp' + - dhcp_pol1_cm.current.tenantId == dhcp_pol1_nm.current.tenantId == ansible_tenant.current.id + + - name: Add a new DHCP Relay Policy 1 again (check mode) + mso_dhcp_relay_policy: + <<: *create_dhcp + check_mode: yes + register: dhcp_pol1_again_cm + + - name: Add a new DHCP Relay Policy 1 again (normal mode) + mso_dhcp_relay_policy: + <<: *create_dhcp + register: dhcp_pol1_again_nm + + - name: Verify dhcp_pol1_again_cm and dhcp_pol1_again_nm + assert: + that: + - dhcp_pol1_again_cm is not changed + - dhcp_pol1_again_nm is not changed + - dhcp_pol1_again_cm.current.name == dhcp_pol1_again_nm.current.name == 'ansible_dhcp_relay_1' + - dhcp_pol1_again_cm.current.desc == dhcp_pol1_again_nm.current.desc == 'My Test DHCP Policy 1' + - dhcp_pol1_again_cm.current.policySubtype == dhcp_pol1_again_nm.current.policySubtype == 'relay' + - dhcp_pol1_again_cm.current.policyType == dhcp_pol1_again_nm.current.policyType == 'dhcp' + - dhcp_pol1_again_cm.current.tenantId == dhcp_pol1_again_nm.current.tenantId == ansible_tenant.current.id + + - name: Add a new DHCP Relay Policy 2 (normal mode) + mso_dhcp_relay_policy: + <<: *create_dhcp + dhcp_relay_policy: ansible_dhcp_relay_2 + + - name: Change DHCP Relay Policy 1 description (check mode) + mso_dhcp_relay_policy: + <<: *create_dhcp + description: "My Changed Test DHCP Policy 1" + check_mode: yes + register: change_dhcp_pol1_cm + + - name: Change DHCP Relay Policy 1 description (normal mode) + mso_dhcp_relay_policy: + <<: *create_dhcp + description: "My Changed Test DHCP Policy 1" + register: change_dhcp_pol1_nm + + - name: Verify change_dhcp_pol1_cm and change_dhcp_pol1_nm + assert: + that: + - change_dhcp_pol1_cm is changed + - change_dhcp_pol1_nm is changed + - change_dhcp_pol1_cm.current.name == change_dhcp_pol1_nm.current.name == 'ansible_dhcp_relay_1' + - change_dhcp_pol1_cm.current.desc == change_dhcp_pol1_nm.current.desc == 'My Changed Test DHCP Policy 1' + - change_dhcp_pol1_cm.current.policySubtype == change_dhcp_pol1_nm.current.policySubtype == 'relay' + - change_dhcp_pol1_cm.current.policyType == change_dhcp_pol1_nm.current.policyType == 'dhcp' + - change_dhcp_pol1_cm.current.tenantId == change_dhcp_pol1_nm.current.tenantId == ansible_tenant.current.id + + # QUERY A DHCP RELAY POLICY + - name: Query DHCP Relay Policy 1 (check mode) + mso_dhcp_relay_policy: &query_dhcp + <<: *mso_info + dhcp_relay_policy: ansible_dhcp_relay_1 + state: query + check_mode: yes + register: dhcp_pol1_query_cm + + - name: Query DHCP Relay Policy 1 (normal mode) + mso_dhcp_relay_policy: + <<: *query_dhcp + register: dhcp_pol1_query_nm + + - name: Verify dhcp_pol1_query + assert: + that: + - dhcp_pol1_query_cm is not changed + - dhcp_pol1_query_nm is not changed + - dhcp_pol1_query_cm.current.name == dhcp_pol1_query_nm.current.name == 'ansible_dhcp_relay_1' + - dhcp_pol1_query_cm.current.desc == dhcp_pol1_query_nm.current.desc == 'My Changed Test DHCP Policy 1' + - dhcp_pol1_query_cm.current.policySubtype == dhcp_pol1_query_nm.current.policySubtype == 'relay' + - dhcp_pol1_query_cm.current.policyType == dhcp_pol1_query_nm.current.policyType == 'dhcp' + + # QUERY A NON-EXISTING DHCP RELAY POLICY + - name: Query non-existing DHCP Relay Policy (normal mode) + mso_dhcp_relay_policy: + <<: *mso_info + dhcp_relay_policy: non_existing + state: query + register: quey_non_dhcp_pol + + - name: Verify quey_non_dhcp_pol + assert: + that: + - quey_non_dhcp_pol is not changed + + # QUERY ALL DHCP RELAY POLICIES + - name: Query all DHCP Relay Policies (normal mode) + mso_dhcp_relay_policy: + <<: *mso_info + state: query + register: dhcp_policies_query + + - name: Verify dhcp_policies_query + assert: + that: + - dhcp_policies_query is not changed + - dhcp_policies_query.current | length == 2 + + # REMOVE DHCP POLICY + - name: Remove DHCP Relay Policy 1 (check mode) + mso_dhcp_relay_policy: &remove_dhcp + <<: *mso_info + dhcp_relay_policy: ansible_dhcp_relay_1 + state: absent + check_mode: yes + register: dhcp_pol1_removed_cm + + - name: Remove DHCP Relay Policy 1 (normal mode) + mso_dhcp_relay_policy: + <<: *remove_dhcp + register: dhcp_pol1_removed_nm + + - name: Verify dhcp_policies_removed + assert: + that: + - dhcp_pol1_removed_cm is changed + - dhcp_pol1_removed_nm is changed + - dhcp_pol1_removed_cm.current == dhcp_pol1_removed_nm.current == {} + + # REMOVE DHCP POLICY AGAIN + - name: Remove DHCP Relay Policy 1 again (check mode) + mso_dhcp_relay_policy: + <<: *remove_dhcp + check_mode: yes + register: dhcp_pol1_removed_again_cm + + - name: Remove DHCP Relay Policy 1 again (normal mode) + mso_dhcp_relay_policy: + <<: *remove_dhcp + register: dhcp_pol1_removed_again_nm + + - name: Verify dhcp_pol1_removed_again + assert: + that: + - dhcp_pol1_removed_again_cm is not changed + - dhcp_pol1_removed_again_nm is not changed + - dhcp_pol1_removed_again_cm.current == dhcp_pol1_removed_again_nm.current == {} + - dhcp_pol1_removed_again_cm.previous == dhcp_pol1_removed_again_nm.previous == {} + + + # USE A NON-EXISTING TENANT + - name: Non Existing Tenant for DHCP Relay Policy 3 (normal mode) + mso_dhcp_relay_policy: + <<: *mso_info + dhcp_relay_policy: ansible_dhcp_relay_3 + description: "My Test DHCP Policy 3" + tenant: non_existing + state: present + ignore_errors: yes + register: nm_non_existing_tenant + + - name: Verify nm_non_existing_tenant + assert: + that: + - nm_non_existing_tenant is not changed + - nm_non_existing_tenant.msg == "Tenant 'non_existing' is not valid tenant name." + + # CLEAN UP DHCP POLICIES + - name: Stop consuming DHCP Policy + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + bd: CLIENT_BD + vrf: + name: VRF1 + state: absent + ignore_errors: yes + + - name: Remove DHCP Relay Policy 1 + mso_dhcp_relay_policy: + <<: *mso_info + dhcp_relay_policy: '{{ item }}' + state: absent + loop: + - ansible_dhcp_relay_1 + - ansible_dhcp_relay_2
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_dhcp_relay_policy_provider/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_dhcp_relay_policy_provider/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_dhcp_relay_policy_provider/aliases @@ -0,0 +1,2 @@ +# No ACI MultiSite infrastructure, so not enabled +# unsupported diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_dhcp_relay_policy_provider/tasks/main.yaml b/ansible_collections/cisco/mso/tests/integration/targets/mso_dhcp_relay_policy_provider/tasks/main.yaml new file mode 100644 index 00000000..de989945 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_dhcp_relay_policy_provider/tasks/main.yaml @@ -0,0 +1,662 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Jorge Gomez (@jgomezve) <cizhao@jgomezve.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") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Execute tasks only for MSO version < 4.0 + when: version.current.version is version('4.0', '<') + block: + - name: Remove EXT_EPGs Providers from DHCP Relay Policy + mso_dhcp_relay_policy_provider: + <<: *mso_info + dhcp_relay_policy: ansible_dhcp_relay_1 + tenant: ansible_test + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_endpoint_group: "{{ item }}" + state: absent + ignore_errors: yes + loop: + - EXT_EPG_1 + - EXT_EPG_2 + + - name: Remove EXT_EPGs Providers from DHCP Relay Policy + mso_dhcp_relay_policy_provider: + <<: *mso_info + dhcp_relay_policy: ansible_dhcp_relay_1 + tenant: ansible_test + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + endpoint_group: "{{ item }}" + application_profile: "ANP_1" + state: absent + ignore_errors: yes + loop: + - EPG_1 + - EPG_2 + + - name: Stop consuming DHCP Policy + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + bd: CLIENT_BD + vrf: + name: VRF1 + state: present + ignore_errors: yes + + - name: Remove DHCP Relay Policies + mso_dhcp_relay_policy: + <<: *mso_info + dhcp_relay_policy: '{{ item }}' + state: absent + ignore_errors: yes + loop: + - ansible_dhcp_relay_1 + - ansible_dhcp_relay_2 + + - name: Undeploy sites in schema 1 template 1 + mso_schema_template_deploy: + <<: *mso_info + template: Template 1 + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ item }}' + state: undeploy + ignore_errors: yes + loop: + - '{{ mso_site | default("ansible_test") }}' + - '{{ mso_site | default("ansible_test") }}_2' + - 'aws_{{ mso_site | default("ansible_test") }}' + - 'azure_{{ mso_site | default("ansible_test") }}' + + - name: Undeploy sites in schema 1 template 2 + mso_schema_template_deploy: + <<: *mso_info + template: Template 2 + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ item }}' + state: undeploy + ignore_errors: yes + loop: + - '{{ mso_site | default("ansible_test") }}' + - '{{ mso_site | default("ansible_test") }}_2' + - 'aws_{{ mso_site | default("ansible_test") }}' + - 'azure_{{ mso_site | default("ansible_test") }}' + + - name: Remove schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + + - name: Ensure tenant ansible_test exist + mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + state: present + register: tenant_ansible + + - name: Ensure schema 1 with Template 1 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template 1 + state: present + + # CREATE EPG PROVIDER + - name: Add a new VRF + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF1 + state: present + + - name: Add a new BD + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + bd: BD_1 + vrf: + name: VRF1 + state: present + + - name: Add 2nd BD + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + bd: CLIENT_BD + vrf: + name: VRF1 + state: present + + - name: Add a new ANP + mso_schema_template_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP_1 + state: present + + - name: Add a new EPG + mso_schema_template_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP_1 + epg: EPG_1 + bd: + name: BD_1 + vrf: + name: VRF1 + state: present + + - name: Add 2nd EPG + mso_schema_template_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP_1 + epg: EPG_2 + bd: + name: BD_1 + vrf: + name: VRF1 + state: present + + - name: Add a new L3out + mso_schema_template_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + l3out: L3OUT_1 + vrf: + name: VRF1 + state: present + + - name: Add a new external EPG + cisco.mso.mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: EXT_EPG_1 + vrf: + name: VRF1 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + l3out: + name: L3OUT_1 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + state: present + + - name: Add 2nd external EPG + cisco.mso.mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: EXT_EPG_2 + vrf: + name: VRF1 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + l3out: + name: L3OUT_1 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + state: present + + # ADD DHCP RELAY POLICY + - name: Add a new DHCP Relay Policy 1 (Normal mode) + mso_dhcp_relay_policy: + <<: *mso_info + dhcp_relay_policy: ansible_dhcp_relay_1 + description: "My Test DHCP Policy 1" + tenant: ansible_test + state: present + + # ADD PROVIDER TO DHCP RELAY POLICY + - name: Add Provider to DHCP Relay Policy (check mode) + mso_dhcp_relay_policy_provider: &create_provider + <<: *mso_info + dhcp_relay_policy: ansible_dhcp_relay_1 + ip: "1.1.1.1" + tenant: ansible_test + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + application_profile: ANP_1 + endpoint_group: EPG_1 + state: present + check_mode: yes + register: dhcp_pol1_prov1_cm + + - name: Add Provider to DHCP Relay Policy (normal mode) + mso_dhcp_relay_policy_provider: + <<: *create_provider + register: dhcp_pol1_prov1_nm + + - name: Verify dhcp_pol1_prov1 + assert: + that: + - dhcp_pol1_prov1_cm is changed + - dhcp_pol1_prov1_nm is changed + - dhcp_pol1_prov1_cm.current.addr == dhcp_pol1_prov1_nm.current.addr == '1.1.1.1' + - "'EPG_1' in dhcp_pol1_prov1_cm.current.epgRef" + - "'EPG_1' in dhcp_pol1_prov1_nm.current.epgRef" + - "'ANP_1' in dhcp_pol1_prov1_cm.current.epgRef" + - "'ANP_1' in dhcp_pol1_prov1_nm.current.epgRef" + - "'Template1' in dhcp_pol1_prov1_cm.current.epgRef" + - "'Template1' in dhcp_pol1_prov1_nm.current.epgRef" + - dhcp_pol1_prov1_cm.current.tenantId == tenant_ansible.current.id + - dhcp_pol1_prov1_nm.current.tenantId == tenant_ansible.current.id + + - name: Add Provider to DHCP Relay Policy again (check mode) + mso_dhcp_relay_policy_provider: + <<: *create_provider + check_mode: yes + register: dhcp_pol1_prov1_again_cm + + - name: Add Provider to DHCP Relay Policy again (normal mode) + mso_dhcp_relay_policy_provider: + <<: *create_provider + register: dhcp_pol1_prov1_again_nm + + - name: Verify dhcp_pol1_prov1_again + assert: + that: + - dhcp_pol1_prov1_again_cm is not changed + - dhcp_pol1_prov1_again_nm is not changed + - dhcp_pol1_prov1_again_cm.current.addr == dhcp_pol1_prov1_again_nm.current.addr == '1.1.1.1' + - "'EPG_1' in dhcp_pol1_prov1_again_cm.current.epgRef" + - "'EPG_1' in dhcp_pol1_prov1_again_nm.current.epgRef" + - "'ANP_1' in dhcp_pol1_prov1_again_cm.current.epgRef" + - "'ANP_1' in dhcp_pol1_prov1_again_nm.current.epgRef" + - "'Template1' in dhcp_pol1_prov1_again_cm.current.epgRef" + - "'Template1' in dhcp_pol1_prov1_again_nm.current.epgRef" + - dhcp_pol1_prov1_again_cm.current.tenantId == tenant_ansible.current.id + - dhcp_pol1_prov1_again_nm.current.tenantId == tenant_ansible.current.id + + - name: Change Provider IP to DHCP Relay Policy (check mode) + mso_dhcp_relay_policy_provider: + <<: *create_provider + ip: "2.2.2.2" + check_mode: yes + register: dhcp_pol1_prov1_change_cm + + - name: Change Provider IP to DHCP Relay Policy (normal mode) + mso_dhcp_relay_policy_provider: + <<: *create_provider + ip: "2.2.2.2" + register: dhcp_pol1_prov1_change_nm + + - name: Verify dhcp_pol1_prov1_change + assert: + that: + - dhcp_pol1_prov1_change_cm is changed + - dhcp_pol1_prov1_change_nm is changed + - dhcp_pol1_prov1_change_cm.current.addr == dhcp_pol1_prov1_change_nm.current.addr == '2.2.2.2' + - "'EPG_1' in dhcp_pol1_prov1_change_cm.current.epgRef" + - "'EPG_1' in dhcp_pol1_prov1_change_nm.current.epgRef" + - "'ANP_1' in dhcp_pol1_prov1_change_cm.current.epgRef" + - "'ANP_1' in dhcp_pol1_prov1_change_nm.current.epgRef" + - "'Template1' in dhcp_pol1_prov1_change_cm.current.epgRef" + - "'Template1' in dhcp_pol1_prov1_change_nm.current.epgRef" + - dhcp_pol1_prov1_change_cm.current.tenantId == tenant_ansible.current.id + - dhcp_pol1_prov1_change_nm.current.tenantId == tenant_ansible.current.id + + - name: Add 2nd Provider (EPG_2) to DHCP Relay Policy (check mode) + mso_dhcp_relay_policy_provider: + <<: *create_provider + ip: "2.2.2.2" + endpoint_group: EPG_2 + check_mode: yes + register: dhcp_pol1_prov2_cm + + - name: Add 2nd Provider (EPG_2) to DHCP Relay Policy (normal mode) + mso_dhcp_relay_policy_provider: + <<: *create_provider + ip: "2.2.2.2" + endpoint_group: EPG_2 + register: dhcp_pol1_prov2_nm + + - name: Add 3rd Provider (EXT_EPG_1) to DHCP Relay Policy (check mode) + mso_dhcp_relay_policy_provider: &create_provider_external_epg + <<: *create_provider + ip: "2.2.2.2" + external_endpoint_group: EXT_EPG_1 + application_profile: null + endpoint_group: null + check_mode: yes + register: dhcp_pol1_prov3_cm + + - name: Add 3rd Provider (EXT_EPG_1) to DHCP Relay Policy (normal mode) + mso_dhcp_relay_policy_provider: + <<: *create_provider_external_epg + external_endpoint_group: EXT_EPG_1 + register: dhcp_pol1_prov3_nm + + - name: Add 4th Provider (EXT_EPG_2) to DHCP Relay Policy (check mode) + mso_dhcp_relay_policy_provider: + <<: *create_provider_external_epg + external_endpoint_group: EXT_EPG_2 + check_mode: yes + register: dhcp_pol1_prov4_cm + + - name: Add 4th Provider (EXT_EPG_2) to DHCP Relay Policy (normal mode) + mso_dhcp_relay_policy_provider: + <<: *create_provider_external_epg + external_endpoint_group: EXT_EPG_2 + register: dhcp_pol1_prov4_nm + + - name: Verify dhcp_pol1_prov2, dhcp_pol1_prov3 and dhcp_pol1_prov4 + assert: + that: + - dhcp_pol1_prov2_cm is changed + - dhcp_pol1_prov2_nm is changed + - dhcp_pol1_prov3_cm is changed + - dhcp_pol1_prov3_nm is changed + - dhcp_pol1_prov4_cm is changed + - dhcp_pol1_prov4_nm is changed + - dhcp_pol1_prov2_cm.current.addr == dhcp_pol1_prov2_nm.current.addr == '2.2.2.2' + - dhcp_pol1_prov3_cm.current.addr == dhcp_pol1_prov3_nm.current.addr == '2.2.2.2' + - dhcp_pol1_prov4_cm.current.addr == dhcp_pol1_prov4_nm.current.addr == '2.2.2.2' + - "'EPG_2' in dhcp_pol1_prov2_cm.current.epgRef" + - "'EPG_2' in dhcp_pol1_prov2_nm.current.epgRef" + - "'ANP_1' in dhcp_pol1_prov2_cm.current.epgRef" + - "'ANP_1' in dhcp_pol1_prov2_nm.current.epgRef" + - "'Template1' in dhcp_pol1_prov2_cm.current.epgRef" + - "'Template1' in dhcp_pol1_prov2_nm.current.epgRef" + - "'EXT_EPG_1' in dhcp_pol1_prov3_cm.current.externalEpgRef" + - "'EXT_EPG_1' in dhcp_pol1_prov3_nm.current.externalEpgRef" + - "'EXT_EPG_2' in dhcp_pol1_prov4_cm.current.externalEpgRef" + - "'EXT_EPG_2' in dhcp_pol1_prov4_nm.current.externalEpgRef" + - dhcp_pol1_prov3_cm.current.tenantId == tenant_ansible.current.id + - dhcp_pol1_prov3_nm.current.tenantId == tenant_ansible.current.id + - dhcp_pol1_prov4_cm.current.tenantId == tenant_ansible.current.id + - dhcp_pol1_prov4_nm.current.tenantId == tenant_ansible.current.id + + # ADD DHCP RELAY PROVIDER WITH WRONG Attributes + - name: Add Provider to DHCP Relay Policy - wrong tenant (Normal mode) + mso_dhcp_relay_policy_provider: + <<: *mso_info + dhcp_relay_policy: ansible_dhcp_relay_1 + ip: "2.2.2.2" + tenant: ansible_test_wrong + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + application_profile: ANP_1 + endpoint_group: EPG_1 + state: present + ignore_errors: yes + register: dhcp_pol1_prov2_nm_ten_wrong + + - name: Add Provider to DHCP Relay Policy - wrong Schema (Normal mode) + mso_dhcp_relay_policy_provider: + <<: *mso_info + dhcp_relay_policy: ansible_dhcp_relay_1 + ip: "2.2.2.2" + tenant: ansible_test + schema: schema_wrong + template: Template 1 + application_profile: ANP_1 + endpoint_group: EPG_1 + state: present + ignore_errors: yes + register: dhcp_pol1_prov2_nm_sch_wrong + + - name: Verify dhcp_pol1_prov2_nm_ten_wrong, dhcp_pol1_prov2_nm_sch_wrong & dhcp_pol1_prov2_nm_tmp_wrong + assert: + that: + - dhcp_pol1_prov2_nm_ten_wrong is not changed + - dhcp_pol1_prov2_nm_ten_wrong.msg == "Tenant 'ansible_test_wrong' is not valid tenant name." + - dhcp_pol1_prov2_nm_sch_wrong is not changed + - dhcp_pol1_prov2_nm_sch_wrong.msg == "Provided schema 'schema_wrong' does not exist." + # MSO API allows to create provider in non-existing/wrong templates/epgs/ext_epgs + + # QUERY PROVIDER FROM DHCP RELAY POLICY + - name: Query Provider from DHCP Relay Policy (check mode) + mso_dhcp_relay_policy_provider: &query_provider + <<: *mso_info + dhcp_relay_policy: ansible_dhcp_relay_1 + tenant: ansible_test + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + application_profile: ANP_1 + endpoint_group: EPG_1 + state: query + register: dhcp_pol1_prov1_query_cm + + - name: Query Provider from DHCP Relay Policy (normal mode) + mso_dhcp_relay_policy_provider: + <<: *query_provider + register: dhcp_pol1_prov1_query_nm + + - name: Query non_existing Provider from DHCP Relay Policy + mso_dhcp_relay_policy_provider: + <<: *query_provider + endpoint_group: non_existing + state: query + register: dhcp_pol1_prov1_query_non_existing + + - name: Query all Providers from a DHCP Relay Policy + mso_dhcp_relay_policy_provider: + <<: *mso_info + dhcp_relay_policy: ansible_dhcp_relay_1 + state: query + register: dhcp_pol1_query_all + + - name: Verify all query variables + assert: + that: + - dhcp_pol1_prov1_query_cm is not changed + - dhcp_pol1_prov1_query_nm is not changed + - dhcp_pol1_prov1_query_non_existing is not changed + - dhcp_pol1_query_all is not changed + - dhcp_pol1_prov1_query_cm.current.addr == dhcp_pol1_prov1_query_nm.current.addr == '2.2.2.2' + - "'EPG_1' in dhcp_pol1_prov1_query_cm.current.epgRef" + - "'EPG_1' in dhcp_pol1_prov1_query_nm.current.epgRef" + - "'ANP_1' in dhcp_pol1_prov1_query_cm.current.epgRef" + - "'ANP_1' in dhcp_pol1_prov1_query_nm.current.epgRef" + - "'Template1' in dhcp_pol1_prov1_query_cm.current.epgRef" + - "'Template1' in dhcp_pol1_prov1_query_nm.current.epgRef" + - dhcp_pol1_prov1_query_non_existing.current == {} + - dhcp_pol1_query_all.current | length == 4 + + # REMOVE PROVIDER FROM DHCP RELAY POLICY + - name: Remove Provider (EXT_EPG) from DHCP Relay Policy (check mode) + mso_dhcp_relay_policy_provider: &delete_provider + <<: *mso_info + dhcp_relay_policy: ansible_dhcp_relay_1 + tenant: ansible_test + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_endpoint_group: EXT_EPG_1 + state: absent + check_mode: yes + register: dhcp_pol1_prov1_del_cm + + - name: Remove Provider (EXT_EPG) from DHCP Relay Policy (normal mode) + mso_dhcp_relay_policy_provider: + <<: *delete_provider + register: dhcp_pol1_prov1_del_nm + + - name: Verify dhcp_pol1_prov1_del + assert: + that: + - dhcp_pol1_prov1_del_cm is changed + - dhcp_pol1_prov1_del_nm is changed + - dhcp_pol1_prov1_del_cm.current == dhcp_pol1_prov1_del_nm.current == {} + + - name: Remove Provider (EXT_EPG) from DHCP Relay Policy again (check mode) + mso_dhcp_relay_policy_provider: + <<: *delete_provider + check_mode: yes + register: dhcp_pol1_prov1_del_again_cm + + - name: Remove Provider (EXT_EPG) from DHCP Relay Policy again (normal mode) + mso_dhcp_relay_policy_provider: + <<: *delete_provider + register: dhcp_pol1_prov1_del_again_nm + + - name: Verify dhcp_pol1_prov1_again_del + assert: + that: + - dhcp_pol1_prov1_del_again_cm is not changed + - dhcp_pol1_prov1_del_again_nm is not changed + - dhcp_pol1_prov1_del_again_cm.current == dhcp_pol1_prov1_del_again_nm.current == {} + + - name: Remove Non-Existing Provider (EXT_EPG) + mso_dhcp_relay_policy_provider: + <<: *delete_provider + external_endpoint_group: non_existing + register: dhcp_pol1_prov1_del_nm_non_existing + + - name: Remove Provider without epg or ext_epg + mso_dhcp_relay_policy_provider: + <<: *mso_info + dhcp_relay_policy: ansible_dhcp_relay_1 + tenant: ansible_test + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + state: absent + ignore_errors: yes + register: dhcp_pol1_prov1_del_none + + - name: Verify dhcp_pol1_prov1_del_nm_non_existing + assert: + that: + - dhcp_pol1_prov1_del_nm_non_existing is not changed + - dhcp_pol1_prov1_del_none is not changed + - dhcp_pol1_prov1_del_nm_non_existing.current == {} + - dhcp_pol1_prov1_del_none.msg == 'Missing either endpoint_group or external_endpoint_group required attribute.' + + # CONSUME DHCP POLICIES + - name: Get DHCP Relay Policy version + mso_dhcp_relay_policy: + <<: *mso_info + dhcp_relay_policy: ansible_dhcp_relay_1 + state: query + register: dhcp_relay_policy_version + + - name: Consume DHCP Policy + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + bd: CLIENT_BD + vrf: + name: VRF1 + dhcp_policy: + name: "{{ dhcp_relay_policy_version.current.name }}" + version: "{{ dhcp_relay_policy_version.current.version | int }}" + state: present + register: bd_dhcp_policy + + - name: Stop consuming DHCP Policy + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + bd: CLIENT_BD + vrf: + name: VRF1 + state: present + register: bd_dhcp_policy + + # QUERY PROVIDER FROM non_existing DHCP RELAY POLICY + - name: Query Provider from DHCP Relay Policy (check mode) + mso_dhcp_relay_policy_provider: + <<: *mso_info + dhcp_relay_policy: non_existing + state: query + ignore_errors: yes + register: dhcp_non_existing + + - name: Verify dhcp_non_existing + assert: + that: + - dhcp_non_existing is not changed + - dhcp_non_existing.msg == "DHCP Relay Policy 'non_existing' is not a valid DHCP Relay Policy name." + + # CLEAN UP + - name: Remove EXT_EPGs Providers from DHCP Relay Policy + mso_dhcp_relay_policy_provider: + <<: *mso_info + dhcp_relay_policy: ansible_dhcp_relay_1 + tenant: ansible_test + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_endpoint_group: "{{ item }}" + state: absent + ignore_errors: yes + loop: + - EXT_EPG_1 + - EXT_EPG_2 + + - name: Remove EXT_EPGs Providers from DHCP Relay Policy + mso_dhcp_relay_policy_provider: + <<: *mso_info + dhcp_relay_policy: ansible_dhcp_relay_1 + tenant: ansible_test + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + endpoint_group: "{{ item }}" + application_profile: "ANP_1" + state: absent + ignore_errors: yes + loop: + - EPG_1 + - EPG_2 + + - name: Stop consuming DHCP Policy + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + bd: CLIENT_BD + vrf: + name: VRF1 + state: absent + ignore_errors: yes + + - name: Remove DHCP Relay Policies + mso_dhcp_relay_policy: + <<: *mso_info + dhcp_relay_policy: '{{ item }}' + state: absent + ignore_errors: yes + loop: + - ansible_dhcp_relay_1 + - ansible_dhcp_relay_2
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_label/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_label/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_label/aliases @@ -0,0 +1,2 @@ +# No ACI MultiSite infrastructure, so not enabled +# unsupported diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_label/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_label/tasks/main.yml new file mode 100644 index 00000000..ad057aa8 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_label/tasks/main.yml @@ -0,0 +1,411 @@ +# Test code for the MSO modules +# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.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") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Execute tasks only for MSO version < 3.2 + when: version.current.version is version('3.2', '<') + block: + - name: GET auth radius providers + mso_rest: + <<: *mso_info + path: /api/v1/auth/providers/radius + method: get + register: radius_providers + + - name: Add auth radius provider + mso_rest: + <<: *mso_info + path: /api/v1/auth/providers/radius + method: post + content: + { + "host": "{{ mso_radius_server }}", + "description": "", + "port": 1812, + "providerType": "radius", + "sharedSecret": "{{ mso_radius_secret | default('radius-secret') }}", + "timeoutInSeconds": 5, + "retries": 3, + "protocol": "pap" + } + register: radius_provider + when: mso_radius_server not in (radius_providers.jsondata.radiusProviders | map(attribute='host')) + + - name: GET login domains + mso_rest: + <<: *mso_info + path: /api/v1/auth/domains + method: get + register: login_domains + + - name: GET auth radius providers again after creation + mso_rest: + <<: *mso_info + path: /api/v1/auth/providers/radius + method: get + register: radius_providers + + - name: GET auth radius provider ID + set_fact: + radius_provider_id: "{{ (radius_providers.jsondata.radiusProviders | selectattr('host', 'eq', mso_radius_server) | first)['id'] }}" + + - name: Add test login domain + mso_rest: + <<: *mso_info + path: /api/v1/auth/domains + method: post + content: + { + "name": "{{ mso_login_domain | default('test') }}", + "description": "", + "realm": "radius", + "providerAssociations": [{ + "priority": 1, + "providerId": "{{ radius_provider_id }}" + }], + "status": "active", + "isDefault": false + } + when: (mso_login_domain | default('test')) not in (login_domains.jsondata.domains | map(attribute='name')) + +# REMOVE DHCP POLICY +- name: Remove DHCP Option Policy + mso_dhcp_option_policy: &remove_dhcp + <<: *mso_info + dhcp_option_policy: '{{ item }}' + state: absent + loop: + - ansible_dhcp_option_1 + - ansible_dhcp_option_2 + +- name: Remove DHCP Relay Policy + mso_dhcp_relay_policy: + <<: *mso_info + dhcp_relay_policy: '{{ item }}' + state: absent + loop: + - ansible_dhcp_relay_1 + - ansible_dhcp_relay_2 + +- name: Remove label ansible_test + mso_label: &label_absent + <<: *mso_info + label: ansible_test + state: absent + +- name: Remove label ansible_test2 + mso_label: + <<: *label_absent + label: ansible_test2 + register: cm_remove_label + +- name: Remove label ansible_test3 + mso_label: &domain_label_absent + <<: *mso_info + state: absent + label: ansible_test3 + login_domain: Local + register: nm_remove_label3 + +- name: Remove label ansible_test4 + mso_label: + <<: *domain_label_absent + label: ansible_test4 + login_domain: '{{ mso_login_domain | default("test") }}' + +# ADD LABEL +- name: Add label (check_mode) + mso_label: &label_present + <<: *mso_info + label: ansible_test + state: present + check_mode: yes + register: cm_add_label + +- name: Verify cm_add_label + assert: + that: + - cm_add_label is changed + - cm_add_label.previous == {} + - cm_add_label.current.displayName == 'ansible_test' + - cm_add_label.current.id is not defined + - cm_add_label.current.type == 'site' + +- name: Add label (normal mode) + mso_label: *label_present + register: nm_add_label + +- name: Verify nm_add_label + assert: + that: + - nm_add_label is changed + - nm_add_label.previous == {} + - nm_add_label.current.displayName == 'ansible_test' + - nm_add_label.current.id is defined + - nm_add_label.current.type == 'site' + +- name: Add label again (check_mode) + mso_label: *label_present + check_mode: yes + register: cm_add_label_again + +- name: Verify cm_add_label_again + assert: + that: + - cm_add_label_again is not changed + - cm_add_label_again.previous.displayName == 'ansible_test' + - cm_add_label_again.previous.type == 'site' + - cm_add_label_again.current.displayName == 'ansible_test' + - cm_add_label_again.current.id == nm_add_label.current.id + - cm_add_label_again.current.type == 'site' + +- name: Add label again (normal mode) + mso_label: *label_present + register: nm_add_label_again + +- name: Verify nm_add_label_again + assert: + that: + - nm_add_label_again is not changed + - nm_add_label_again.previous.displayName == 'ansible_test' + - nm_add_label_again.previous.type == 'site' + - nm_add_label_again.current.displayName == 'ansible_test' + - nm_add_label_again.current.id == nm_add_label.current.id + - nm_add_label_again.current.type == 'site' + + +# CHANGE LABEL +# - name: Change label (check_mode) +# mso_label: +# <<: *label_present +# label_id: '{{ nm_add_label.current.id }}' +# label: ansible_test2 +# check_mode: yes +# register: cm_change_label + +# - name: Verify cm_change_label +# assert: +# that: +# - cm_change_label is changed +# - cm_change_label.current.displayName == 'ansible_test2' +# - cm_change_label.current.id == nm_add_label.current.id +# - cm_change_label.current.type == 'site' + +# - name: Change label (normal mode) +# mso_label: +# <<: *label_present +# label_id: '{{ nm_add_label.current.id }}' +# label: ansible_test2 +# output_level: debug +# register: nm_change_label + +# - name: Verify nm_change_label +# assert: +# that: +# - nm_change_label is changed +# - cm_change_label.current.displayName == 'ansible_test2' +# - nm_change_label.current.id == nm_add_label.current.id +# - nm_change_label.current.type == 'site' + +# - name: Change label again (check_mode) +# mso_label: +# <<: *label_present +# label_id: '{{ nm_add_label.current.id }}' +# label: ansible_test2 +# check_mode: yes +# register: cm_change_label_again + +# - name: Verify cm_change_label_again +# assert: +# that: +# - cm_change_label_again is not changed +# - cm_change_label_again.current.displayName == 'ansible_test2' +# - cm_change_label_again.current.id == nm_add_label.current.id +# - cm_change_label_again.current.type == 'site' + +# - name: Change label again (normal mode) +# mso_label: +# <<: *label_present +# label_id: '{{ nm_add_label.current.id }}' +# label: ansible_test2 +# register: nm_change_label_again + +# - name: Verify nm_change_label_again +# assert: +# that: +# - nm_change_label_again is not changed +# - nm_change_label_again.current.displayName == 'ansible_test2' +# - nm_change_label_again.current.id == nm_add_label.current.id +# - nm_change_label_again.current.type == 'site' + + +# QUERY ALL LABELS +- name: Query all labels (check_mode) + mso_label: &label_query + <<: *mso_info + state: query + check_mode: yes + register: cm_query_all_labels + +- name: Query all labels (normal mode) + mso_label: *label_query + register: nm_query_all_labels + +- name: Verify query_all_labels + assert: + that: + - cm_query_all_labels is not changed + - nm_query_all_labels is not changed + # NOTE: Order of labels is not stable between calls + # FIXME: + #- cm_query_all_labels == nm_query_all_labels + + +# QUERY A LABEL +- name: Query our label (check mode) + mso_label: + <<: *label_query + label: ansible_test + check_mode: yes + register: cm_query_label + +- name: Query our label (normal mode) + mso_label: + <<: *label_query + label: ansible_test + register: nm_query_label + +- name: Verify query_label + assert: + that: + - cm_query_label is not changed + - cm_query_label.current.displayName == 'ansible_test' + - cm_query_label.current.id == nm_add_label.current.id + - cm_query_label.current.type == 'site' + - nm_query_label is not changed + - nm_query_label.current.displayName == 'ansible_test' + - nm_query_label.current.id == nm_add_label.current.id + - nm_query_label.current.type == 'site' + - cm_query_label == nm_query_label + + +# REMOVE LABEL +- name: Remove label (check_mode) + mso_label: *label_absent + check_mode: yes + register: cm_remove_label + +- name: Verify cm_remove_label + assert: + that: + - cm_remove_label is changed + - cm_remove_label.current == {} + +- name: Remove label (normal mode) + mso_label: *label_absent + register: nm_remove_label + +- name: Verify nm_remove_label + assert: + that: + - nm_remove_label is changed + - nm_remove_label.current == {} + +- name: Remove label again (check_mode) + mso_label: *label_absent + check_mode: yes + register: cm_remove_label_again + +- name: Verify cm_remove_label_again + assert: + that: + - cm_remove_label_again is not changed + - cm_remove_label_again.current == {} + +- name: Remove label again (normal mode) + mso_label: *label_absent + register: nm_remove_label_again + +- name: Verify nm_remove_label_again + assert: + that: + - nm_remove_label_again is not changed + - nm_remove_label_again.current == {} + + +# QUERY NON-EXISTING LABEL +- name: Query non-existing label (check_mode) + mso_label: + <<: *label_query + label: ansible_test + check_mode: yes + register: cm_query_non_label + +- name: Query non-existing label (normal mode) + mso_label: + <<: *label_query + label: ansible_test + register: nm_query_non_label + +# TODO: Implement more tests +- name: Verify query_non_label + assert: + that: + - cm_query_non_label is not changed + - nm_query_non_label is not changed + - cm_query_non_label == nm_query_non_label + +# add label with login domain +- name: Add label local domain(normal mode) + mso_label: &domain_label_present + <<: *mso_info + state: present + label: ansible_test3 + login_domain: Local + register: label_local_domain + +- name: Verify label_local_domain + assert: + that: + - label_local_domain is changed + - label_local_domain.current.displayName == 'ansible_test3' + - label_local_domain.current.type == 'site' + +- name: Add label test domain(normal mode) + mso_label: + <<: *domain_label_present + label: ansible_test4 + login_domain: '{{ mso_login_domain | default("test") }}' + register: label_test_domain + +- name: Verify label_test_domain + assert: + that: + - label_test_domain is changed + - label_test_domain.current.displayName == 'ansible_test4' + - label_test_domain.current.type == 'site' diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_remote_location/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_remote_location/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_remote_location/aliases @@ -0,0 +1,2 @@ +# No ACI MultiSite infrastructure, so not enabled +# unsupported diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_remote_location/pki/rsa b/ansible_collections/cisco/mso/tests/integration/targets/mso_remote_location/pki/rsa new file mode 100644 index 00000000..1c3cede1 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_remote_location/pki/rsa @@ -0,0 +1,39 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIG5QIBAAKCAYEAn/kFOjXlF4NV5aO/V0EQV1Z0Wqnss5fLpQ/fbBHhq98aalpJ +v9tSnfjlBDOp9n/MvxudqWRQPNMfvQkUyxcN1NbSeiy3QMX+iWjFt/C9q9oij5m4 +c8dk+oJ9qfha65EFVrlUGPc3+ydEIofnsLJbIIwWqNMlPKqjqhC/iMWW7BOkXliR +Go2GCYLYBdA00W59gI4xkbsc4Q0Br6vTLIX+BzJHXuTl4SFZFFvCPYSjW+j8twhQ +2NUjaVblOLZtWbEVyb5hlKJ73alS/fndIJKH1I31qGXqSwvnYQwpLx2ufPTMTVBM +q4l+0qfgIiv6SJVwiMVHxG6MP/fWUATJNE0DFjFGX61qJAqAuoa/PyOM6N01/dF9 +5jvljd5Wafut3JGGxbJ4f8T4fAeEvi3EX+axlgjVtbUjuqeyC03YpS/iMu8A6P34 +/dENbMHu1Xh6UjlTaqREb7KZl/Nsp0+vLFUrFr/8QHhHs19C54WtQsEwD73/pqo5 +Pn1/gTIRux2w23e5AgMBAAECggGAUBjxQxolIMbDxX1dmqSbN/+ztomKWMnST01J +QuUZJ2NH6KRYdNWt4ibzFE2B9kg7Dh0Xre7qNepH4/CeFqnuZPlC3aVyA96e+dIZ +3WWOsnNABsKjFmVp6/xWSzps27H7CFc3AmEWCIy6kseVfGVxNzStS86cwGl4FPjZ +zfORA5c6H3sc/DyMNkrrOs3rBEncUPfhXeRgK1bF112jGJHmhVfpYFwftb9qyMTA +1uiImsZncoWZZVgiqOW3U9QToGsHgRYhg73hQuPHhmQ869z/O5pkQ2rcP5XpC0aP +uUGLRQ/U51v5QQ05uAa9a4rejaQr6Sp2UteWr0QkKcZzLAUNstEqOHcRnXedI6py +Ls5kABZxPJhdMxHtrCUwX0XIKMIiKpGxE+vZMZQIPbD8jJE56nrFkQ3d/CA0E4fw +LALavs6x6o3f7LMUQpBCWoVQy9D9udVqx+5+TgbHhpnG9W3J957Y2g1NX/xVCIfU +KzPzmRH/7Bv1FFSWpkR7GrxtlMABAoHBAM0fNBQ0pGUFFn8mQVT1gdpASiqDZNJB +VVFQy9SaBuWIxJcJycJ/ILOhkAi2qYcqBBtS3WdTH1oplccgkFn0YijxnaE7T1rw +K29+J9pQXBQsNFWoaOhlzMNU1taXjIEhnDzTJWDPy7XNpKWsWucZH3CM5lWZEmZ4 +6Rr+MCu1BOAdiC7klGr9K91WAYe3mp9IShloWrQSJYLRtEgew+wR/kiDPfwQwR7C +siIEzWGO3DOsypIJQdJ6S0sKpVBL7jIcAQKBwQDHpvGCPmaDsi6ndXr/MqYDlxVg +Nu/Nr75xaQzvx3oqiPViet7d8WWN2ZFJd3vI70Xwmoj3gB2okpscgfJGxTZ3xCcN +ywKsshWLYkt1nAMMMC1OZiN1xL2LLos6R9ioe6R4pXChIIr1hmzycKMFA6HAdt0b +Bgcr2Odl5V9D5BIAkCbBD089WJfylz/mgqNuVh3oL2ECEJdPbpmjecXzQVqq78z5 +UjNj7qU8bGnVjkU3STr2TBuKdO1h5XFimaYxO7kCgcEAxKii9LBX4OaU4AjcYEkV +WxuCP+pDknXDB7gwBEA8VnrfCHQA9TGPN8mxXzlJpeY5k7zJutNt3rK5//UPkL8G +EX09BKTpeyWCb12DdgLPlSOgdXOGSTG4tJm1dH5N3kxMD+DcGEqBY2eq8JAjgyeK +Bg2AlBazFn3b9942buEZsIl/1H2gckcSdB2OUAFPBGF5cYykUbqILjlB4FdmvgGu +SvVRS0cA8K33vTffdSZTplOGz6aCbfqED4lAX5C86VwBAoHBAIbcePSejAbXnHYX +gE7T+pogOxsz4MZSuVTIPinV1+rVetPb5aGMBypLVb2HjUEMh3TgHjb4/o+5ADfA +e1RcsM8z26GQiSz4Wl89tXUrPk/EV0ZG7hsGG3bhqMBkebBNXKr2Ld9ZKSRyejNF +7IhdjKyCXhZ7+uoeaShGSRSGAbcJqHPukHsC1hjTHCHsCtNkLm2BW4jWhi7sqbFo +d1M6yTEALLgZU4dkU48+ODs+D/kpaT+n506ebx8aqn2NBlrpWQKBwQCtCCntlu2U +p0ZcBjXnliGJpxfEg1w6R/dj3w1Sju0M45UGqIoLFBmNpFSadBWE2JPBxuwUgqf/ +/eJoNUl6aIAr8NGF8EWvu16Hxg0Qx1vJkeBO9/EwoHZ8PmwXFzM2dW+P4yXmaDMI +Q+rvn7gI1UJk/1MxhfXpEWTxIyPTDhvHDb4iC6OPxt8+qNO/MRHCUyQ4grUOkeyQ +eSPW4pVejih5Kd+k5uFah8+PyoL7csVrt3RaOZiOCa7qq6L0CRmvXeI= +-----END RSA PRIVATE KEY----- diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_remote_location/pki/rsa-passphrase b/ansible_collections/cisco/mso/tests/integration/targets/mso_remote_location/pki/rsa-passphrase new file mode 100644 index 00000000..fce397fb --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_remote_location/pki/rsa-passphrase @@ -0,0 +1,42 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-128-CBC,234BAAD9A19386249918BB2C07874AD1 + +CUqdVbGGnu9XRtHfdVzZ0SvLGaEgkDTvBk5kNnkkSHXjlJTdpjzccD7K8sWKfSR+ +LpuTf4yGfkAQMFZBvTbrMuFYrkARxNh65i6U8YTp2punE0LzgI59ykOquz9XJKMz +c4fo4xQLqnEf3+XypwDLCrSaWLcWJ/5GDjDL0B+GexomOhj+07D3QPALtmj/4qWq +QC3Q3xb8hMQJelyC39Z4I3Gb2VIMxzvZi6rOeLtXd7OdrP5ZWT43XIC8U1Uo+Pp7 +g58XXDS1JmYDbVUqgVE73dvEfM3vtDmS3XpP8+8Wvm2ld5Ky55G+eG3xE2iellLT +q2THpzDvgQcvxIL+/E+kazCMv44aWuqeo2+BIRa2yKPicc9SXMyDibmvF5MjSiVb +/FdWd2pYzUl1z2lkhMv23H53o6Yu+3y+aOfyWPSSJHObZ+CNblKrnIP6Vj/oZ6XI +uwEqe9bwUwakrLUybgthFxw77fLr5k8miQk58sdp7fPl4l+6MRO9by+gXKD6SEmk +LK5OiqztiMHJrRb79WarCgiqelIXL4jz6dM/vNVZLcgqNLVAmxzMHm/p0bK3W2cU ++LQYeW51d9laQ1QeXY57jIaOMQhkoHqnkUqifrIWIzxdcl+lCtn3+MFZAXVI0tik +q9LqDVbDoxn0SuF1EELHx6AUFNJU5Rn/56DMYFUlWWXs22uKq7g1ci8NShSX1S2J +s/HkLFgHWE4IvvWmyyolRG5vh3VgUwdVdU4h+g8nkUaQm1OstbxmcfPOuYfsQpmY +jlhk/d4WZ3l3Et/Kjb4c25789xMfBgB6KReLapoE6nr7vg9oKfsFXIEiakwWRwHK +f/O9fiZZr55IDRX7herp3dYJqY5kINanl1s8FoFSoUc9opgY4ENg5FXer4RFLdWI +ZPAY9DPxXYY+MjGpEXrlA0W/kuTqNkUH3fMrX+0kEO0OCDDRcsUTJ8J//oRx//4O +UggbCK6DuZJLzlosRoabshkhCPHQxsujk5jeIZCI7Yae+UZCFXqgluXdFcRslFuR +BP1etL4qh3BFxmKpwq3dSwT3iqEd+kPK2HZXeWmy2E8XJhuL6+gc4ULohAKAjWWm +HrehCQjrQVG1dIOMuPFAXb2d4uhBZFIEf0yzs9HDNKlW2E0npr0yf7XHuI40E+mP +V70Wpb49Z1vhmtXp84k6Xu+QG9GPYceZG4jDaQupKunQbgaH1zSglExPLy1wAKIc +IX2nO8xXanMl6yx87eQtq+/Rvlrv8PyjbbLQlZt6TMKNWJlmH20OG5nA6E+L4sye +LGzkd/vA0b3jL0tNIXkteDT1oIS/OPW/7smWwNOeKbutdGPCxfuW52agLoxJwac+ +a3Z2G1TE9fIIJE9GnBjTp2IO5AZ/cUNsqkQhrPMb2F7w3lu+wBFV53KoJlkHpryJ +PHRP+can696UiauwHiq8C1ufcqnaNdktH2Gl1nFN5urDEkOLQ3bT+3Zpr9DJvhS7 +LekjXImMIsvjKgbEb16Hz9ZuQ2BPU1KNHv3KSrxR7f4RIA9KVoSsKd0NsqR47EVz +TyN1Aci2eu5ngeCNeQ2w8DYzx7ZS0tsL8xBTJa0dm10XmI1N+lLOYMZHeiBmaXXN +Rw5RRBqk22ulConecg44M78eLvWTxvNE5CQoO/fPRaaKu8f6zU/rig5AEsv+BPOO +HGEtRzpITF8icS+p8rHCd4YwiU+fJhtl77GA0zMcN/pPFavtW3nmL4jKtnOxq7Js +m5QNBp4dKllo70jT7/f6IlZD8CQibA1h34M4tn3NyTR7UI/2A0IsbyXEgriw0Pl+ +wKyPJ0vkkL8/0UoJ8Z+0QqrKZbH1a77myjDrLoGzlGzFmesPvmNIhWpPKEqnIJrx +JvEgxEET4Ry1/5dqovxmE20TMap4EX6LHuORJTqjCFtUn8y0m6+019EmW7Jvo7vs +uo/xMUXmbkAtQhYnN/bQkfV6L0QxwFAFHGDvC/8AzJdw146cjlZ1ReCWca6uEs1H +QoKwjIt4B+9WfNjCOLYe3iReDkTL/FW6Tkn15mYGSOql9Zza+sVvvxKYRbnyVh0g +gaRtundjZVtUPMkIYMSB8XEqdJ2pHJm1g+KJR+QsL21qeoWJ7D2MTqOY9ErDgh/c +mvrLWyajGVr6SsbwhOVfltCuR2bBeRwC75duqif3dnEWXipUhvTB/SR6u1m1SJ0p +IJfcPJI1KiRII4L0ihFk2WzXPQA3XbWVVWZ2wN9AqhtV6/e19xP2L1rgpfVwAf/i +Q/8mv5ACzo0V8UJRWgO4CA1yZqhUqUQHRUm6WjRJrGheQKdU3ZK9ZOAWY+yW/2La +QvCyfRIP8jW8EDic5m7VXWEE9vVxyLhTtH0BOgZNTfzCYhdhHeLXKehS9qqhmoy2 +-----END RSA PRIVATE KEY----- diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_remote_location/pki/rsa-passphrase.pub b/ansible_collections/cisco/mso/tests/integration/targets/mso_remote_location/pki/rsa-passphrase.pub new file mode 100644 index 00000000..0c9e393c --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_remote_location/pki/rsa-passphrase.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQColnrKInjNCJXLcAiEOLbTTiP9plzevk+VgMa++0vL7flNhbLJYFJMWgnZLYglUb3crJvR5grxn98iVrWcopLskk1p8yz1BR6Hal6Pv5ZFxKe1w487oQk2ShrV/vX9xC/86SHET0zjFrNNg8bjsYg/do+FzBDBuy/V5sQ6S427bK5h4z8/ld3VAbBopIEPLeuVg3z69aFhnMwNCSpbPjvCc2dJk1avUwLQj2Ol0FaWiYtE1ug9RAFVIWPpLYexkJh7l9OZR+BhgmspUq4w4QjPlhCGs85GpbQAo8fdoT+ukN4oOiLfhL62CAuCfaOEfO9//i7Kk7xQDpf0I5/qA2eGjve1AaTPjGRSk4l90tn5bt+655GIz62zUKSJKaT8Cn2gMbtNxXt1qNQqXxn4bnzVQjdfWKZpSIfTdrC7DgmWObWNMJQlhbaN4brvi4Z5mU3A0FukKDRgPCFykKvbVFtVhUWsBv+rBX0QToaCEwIYYvicLPBA2igYcVmx2NJAu0M= akinross@AKINROSS-M-M4WR diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_remote_location/pki/rsa.pub b/ansible_collections/cisco/mso/tests/integration/targets/mso_remote_location/pki/rsa.pub new file mode 100644 index 00000000..104b840e --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_remote_location/pki/rsa.pub @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCf+QU6NeUXg1Xlo79XQRBXVnRaqeyzl8ulD99sEeGr3xpqWkm/21Kd+OUEM6n2f8y/G52pZFA80x+9CRTLFw3U1tJ6LLdAxf6JaMW38L2r2iKPmbhzx2T6gn2p+FrrkQVWuVQY9zf7J0Qih+ewslsgjBao0yU8qqOqEL+IxZbsE6ReWJEajYYJgtgF0DTRbn2AjjGRuxzhDQGvq9Mshf4HMkde5OXhIVkUW8I9hKNb6Py3CFDY1SNpVuU4tm1ZsRXJvmGUonvdqVL9+d0gkofUjfWoZepLC+dhDCkvHa589MxNUEyriX7Sp+AiK/pIlXCIxUfEbow/99ZQBMk0TQMWMUZfrWokCoC6hr8/I4zo3TX90X3mO+WN3lZp+63ckYbFsnh/xPh8B4S+LcRf5rGWCNW1tSO6p7ILTdilL+Iy7wDo/fj90Q1swe7VeHpSOVNqpERvspmX82ynT68sVSsWv/xAeEezX0Lnha1CwTAPvf+mqjk+fX+BMhG7HbDbd7k= akinross@AKINROSS-M-M4WR diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_remote_location/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_remote_location/tasks/main.yml new file mode 100644 index 00000000..f93e6e0b --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_remote_location/tasks/main.yml @@ -0,0 +1,303 @@ +# Test code for the MSO modules +# Copyright: (c) 2022, 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: 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") }}' + +- name: Query all backups + cisco.mso.mso_backup: + <<: *mso_info + state: query + delegate_to: localhost + register: backups + +- name: Ensure all backups with link to remote location ansible_test are removed + cisco.mso.mso_backup: + <<: *mso_info + backup_id: "{{ item.id }}" + state: absent + when: + - item.location is defined + - item.location.locationType is defined + - item.location.locationType == "remote" + loop: "{{ backups.current | sort(attribute='name', reverse=True) }}" + delegate_to: localhost + +- name: Ensure remote location ansible_test is removed + cisco.mso.mso_remote_location: + <<: *mso_info + remote_location: ansible_test + state: absent + delegate_to: localhost + +- name: Configure remote location scp (check mode) + cisco.mso.mso_remote_location: &remote_location + <<: *mso_info + remote_location: ansible_test + remote_protocol: scp + remote_host: '{{ mso_remote_location }}' + remote_path: '{{ mso_remote_location_path | default("/tmp") }}' + authentication_type: password + remote_username: '{{ mso_remote_location_user | default(mso_username) }}' + remote_password: '{{ mso_remote_location_password | default(mso_password) }}' + state: present + check_mode: yes + delegate_to: localhost + register: cm_config_remote + +- name: Configure remote location scp + cisco.mso.mso_remote_location: + <<: *remote_location + delegate_to: localhost + register: nm_config_remote + +- name: Verify configuration + assert: + that: + - cm_config_remote is changed + - cm_config_remote.current.name == "ansible_test" + - cm_config_remote.current.credential.authType == "password" + - cm_config_remote.current.credential.port == 22 + - cm_config_remote.current.credential.protocolType == "scp" + - cm_config_remote.current.credential.hostname == '{{ mso_remote_location }}' + - cm_config_remote.current.credential.remotePath == '/tmp' + - cm_config_remote.current.credential.username == '{{ mso_remote_location_user | default(mso_username) }}' + - nm_config_remote is changed + - nm_config_remote.current.name == "ansible_test" + - nm_config_remote.current.credential.authType == "password" + - nm_config_remote.current.credential.port == 22 + - nm_config_remote.current.credential.protocolType == "scp" + - nm_config_remote.current.credential.hostname == '{{ mso_remote_location }}' + - nm_config_remote.current.credential.remotePath == '/tmp' + - nm_config_remote.current.credential.username == '{{ mso_remote_location_user | default(mso_username) }}' + - nm_config_remote.current.id is defined + +- name: Configure remote location again + cisco.mso.mso_remote_location: + <<: *remote_location + delegate_to: localhost + register: nm_config_remote_again + +- name: Verify configuration after again + assert: + that: + - nm_config_remote_again is not changed + +- name: Change remote location description (check mode) + cisco.mso.mso_remote_location: + <<: *remote_location + description: changed_description + check_mode: yes + delegate_to: localhost + register: cm_change_config_remote_description + +- name: Change remote location description + cisco.mso.mso_remote_location: + <<: *remote_location + description: changed_description + delegate_to: localhost + register: nm_change_config_remote_description + +- name: Verify configuration change + assert: + that: + - cm_change_config_remote_description is changed + - cm_change_config_remote_description.current.description == "changed_description" + - nm_change_config_remote_description is changed + - nm_change_config_remote_description.current.description == "changed_description" + +- name: Query remote location + cisco.mso.mso_remote_location: + <<: *remote_location + state: query + delegate_to: localhost + register: nm_query_remote + +- name: Query all remote locations + cisco.mso.mso_remote_location: + <<: *mso_info + state: query + delegate_to: localhost + register: nm_query_all_remotes + +- name: Query non existing remote location + cisco.mso.mso_remote_location: + <<: *mso_info + remote_location: non_existing + state: query + ignore_errors: yes + delegate_to: localhost + register: nm_query_non_existing + +- name: Verify queries + assert: + that: + - nm_query_remote is not changed + - nm_query_remote.current | type_debug == "dict" + - nm_query_all_remotes is not changed + - nm_query_all_remotes.current | type_debug == "list" + - nm_query_non_existing is not changed + - 'nm_query_non_existing.msg == "Remote location non_existing not found. Remote locations configured: ansible_test"' + +- name: Remove remote location (check mode) + cisco.mso.mso_remote_location: + <<: *remote_location + state: absent + check_mode: yes + delegate_to: localhost + register: cm_delete_config_remote + +- name: Remove remote location + cisco.mso.mso_remote_location: + <<: *remote_location + state: absent + delegate_to: localhost + register: nm_delete_config_remote + +- name: Verify delete + assert: + that: + - cm_delete_config_remote is changed + - cm_delete_config_remote.current == {} + - nm_delete_config_remote is changed + - nm_delete_config_remote.current == {} + +- name: Create remote location different path directory if it does not exist + ansible.builtin.file: + path: '{{ mso_remote_location_alternate_path | default("/home/"~mso_username) }}' + state: directory + mode: '0755' + +- name: Configure remote location different path (check mode) + cisco.mso.mso_remote_location: + <<: *remote_location + remote_path: '{{ mso_remote_location_alternate_path | default("/home/"~mso_username) }}' + check_mode: yes + delegate_to: localhost + register: cm_config_remote_different_path + +- name: Configure remote location different path + cisco.mso.mso_remote_location: + <<: *remote_location + remote_path: '{{ mso_remote_location_alternate_path | default("/home/"~mso_username) }}' + delegate_to: localhost + register: nm_config_remote_different_path + +- name: Verify configuration different path + assert: + that: + - cm_config_remote_different_path is changed + - cm_config_remote_different_path.current.credential.remotePath == '{{ mso_remote_location_alternate_path | default("/home/"~mso_username) }}' + - nm_config_remote_different_path is changed + - nm_config_remote_different_path.current.credential.remotePath == '{{ mso_remote_location_alternate_path | default("/home/"~mso_username) }}' + +- name: Remove remote location + cisco.mso.mso_remote_location: + <<: *remote_location + state: absent + delegate_to: localhost + +- name: Configure remote location sftp (check mode) + cisco.mso.mso_remote_location: + <<: *remote_location + remote_protocol: sftp + check_mode: yes + delegate_to: localhost + register: cm_config_remote_sftp + +- name: Configure remote location sftp + cisco.mso.mso_remote_location: + <<: *remote_location + remote_protocol: sftp + delegate_to: localhost + register: nm_config_remote_sftp + +- name: Verify configuration sftp + assert: + that: + - cm_config_remote_sftp is changed + - cm_config_remote_sftp.current.credential.protocolType == "sftp" + - nm_config_remote_sftp is changed + - nm_config_remote_sftp.current.credential.protocolType == "sftp" + +- name: Remove remote location + cisco.mso.mso_remote_location: + <<: *remote_location + state: absent + delegate_to: localhost + +- name: Configure remote location ssh (check mode) + cisco.mso.mso_remote_location: &remote_location_ssh + <<: *remote_location + authentication_type: ssh + remote_ssh_key: "{{ lookup('file', 'pki/rsa') }}" + check_mode: yes + delegate_to: localhost + register: cm_config_remote_ssh + +- name: Configure remote location ssh + cisco.mso.mso_remote_location: + <<: *remote_location_ssh + delegate_to: localhost + register: nm_config_remote_ssh + +- name: Verify configuration ssh + assert: + that: + - cm_config_remote_ssh is changed + - cm_config_remote_ssh.current.credential.authType == "sshKey" + - nm_config_remote_ssh is changed + - nm_config_remote_ssh.current.credential.authType == "sshKey" + +- name: Remove remote location + cisco.mso.mso_remote_location: + <<: *remote_location_ssh + state: absent + delegate_to: localhost + +- name: Configure remote location ssh with passphrase (check mode) + cisco.mso.mso_remote_location: &remote_location_ssh_pass + <<: *remote_location + authentication_type: ssh + remote_ssh_key: "{{ lookup('file', 'pki/rsa-passphrase') }}" + remote_ssh_passphrase: '{{ mso_output_level | default("ansible") }}' + check_mode: yes + delegate_to: localhost + register: cm_config_remote_ssh_pass + +- name: Configure remote location ssh with passphrase + cisco.mso.mso_remote_location: + <<: *remote_location_ssh_pass + delegate_to: localhost + register: nm_config_remote_ssh_pass + +- name: Verify configuration ssh + assert: + that: + - cm_config_remote_ssh_pass is changed + - cm_config_remote_ssh_pass.current.credential.authType == "sshKey" + - nm_config_remote_ssh_pass is changed + - nm_config_remote_ssh_pass.current.credential.authType == "sshKey" + +- name: Remove remote location + cisco.mso.mso_remote_location: + <<: *remote_location_ssh_pass + state: absent + delegate_to: localhost
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_rest/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_rest/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_rest/aliases @@ -0,0 +1,2 @@ +# No ACI MultiSite infrastructure, so not enabled +# unsupported diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_rest/tasks/error_handling.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_rest/tasks/error_handling.yml new file mode 100644 index 00000000..953f2761 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_rest/tasks/error_handling.yml @@ -0,0 +1,153 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Anvitha Jain (@anvitha-jain) <anvjain@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 + + +# SET VARs +- 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") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +# PROVOKE ERRORS +- name: Error when required parameter is missing + cisco.mso.mso_rest: + <<: *mso_info + output_level: debug + method: post + content: + displayName: mso_tenant + name: mso_tenant + description: MSO tenant + siteAssociations: [] + userAssociations: [] + _updateVersion: 0 + ignore_errors: yes + register: error_on_missing_required_param + +- name: Verify error_on_missing_required_param + assert: + that: + - error_on_missing_required_param is failed + - 'error_on_missing_required_param.msg == "missing required arguments: path"' + +- name: Error on name resolution + cisco.mso.mso_rest: + host: foo.bar.cisco.com + 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") }}' + path: /mso/api/v1/tenants + method: post + content: + fvFoobar: + displayName: mso_tenant + name: mso_tenant + description: This is description + siteAssociations: [] + userAssociations: [] + _updateVersion: 0 + ignore_errors: yes + register: error_on_name_resolution + +- name: Verify error_on_name_resolution + assert: + that: + - error_on_name_resolution is failed + +- name: Verify error_on_name_resolution + assert: + that: + - error_on_name_resolution.msg is search("Name or service not known") + when: + - version.current.version is version('3.7', '>=') + +- name: Error on invalid path + mso_rest: + <<: *mso_info + path: /mso/api/v1/tenant + method: post + content: + displayName: mso_tenant + name: mso_tenant + description: MSO tenant + siteAssociations: [] + userAssociations: [] + _updateVersion: 0 + ignore_errors: yes + register: error_on_invalid_path + +- name: Verify error_on_invalid_path + assert: + that: + - error_on_invalid_path is failed + - error_on_invalid_path.status == 404 + when: version.current.version is version('3.0.0a', '<') or version.current.version is version('3.2', '>=') + +- name: Verify error_on_invalid_path + assert: + that: + - error_on_invalid_path is failed + - error_on_invalid_path.status == 405 + when: + - version.current.version is version('3.0.0a', '>=') + - version.current.version is version('3.2', '<') + +- name: Error when attributes are missing + cisco.mso.mso_rest: + <<: *mso_info + path: /mso/api/v1/tenants + method: post + content: + children: + ignore_errors: yes + register: error_on_missing_attributes + +- name: Verify error_on_missing_attributes + assert: + that: + - error_on_missing_attributes is failed + - error_on_missing_attributes.status == 400 + +- name: Error when input does not validate + cisco.mso.mso_rest: + <<: *mso_info + path: /mso/api/v1/tenants + method: post + content: + displayName: 0 + name: 0 + descr: This is an [invalid] description + siteAssociations: [] + userAssociations: [] + _updateVersion: 0 + ignore_errors: yes + register: error_on_input_validation + +- name: Verify error_on_input_validation + assert: + that: + - error_on_input_validation is failed + - error_on_input_validation.status == 400 diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_rest/tasks/json_inline.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_rest/tasks/json_inline.yml new file mode 100644 index 00000000..d2959fd5 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_rest/tasks/json_inline.yml @@ -0,0 +1,287 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Anvitha Jain (@anvitha-jain) <anvjain@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") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Remove EXT_EPGs Providers from DHCP Relay Policy + mso_dhcp_relay_policy_provider: + <<: *mso_info + dhcp_relay_policy: ansible_dhcp_relay_1 + tenant: ansible_test + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_endpoint_group: "{{ item }}" + state: absent + ignore_errors: yes + loop: + - EXT_EPG_1 + - EXT_EPG_2 + +- name: Remove EXT_EPGs Providers from DHCP Relay Policy + mso_dhcp_relay_policy_provider: + <<: *mso_info + dhcp_relay_policy: ansible_dhcp_relay_1 + tenant: ansible_test + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + endpoint_group: "{{ item }}" + application_profile: "ANP_1" + state: absent + ignore_errors: yes + loop: + - EPG_1 + - EPG_2 + +- name: Stop consuming DHCP Policy + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + bd: CLIENT_BD + vrf: + name: VRF1 + state: absent + ignore_errors: yes + +- name: Remove DHCP Relay Policies + mso_dhcp_relay_policy: + <<: *mso_info + dhcp_relay_policy: '{{ item }}' + state: absent + ignore_errors: yes + loop: + - ansible_dhcp_relay_1 + - ansible_dhcp_relay_2 + +- name: Remove DHCP Option Policies + mso_dhcp_option_policy: + <<: *mso_info + dhcp_option_policy: '{{ item }}' + state: absent + ignore_errors: yes + loop: + - ansible_dhcp_option_1 + - ansible_dhcp_option_2 + +- name: Remove schemas + cisco.mso.mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + ignore_errors: yes + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Remove tenant ansible_test + mso_tenant: + <<: *mso_info + tenant: ansible_test + state: absent + ignore_errors: yes + +# QUERY SCHEMAS +- name: Query schema + mso_rest: + <<: *mso_info + path: /mso/api/v1/schemas + method: get + register: query_all_schema + +- name: Verify query_all_schema in json_inline + assert: + that: + - query_all_schema is not changed + +# QUERY A USER +- name: Query our user + mso_user: + <<: *mso_info + state: query + user: '{{ mso_username }}' + check_mode: yes + register: query_user_id + +- name: Verify query_user_id + assert: + that: + - query_user_id is not changed + - query_user_id.current.username == '{{ mso_username }}' + +# ADD tenant +- name: Add tenant + mso_rest: + <<: *mso_info + path: /api/v1/tenants + method: post + content: + { + "displayName": "ansible_test", + "name": "ansible_test", + "description": "", + "siteAssociations": [], + "userAssociations": [{ + "userId": "{{ query_user_id.current.id }}" + }], + "_updateVersion": 0, + } + register: add_tenant + +- name: Verify add_tenant in json_inline + assert: + that: + - add_tenant is changed + - add_tenant.jsondata.displayName == 'ansible_test' + +# ADD schema +- name: Add schema + mso_rest: + <<: *mso_info + path: /mso/api/v1/schemas + method: post + content: + { + "displayName": "{{ mso_schema | default('ansible_test') }}", + "templates": [{ + "name": "Template_1", + "tenantId": "{{ add_tenant.jsondata.id }}", + "displayName": "Template_1", + "templateSubType": [], + "templateType": "stretched-template", + "anps": [], + "contracts": [], + "vrfs": [], + "bds": [], + "filters": [], + "externalEpgs": [], + "serviceGraphs": [], + "intersiteL3outs": [] + }], + "sites": [], + "_updateVersion": 0 + } + register: add_schema + +- name: Verify add_schema in json_inline + assert: + that: + - add_schema is changed + - add_schema.jsondata.displayName == 'ansible_test' + +# PUT schema +- name: Put schema + mso_rest: + <<: *mso_info + port: 443 + path: "/mso/api/v1/schemas/{{ add_schema.jsondata.id }}" + method: put + content: + { + "displayName": "ansible_test_2", + "templates": [{ + "name": "Template_1", + "tenantId": "{{ add_tenant.jsondata.id }}", + "displayName": "Template_1", + "templateSubType": [], + "templateType": "stretched-template", + "anps": [], + "contracts": [], + "vrfs": [], + "bds": [], + "filters": [], + "externalEpgs": [], + "serviceGraphs": [], + "intersiteL3outs": [] + }], + "sites": [], + "_updateVersion": 0 + } + register: put_schema + +- name: Verify put_schema in json_inline + assert: + that: + - put_schema is changed + - put_schema.jsondata.displayName == 'ansible_test_2' + +# PATCH schema +- name: Patch schema + mso_rest: + <<: *mso_info + path: "/mso/api/v1/schemas/{{ add_schema.jsondata.id }}" + method: patch + content: + [ + { + "op": "add", + "path": "/templates/Template_1/anps/-", + "value": { "name": "AP2", "displayName": "AP2", "epgs": [] }, + "_updateVersion": 0 + } + ] + register: patch_schema + +- name: Verify patch_schema in json_inline + assert: + that: + - patch_schema is changed + +- name: Verify patch_schema in json_inline + assert: + that: + - patch_schema.jsondata.templates[0].anps[0].displayName == 'AP2' + # MSO 3.3 PATCH does not return anything anymore. + when: version.current.version is version('3.3', '<') + +# DELETE the schema +- name: Delete the schema + mso_rest: + <<: *mso_info + path: "/mso/api/v1/schemas/{{ add_schema.jsondata.id }}" + method: delete + register: delete_schema + +- name: Verify delete_schema in json_inline + assert: + that: + - delete_schema is changed + - delete_schema.jsondata == None + +# DELETE TENANT +- name: Delete the tenant + mso_rest: + <<: *mso_info + path: "/mso/api/v1/tenants/{{ add_tenant.jsondata.id }}" + method: delete + register: delete_tenant + +- name: Verify delete_tenant in json_inline + assert: + that: + - delete_tenant is changed + - delete_tenant.jsondata == None
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_rest/tasks/json_string.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_rest/tasks/json_string.yml new file mode 100644 index 00000000..ce6d801f --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_rest/tasks/json_string.yml @@ -0,0 +1,224 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Anvitha Jain (@anvitha-jain) <anvjain@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") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Remove schemas + cisco.mso.mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Remove tenant ansible_test + mso_tenant: + <<: *mso_info + tenant: ansible_test + state: absent + +# QUERY SCHEMAS +- name: Query schema + mso_rest: + <<: *mso_info + path: /mso/api/v1/schemas + method: get + register: query_all_schema + +- name: Verify query_all_schema + assert: + that: + - query_all_schema is not changed + +# QUERY A USER +- name: Query our user + mso_user: + <<: *mso_info + state: query + user: '{{ mso_username }}' + check_mode: yes + register: query_user_id + +- name: Verify query_user_id + assert: + that: + - query_user_id is not changed + - query_user_id.current.username == '{{ mso_username }}' + +# ADD tenant +- name: Add tenant + mso_rest: + <<: *mso_info + path: /api/v1/tenants + method: post + content: + { + "displayName": "ansible_test", + "name": "ansible_test", + "description": "", + "siteAssociations": [], + "userAssociations": [{ + "userId": "{{ query_user_id.current.id }}" + }], + "_updateVersion": 0, + } + register: add_tenant + +- name: Verify add_tenant in json_string + assert: + that: + - add_tenant is changed + - add_tenant.jsondata.displayName == 'ansible_test' + +# ADD schema +- name: Add schema + mso_rest: + <<: *mso_info + path: /mso/api/v1/schemas + method: post + content: | + { + "displayName": "{{ mso_schema | default('ansible_test') }}", + "templates": [{ + "name": "Template_1", + "tenantId": "{{ add_tenant.jsondata.id }}", + "displayName": "Template_1", + "templateSubType": [], + "templateType": "stretched-template", + "anps": [], + "contracts": [], + "vrfs": [], + "bds": [], + "filters": [], + "externalEpgs": [], + "serviceGraphs": [], + "intersiteL3outs": [] + }], + "sites": [], + "_updateVersion": 0 + } + register: add_schema + +- name: Verify add_schema in json_string + assert: + that: + - add_schema is changed + - add_schema.jsondata.displayName == 'ansible_test' + +# PUT schema +- name: Put schema + mso_rest: + <<: *mso_info + path: "/mso/api/v1/schemas/{{ add_schema.jsondata.id }}" + method: put + content: | + { + "displayName": "ansible_test_2", + "templates": [{ + "name": "Template_1", + "tenantId": "{{ add_tenant.jsondata.id }}", + "displayName": "Template_1", + "templateSubType": [], + "templateType": "stretched-template", + "anps": [], + "contracts": [], + "vrfs": [], + "bds": [], + "filters": [], + "externalEpgs": [], + "serviceGraphs": [], + "intersiteL3outs": [] + }], + "sites": [], + "_updateVersion": 0 + } + register: put_schema + +- name: Verify put_schema in json_string + assert: + that: + - put_schema is changed + - put_schema.jsondata.displayName == 'ansible_test_2' + +# PATCH schema +- name: Patch schema + mso_rest: + <<: *mso_info + path: "/mso/api/v1/schemas/{{ add_schema.jsondata.id }}" + method: patch + content: | + [ + { + "op": "add", + "path": "/templates/Template_1/anps/-", + "value": { "name": "AP2", "displayName": "AP2", "epgs": [] }, + "_updateVersion": 0 + } + ] + register: patch_schema + +- name: Verify patch_schema in json_string + assert: + that: + - patch_schema is changed + +- name: Verify patch_schema in json_string + assert: + that: + - patch_schema.jsondata.templates[0].anps[0].displayName == 'AP2' + # MSO 3.3 PATCH does not return anything anymore. + when: version.current.version is version('3.3', '<') + +# DELETE the schema +- name: Delete the schema + mso_rest: + <<: *mso_info + path: "/mso/api/v1/schemas/{{ add_schema.jsondata.id }}" + method: delete + register: delete_schema + +- name: Verify delete_schema in json_string + assert: + that: + - delete_schema is changed + - delete_schema.jsondata == None + +# DELETE TENANT +- name: Delete the tenant + mso_rest: + <<: *mso_info + path: "/mso/api/v1/tenants/{{ add_tenant.jsondata.id }}" + method: delete + register: delete_tenant + +- name: Verify delete_tenant in json_string + assert: + that: + - delete_tenant is changed + - delete_tenant.jsondata == None
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_rest/tasks/json_template.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_rest/tasks/json_template.yml new file mode 100644 index 00000000..960d9b52 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_rest/tasks/json_template.yml @@ -0,0 +1,67 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Anvitha Jain (@anvitha-jain) <anvjain@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") }}' + +- name: Remove schemas + cisco.mso.mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_1' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Remove tenant ansible_test + mso_tenant: + <<: *mso_info + tenant: ansible_test + state: absent + +# QUERY A USER +- name: Query our user + mso_user: + <<: *mso_info + state: query + user: '{{ mso_username }}' + check_mode: yes + register: query_user_id + +- name: Verify query_user_id + assert: + that: + - query_user_id is not changed + - query_user_id.current.username == '{{ mso_username }}' + +- name: Add a tenant from a templated payload file from templates + mso_rest: + <<: *mso_info + path: /api/v1/tenants + method: post + content: "{{ lookup('template', 'tenant.json.j2') }}" + register: add_tenant + +- name: Verify add_tenant in json_string + assert: + that: + - add_tenant is changed + - add_tenant.jsondata.displayName == 'ansible_test'
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_rest/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_rest/tasks/main.yml new file mode 100644 index 00000000..22851bf7 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_rest/tasks/main.yml @@ -0,0 +1,28 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Anvitha Jain (@anvitha-jain) <anvjain@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 + +- include_tasks: json_inline.yml + tags: json_inline + +- include_tasks: json_string.yml + tags: json_string + +- include_tasks: json_template.yml + tags: json_template + +- include_tasks: yaml_inline.yml + tags: yaml_inline + +- include_tasks: yaml_string.yml + tags: yaml_string + +- include_tasks: error_handling.yml + tags: error_handling diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_rest/tasks/tenant.json.j2 b/ansible_collections/cisco/mso/tests/integration/targets/mso_rest/tasks/tenant.json.j2 new file mode 100644 index 00000000..2d91ee76 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_rest/tasks/tenant.json.j2 @@ -0,0 +1,10 @@ +{ + "displayName": "ansible_test", + "name": "ansible_test", + "description": "", + "siteAssociations": [], + "userAssociations": [{ + "userId": "{{ query_user_id.current.id }}" + }], + "_updateVersion": 0, +}
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_rest/tasks/yaml_inline.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_rest/tasks/yaml_inline.yml new file mode 100644 index 00000000..d45e09e1 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_rest/tasks/yaml_inline.yml @@ -0,0 +1,214 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Anvitha Jain (@anvitha-jain) <anvjain@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") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Remove schemas + cisco.mso.mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Remove tenant ansible_test + mso_tenant: + <<: *mso_info + tenant: ansible_test + state: absent + +# QUERY SCHEMAS +- name: Query schema + mso_rest: + <<: *mso_info + path: /mso/api/v1/schemas + method: get + register: query_all_schema + +- name: Verify query_all_schema + assert: + that: + - query_all_schema is not changed + +# QUERY A USER +- name: Query our user + mso_user: + <<: *mso_info + state: query + user: '{{ mso_username }}' + check_mode: yes + register: query_user_id + +- name: Verify query_user_id + assert: + that: + - query_user_id is not changed + - query_user_id.current.username == '{{ mso_username }}' + +# ADD tenant +- name: Add tenant + mso_rest: + <<: *mso_info + path: /mso/api/v1/tenants + method: post + content: + displayName: ansible_test + name: ansible_test + description: MSO tenant + siteAssociations: [] + userAssociations: + - userId: '{{ query_user_id.current.id }}' + _updateVersion: 0 + register: add_tenant + +- name: Verify add_tenant in yaml_inline + assert: + that: + - add_tenant is changed + - add_tenant.jsondata.displayName == 'ansible_test' + +# ADD schema +- name: Add schema + mso_rest: + <<: *mso_info + path: /mso/api/v1/schemas + method: post + content: + displayName: '{{ mso_schema | default("ansible_test") }}' + templates: + - name: Template_1 + tenantId: '{{ add_tenant.jsondata.id }}' + displayName: Template_1 + templateSubType: [] + templateType: stretched-template + anps: [] + contracts: [] + vrfs: [] + bds: [] + filters: [] + externalEpgs: [] + serviceGraphs: [] + intersiteL3outs: [] + sites: [] + _updateVersion: 0 + register: add_schema + +- name: Verify add_schema in yaml_inline + assert: + that: + - add_schema is changed + - add_schema.jsondata.displayName == 'ansible_test' + +# PUT schema +- name: Put schema + mso_rest: + <<: *mso_info + path: "/mso/api/v1/schemas/{{ add_schema.jsondata.id }}" + method: put + content: + displayName: ansible_test_2 + templates: + - name: Template_1 + tenantId: '{{ add_tenant.jsondata.id }}' + displayName: Template_1 + templateSubType: [] + templateType: stretched-template + anps: [] + contracts: [] + vrfs: [] + bds: [] + filters: [] + externalEpgs: [] + serviceGraphs: [] + intersiteL3outs: [] + sites: [] + _updateVersion: 0 + register: put_schema + +- name: Verify put_schema in yaml_inline + assert: + that: + - put_schema is changed + - put_schema.jsondata.displayName == 'ansible_test_2' + +# PATCH schema +- name: Patch schema + mso_rest: + <<: *mso_info + path: "/mso/api/v1/schemas/{{ add_schema.jsondata.id }}" + method: patch + content: + - op: add + path: /templates/Template_1/anps/- + value: + name: AP2 + displayName: AP2 + epgs: [] + _updateVersion: 0 + register: patch_schema + +- name: Verify patch_schema in yaml_inline + assert: + that: + - patch_schema is changed + +- name: Verify patch_schema in yaml_inline + assert: + that: + - patch_schema.jsondata.templates[0].anps[0].displayName == 'AP2' + # MSO 3.3 PATCH does not return anything anymore. + when: version.current.version is version('3.3', '<') + +# DELETE the schema +- name: Delete the schema + mso_rest: + <<: *mso_info + path: "/mso/api/v1/schemas/{{ add_schema.jsondata.id }}" + method: delete + register: delete_schema + +- name: Verify delete_schema in yaml_inline + assert: + that: + - delete_schema is changed + - delete_schema.jsondata == None + +# DELETE TENANT +- name: Delete the tenant + mso_rest: + <<: *mso_info + path: "/mso/api/v1/tenants/{{ add_tenant.jsondata.id }}" + method: delete + register: delete_tenant + +- name: Verify delete_tenant in yaml_inline + assert: + that: + - delete_tenant is changed + - delete_tenant.jsondata == None
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_rest/tasks/yaml_string.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_rest/tasks/yaml_string.yml new file mode 100644 index 00000000..e5946e54 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_rest/tasks/yaml_string.yml @@ -0,0 +1,214 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Anvitha Jain (@anvitha-jain) <anvjain@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") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Remove schemas + cisco.mso.mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Remove tenant ansible_test + mso_tenant: + <<: *mso_info + tenant: ansible_test + state: absent + +# QUERY SCHEMAS +- name: Query schema + mso_rest: + <<: *mso_info + path: /mso/api/v1/schemas + method: get + register: query_all_schema + +- name: Verify query_all_schema + assert: + that: + - query_all_schema is not changed + +# QUERY A USER +- name: Query our user + mso_user: + <<: *mso_info + state: query + user: '{{ mso_username }}' + check_mode: yes + register: query_user_id + +- name: Verify query_user_id + assert: + that: + - query_user_id is not changed + - query_user_id.current.username == '{{ mso_username }}' + +# ADD tenant +- name: Add tenant + mso_rest: + <<: *mso_info + path: /mso/api/v1/tenants + method: post + content: + displayName: ansible_test + name: ansible_test + description: MSO tenant + siteAssociations: [] + userAssociations: + - userId: '{{ query_user_id.current.id }}' + _updateVersion: 0 + register: add_tenant + +- name: Verify add_tenant in yaml_string + assert: + that: + - add_tenant is changed + - add_tenant.jsondata.displayName == 'ansible_test' + +# ADD schema +- name: Add schema + mso_rest: + <<: *mso_info + path: /mso/api/v1/schemas + method: post + content: + displayName: '{{ mso_schema | default("ansible_test") }}' + templates: + - name: Template_1 + tenantId: '{{ add_tenant.jsondata.id }}' + displayName: Template_1 + templateSubType: [] + templateType: stretched-template + anps: [] + contracts: [] + vrfs: [] + bds: [] + filters: [] + externalEpgs: [] + serviceGraphs: [] + intersiteL3outs: [] + sites: [] + _updateVersion: 0 + register: add_schema + +- name: Verify add_schema in yaml_string + assert: + that: + - add_schema is changed + - add_schema.jsondata.displayName == 'ansible_test' + +# PUT schema +- name: Put schema + mso_rest: + <<: *mso_info + path: "/mso/api/v1/schemas/{{ add_schema.jsondata.id }}" + method: put + content: + displayName: ansible_test_2 + templates: + - name: Template_1 + tenantId: '{{ add_tenant.jsondata.id }}' + displayName: Template_1 + templateSubType: [] + templateType: stretched-template + anps: [] + contracts: [] + vrfs: [] + bds: [] + filters: [] + externalEpgs: [] + serviceGraphs: [] + intersiteL3outs: [] + sites: [] + _updateVersion: 0 + register: put_schema + +- name: Verify put_schema in yaml_string + assert: + that: + - put_schema is changed + - put_schema.jsondata.displayName == 'ansible_test_2' + +# PATCH schema +- name: Patch schema + mso_rest: + <<: *mso_info + path: "/mso/api/v1/schemas/{{ add_schema.jsondata.id }}" + method: patch + content: + - op: add + path: /templates/Template_1/anps/- + value: + name: AP2 + displayName: AP2 + epgs: [] + _updateVersion: 0 + register: patch_schema + +- name: Verify patch_schema in yaml_string + assert: + that: + - patch_schema is changed + +- name: Verify patch_schema in yaml_string + assert: + that: + - patch_schema.jsondata.templates[0].anps[0].displayName == 'AP2' + # MSO 3.3 PATCH does not return anything anymore. + when: version.current.version is version('3.3', '<') + +# DELETE the schema +- name: Delete the schema + mso_rest: + <<: *mso_info + path: "/mso/api/v1/schemas/{{ add_schema.jsondata.id }}" + method: delete + register: delete_schema + +- name: Verify delete_schema in yaml_string + assert: + that: + - delete_schema is changed + - delete_schema.jsondata == None + +# DELETE TENANT +- name: Delete the tenant + mso_rest: + <<: *mso_info + path: "/mso/api/v1/tenants/{{ add_tenant.jsondata.id }}" + method: delete + register: delete_tenant + +- name: Verify delete_tenant in yaml_string + assert: + that: + - delete_tenant is changed + - delete_tenant.jsondata == None
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_role/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_role/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_role/aliases @@ -0,0 +1,2 @@ +# No ACI MultiSite infrastructure, so not enabled +# unsupported diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_role/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_role/tasks/main.yml new file mode 100644 index 00000000..a27a0e16 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_role/tasks/main.yml @@ -0,0 +1,44 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Lionel Hercot (@lhercot) <lhercot@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") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Set version vars + set_fact: + mso_rw: true + when: + - version.current.version is version('2.2.4', '<') + +- name: Import tasks if RW of role in this MSO version + import_tasks: role-rw.yml + when: mso_rw is defined + +- name: Import tasks if RO of role in this MSO version + import_tasks: role-ro.yml + when: + - mso_rw is not defined + - version.current.version is version('3.2', '<')
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_role/tasks/role-ro.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_role/tasks/role-ro.yml new file mode 100644 index 00000000..e9a36a48 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_role/tasks/role-ro.yml @@ -0,0 +1,88 @@ +# Test code for the MSO modules +# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> +# Copyright: (c) 2020, Lionel Hercot (@lhercot) <lhercot@cisco.com> + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + + +# 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") }}' + + +# QUERY ALL ROLES +- name: Query all roles (check_mode) + mso_role: &role_query + <<: *mso_info + state: query + check_mode: yes + register: cm_query_all_roles + +- name: Query all roles (normal mode) + mso_role: *role_query + register: nm_query_all_roles + +- name: Verify query_all_roles + assert: + that: + - cm_query_all_roles is not changed + - nm_query_all_roles is not changed + # NOTE: Order of roles is not stable between calls + #- cm_query_all_roles == nm_query_all_roles + + +# QUERY A ROLE +- name: Query our role + mso_role: + <<: *role_query + role: powerUser + check_mode: yes + register: cm_query_role + +- name: Query our role + mso_role: + <<: *role_query + role: powerUser + register: nm_query_role + +- name: Verify query_role + assert: + that: + - cm_query_role is not changed + - cm_query_role.current.description == 'Elevates this user to \"admin\"' + - cm_query_role.current.displayName == 'Power User' + - nm_query_role is not changed + - nm_query_role.current.description == 'Elevates this user to \"admin\"' + - nm_query_role.current.displayName == 'Power User' + - cm_query_role == nm_query_role + + +# QUERY NON-EXISTING ROLE +- name: Query non-existing role (check_mode) + mso_role: + <<: *role_query + role: non-existing-role + check_mode: yes + register: cm_query_non_role + +- name: Query non-existing role (normal mode) + mso_role: + <<: *role_query + role: non-existing-role + register: nm_query_non_role + +# TODO: Implement more tests +- name: Verify query_non_role + assert: + that: + - cm_query_non_role is not changed + - nm_query_non_role is not changed + - cm_query_non_role == nm_query_non_role diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_role/tasks/role-rw.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_role/tasks/role-rw.yml new file mode 100644 index 00000000..44a9ba51 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_role/tasks/role-rw.yml @@ -0,0 +1,275 @@ +# Test code for the MSO modules +# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> +# Copyright: (c) 2020, Lionel Hercot (@lhercot) <lhercot@cisco.com> + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + + +# 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") }}' + +- name: Remove role ansible_test + mso_role: &role_absent + <<: *mso_info + role: ansible_test + state: absent + +- name: Remove role ansible_test2 + mso_role: + <<: *role_absent + role: ansible_test2 + register: cm_remove_role + + +# ADD ROLE +- name: Add role (check_mode) + mso_role: &role_present + <<: *mso_info + role: ansible_test + description: Ansible test role + read_permissions: view-sites + write_permissions: manage-sites + state: present + check_mode: yes + register: cm_add_role + +- name: Verify cm_add_role + assert: + that: + - cm_add_role is changed + - cm_add_role.previous == {} + - cm_add_role.current.description == 'Ansible test role' + - cm_add_role.current.displayName == 'ansible_test' + - cm_add_role.current.id is not defined + +- name: Add role (normal mode) + mso_role: *role_present + register: nm_add_role + +- name: Verify nm_add_role + assert: + that: + - nm_add_role is changed + - nm_add_role.previous == {} + - nm_add_role.current.description == 'Ansible test role' + - nm_add_role.current.displayName == 'ansible_test' + - nm_add_role.current.id is defined + +- name: Add role again (check_mode) + mso_role: *role_present + check_mode: yes + register: cm_add_role_again + +- name: Verify cm_add_role_again + assert: + that: + - cm_add_role_again is not changed + - cm_add_role_again.previous.description == 'Ansible test role' + - cm_add_role_again.previous.displayName == 'ansible_test' + - cm_add_role_again.current.description == 'Ansible test role' + - cm_add_role_again.current.displayName == 'ansible_test' + - cm_add_role_again.current.id == nm_add_role.current.id + +- name: Add role again (normal mode) + mso_role: *role_present + register: nm_add_role_again + +- name: Verify nm_add_role_again + assert: + that: + - nm_add_role_again is not changed + - nm_add_role_again.previous.description == 'Ansible test role' + - nm_add_role_again.previous.displayName == 'ansible_test' + - nm_add_role_again.current.description == 'Ansible test role' + - nm_add_role_again.current.displayName == 'ansible_test' + - nm_add_role_again.current.id == nm_add_role.current.id + + +# CHANGE ROLE +- name: Change role (check_mode) + mso_role: + <<: *role_present + role: ansible_test + description: Ansible test role 2 + check_mode: yes + register: cm_change_role + +- name: Verify cm_change_role + assert: + that: + - cm_change_role is changed + - cm_change_role.current.description == 'Ansible test role 2' + - cm_change_role.current.displayName == 'ansible_test' + - cm_change_role.current.id == nm_add_role.current.id + +- name: Change role (normal mode) + mso_role: + <<: *role_present + role: ansible_test + description: Ansible test role 2 + output_level: debug + register: nm_change_role + +- name: Verify nm_change_role + assert: + that: + - nm_change_role is changed + - nm_change_role.current.description == 'Ansible test role 2' + #- nm_change_role.current.displayName == 'ansible_test2' + - nm_change_role.current.id == nm_add_role.current.id + +- name: Change role again (check_mode) + mso_role: + <<: *role_present + role: ansible_test + description: Ansible test role 2 + check_mode: yes + register: cm_change_role_again + +- name: Verify cm_change_role_again + assert: + that: + - cm_change_role_again is not changed + - cm_change_role_again.current.description == 'Ansible test role 2' + - cm_change_role_again.current.displayName == 'ansible_test' + - cm_change_role_again.current.id == nm_add_role.current.id + +- name: Change role again (normal mode) + mso_role: + <<: *role_present + role: ansible_test + description: Ansible test role 2 + register: nm_change_role_again + +- name: Verify nm_change_role_again + assert: + that: + - nm_change_role_again is not changed + - nm_change_role_again.current.description == 'Ansible test role 2' + - nm_change_role_again.current.displayName == 'ansible_test' + - nm_change_role_again.current.id == nm_add_role.current.id + + +# QUERY ALL ROLES +- name: Query all roles (check_mode) + mso_role: &role_query + <<: *mso_info + state: query + check_mode: yes + register: cm_query_all_roles + +- name: Query all roles (normal mode) + mso_role: *role_query + register: nm_query_all_roles + +- name: Verify query_all_roles + assert: + that: + - cm_query_all_roles is not changed + - nm_query_all_roles is not changed + # NOTE: Order of roles is not stable between calls + #- cm_query_all_roles == nm_query_all_roles + + +# QUERY A ROLE +- name: Query our role + mso_role: + <<: *role_query + role: ansible_test + check_mode: yes + register: cm_query_role + +- name: Query our role + mso_role: + <<: *role_query + role: ansible_test + register: nm_query_role + +- name: Verify query_role + assert: + that: + - cm_query_role is not changed + - cm_query_role.current.description == 'Ansible test role 2' + - cm_query_role.current.displayName == 'ansible_test' + - cm_query_role.current.id == nm_add_role.current.id + - nm_query_role is not changed + - nm_query_role.current.description == 'Ansible test role 2' + - nm_query_role.current.displayName == 'ansible_test' + - nm_query_role.current.id == nm_add_role.current.id + - cm_query_role == nm_query_role + + +# REMOVE ROLE +- name: Remove role (check_mode) + mso_role: *role_absent + check_mode: yes + register: cm_remove_role + +- name: Verify cm_remove_role + assert: + that: + - cm_remove_role is changed + - cm_remove_role.current == {} + +- name: Remove role (normal mode) + mso_role: *role_absent + register: nm_remove_role + +- name: Verify nm_remove_role + assert: + that: + - nm_remove_role is changed + - nm_remove_role.current == {} + +- name: Remove role again (check_mode) + mso_role: *role_absent + check_mode: yes + register: cm_remove_role_again + +- name: Verify cm_remove_role_again + assert: + that: + - cm_remove_role_again is not changed + - cm_remove_role_again.current == {} + +- name: Remove role again (normal mode) + mso_role: *role_absent + register: nm_remove_role_again + +- name: Verify nm_remove_role_again + assert: + that: + - nm_remove_role_again is not changed + - nm_remove_role_again.current == {} + + +# QUERY NON-EXISTING ROLE +- name: Query non-existing role (check_mode) + mso_role: + <<: *role_query + role: non-existing-role + check_mode: yes + register: cm_query_non_role + +- name: Query non-existing role (normal mode) + mso_role: + <<: *role_query + role: non-existing-role + register: nm_query_non_role + +# TODO: Implement more tests +- name: Verify query_non_role + assert: + that: + - cm_query_non_role is not changed + - nm_query_non_role is not changed + - cm_query_non_role == nm_query_non_role diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema/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/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema/tasks/main.yml new file mode 100644 index 00000000..dc0613fe --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema/tasks/main.yml @@ -0,0 +1,117 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Cindy Zhao (@cizhao) <cizhao@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") }}' + +- name: Remove schemas + cisco.mso.mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Ensure tenant ansible_test exists + cisco.mso.mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + state: present + +- name: Create schema 1 with Template 1, and Template 2, Template 3 exist + cisco.mso.mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: '{{item.template}}' + state: present + loop: + - { template: Template 1} + - { template: Template 2} + - { template: Template 3} + +- name: Create schema 2 with Template 4 + cisco.mso.mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template 4 + state: present + +- name: Query for all schemas + cisco.mso.mso_schema: + <<: *mso_info + state: query + register: query_all + +- name: Query a schema + cisco.mso.mso_schema: + <<: *mso_info + schema: ansible_test + state: query + register: query_one + +- name: Verify query_all and query_one + assert: + that: + - query_all is not changed + - query_one is not changed + - query_all.current | length >= 2 + - query_one.current.displayName == "ansible_test" + +- name: Remove schema (check_mode) + cisco.mso.mso_schema: + <<: *mso_info + schema: ansible_test + state: absent + check_mode: yes + register: cm_rm_schema + +- name: Remove schema (normal_mode) + cisco.mso.mso_schema: + <<: *mso_info + schema: ansible_test + state: absent + register: nm_rm_schema + +- name: Verify rm_schema + assert: + that: + - cm_rm_schema is changed + - cm_rm_schema.previous.displayName == "ansible_test" + - cm_rm_schema.current == {} + - nm_rm_schema is changed + - nm_rm_schema.current == {} + - nm_rm_schema.previous.displayName == "ansible_test" + +- name: Query non_existing schema + cisco.mso.mso_schema: + <<: *mso_info + schema: non_existing + state: query + register: query_non_existing + +- name: Verify query_non_existing + assert: + that: + - query_non_existing is not changed + - query_non_existing.current == {} diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_clone/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_clone/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_clone/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_clone/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_clone/tasks/main.yml new file mode 100644 index 00000000..9b3a471c --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_clone/tasks/main.yml @@ -0,0 +1,158 @@ +# Test code for the MSO modules +# Copyright: (c) 2021, Anvitha Jain (@anvitha-jain) <anvjain@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") }}' + +- name: Remove schemas + cisco.mso.mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + ignore_errors: yes + loop: + - Destination_Schema + - Source_Schema + +- name: Ensure site exists + mso_site: + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + apic_username: '{{ apic_username }}' + apic_password: '{{ apic_password }}' + apic_site_id: '{{ apic_site_id | default(101) }}' + urls: + - https://{{ apic_hostname }} + state: present + +- name: Ensure tenant ansible_test exists + mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + sites: + - '{{ mso_site | default("ansible_test") }}' + state: present + +- name: Create Source schema with Template 1, and Template 2, Template 3 exist + cisco.mso.mso_schema_template: + <<: *mso_info + schema: Source_Schema + tenant: ansible_test + template: '{{item.template}}' + state: present + loop: + - { template: Template 1} + - { template: Template 2} + - { template: Template 3} + +- name: Ensure VRF exist + mso_schema_template_vrf: &vrf_present + <<: *mso_info + schema: Source_Schema + template: Template1 + vrf: VRF1 + state: present + +- name: Add bd in Source schema + mso_schema_template_bd: &bd_present + <<: *mso_info + schema: Source_Schema + template: Template1 + bd: BD_1 + vrf: + name: VRF1 + state: present + +- name: Clone schema + cisco.mso.mso_schema_clone: + <<: *mso_info + source_schema: Source_Schema + destination_schema: Destination_Schema + state: clone + register: add_schema + +- name: Verify add_schema + assert: + that: + - add_schema is changed + - add_schema.previous == {} + - add_schema.current.displayName == 'Destination_Schema' + +- name: Clone schema with same name + cisco.mso.mso_schema_clone: + <<: *mso_info + source_schema: Source_Schema + destination_schema: Source_Schema + state: clone + ignore_errors: yes + register: add_same_schema + +- name: Verify add_same_schema + assert: + that: + - add_same_schema is not changed + - add_same_schema.current == {} + - add_same_schema.msg == "Source and Destination schema cannot have same names." + +- name: Clone schema when destination schema exists + cisco.mso.mso_schema_clone: + <<: *mso_info + source_schema: Source_Schema + destination_schema: Destination_Schema + state: clone + ignore_errors: yes + register: add_existing_schema + +- name: Verify add_existing_schema + assert: + that: + - add_existing_schema is not changed + - add_existing_schema.msg == "Schema with the name 'Destination_Schema' already exists. Please use another name." + +- name: Clone schema when source schema does not exist + cisco.mso.mso_schema_clone: + <<: *mso_info + source_schema: Source_Schema_1 + destination_schema: Destination_Schema_2 + state: clone + ignore_errors: yes + register: add_existing_schema + +- name: Verify add_existing_schema + assert: + that: + - add_existing_schema is not changed + - add_existing_schema.msg == "Provided schema 'Source_Schema_1' does not exist." + +- name: Remove schemas + cisco.mso.mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + register: rm_schema + loop: + - Destination_Schema + - Source_Schema + +- name: Verify rm_schema + assert: + that: + - rm_schema is changed
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site/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/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site/tasks/main.yml new file mode 100644 index 00000000..b7633b74 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site/tasks/main.yml @@ -0,0 +1,273 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Shreyas Srish (@shrsr) <ssrish@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") }}' + +- name: Ensure site exists + mso_site: + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + apic_username: '{{ apic_username }}' + apic_password: '{{ apic_password }}' + apic_site_id: '{{ apic_site_id | default(101) }}' + urls: + - https://{{ apic_hostname }} + state: present + ignore_errors: yes + +- name: Remove schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Ensure sites removed from tenant ansible_test + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: '{{ item }}' + state: absent + loop: + - '{{ mso_site | default("ansible_test") }}' + - 'aws_{{ mso_site | default("ansible_test") }}' + - 'azure_{{ mso_site | default("ansible_test") }}' + +- name: Ensure tenant ansible_test exists + mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + sites: + - '{{ mso_site | default("ansible_test") }}' + state: present + +- name: Ensure schema 1 with Template 1 and Template 2 exists + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: '{{item.template}}' + state: present + loop: + - { template: Template 1} + - { template: Template 2} + +- name: Add a new site to a schema with Template 1 in check mode + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + state: present + check_mode: yes + register: add_site_cm + +- name: Verify add_site_cm + assert: + that: + - add_site_cm.current.siteId is match ("[0-9a-zA-Z]*") + - add_site_cm.current.templateName == "Template1" + +- name: Add a new site to a schema with Template 1 in normal mode + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + state: present + register: add_site_nm + +- name: Verify add_site_nm + assert: + that: + - add_site_nm.current.siteId is match ("[0-9a-zA-Z]*") + - add_site_nm.current.templateName == "Template1" + +- name: Add a new site to a schema in normal mode again + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + state: present + register: add_site_nm_again + +- name: Verify add_site_nm_again + assert: + that: + - add_site_nm_again is not changed + - add_site_nm_again.current.siteId is match ("[0-9a-zA-Z]*") + +- name: Add a new site to a schema with Template 2 in normal mode + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 2 + state: present + output_level: debug + register: add_site_temp2_nm + +- name: Verify add_site_temp2_nm + assert: + that: + - add_site_temp2_nm.current.siteId is match ("[0-9a-zA-Z]*") + - add_site_temp2_nm.current.templateName == "Template2" + - add_site_temp2_nm.method == "PATCH" + - add_site_temp2_nm.patch_operation != [] + - add_site_temp2_nm.patch_operation.0.value.templateName == "Template2" + - add_site_temp2_nm.previous == {} + - add_site_temp2_nm.proposed != {} + - add_site_temp2_nm.proposed.templateName == "Template2" + - add_site_temp2_nm.sent != {} + - add_site_temp2_nm.sent.templateName == "Template2" + +- name: Query a schema site + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + state: query + register: query_site + +- name: Query all schema sites + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + state: query + register: query_all_sites + +- name: Verify query_site and query_all_sites + assert: + that: + - query_site is not changed + - query_all_sites is not changed + - query_all_sites.current | length == 2 + +- name: Remove a site from a schema with Template1 + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + state: absent + register: rm_site_temp1 + +- name: Remove a site from a schema with Template2 + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 2 + state: absent + register: rm_site_temp2 + +- name: Verify rm_site_temp1 and rm_site_temp2 + assert: + that: + - rm_site_temp1 is changed + - rm_site_temp1.current == {} + - rm_site_temp2 is changed + - rm_site_temp2.current == {} + +- name: Remove a site from a schema with Template2 again + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 2 + state: absent + register: rm_site_again + +- name: Verify rm_site_again + assert: + that: + - rm_site_again is not changed + +# USE NON-EXISTING STATE +- name: non_existing_state state + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + state: non_existing_state + ignore_errors: yes + register: non_existing_state + +- name: Verify non_existing_state + assert: + that: + - non_existing_state is not changed + - non_existing_state.msg == "value of state must be one of{{':'}} absent, present, query, got{{':'}} non_existing_state" + +# USE A NON_EXISTING_SCHEMA +- name: non_existing_schema + mso_schema_site: + <<: *mso_info + schema: non_existing_schema + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + state: query + ignore_errors: yes + register: non_existing_schema + +- name: Verify non_existing_schema + assert: + that: + - non_existing_schema is not changed + - non_existing_schema.msg == "Provided schema 'non_existing_schema' does not exist." + +# USE A NON_EXISTING_TEMPLATE +- name: non_existing_template + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: non_existing_template + state: query + ignore_errors: yes + register: non_existing_template + +- name: Verify non_existing_template + assert: + that: + - non_existing_template is not changed + - non_existing_template.msg == "Template 'non_existing_template' not found" + +- name: Template attribute absent in task + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + state: query + ignore_errors: yes + register: absent_template + +- name: Verify absent_template + assert: + that: + - absent_template is not changed + - absent_template.current == []
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_anp/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_anp/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_anp/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/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_anp/tasks/main.yml new file mode 100644 index 00000000..e533abe2 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_anp/tasks/main.yml @@ -0,0 +1,481 @@ +# Test code for the MSO modules +# Copyright: (c) 2021, Anvitha Jain (@anvitha-jain) <anvjain@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") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Remove schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Ensure physical site exists + mso_site: + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + apic_username: '{{ apic_username }}' + apic_password: '{{ apic_password }}' + apic_site_id: '{{ apic_site_id | default(101) }}' + urls: + - https://{{ apic_hostname }} + state: present + +- name: Ensure aws site exists + mso_site: + <<: *mso_info + site: 'aws_{{ mso_site | default("ansible_test") }}' + apic_username: '{{ aws_apic_username }}' + apic_password: '{{ aws_apic_password }}' + apic_site_id: '{{ aws_site_id | default(102) }}' + urls: + - https://{{ aws_apic_hostname }} + state: present + +- name: Ensure azure site exists + mso_site: + <<: *mso_info + site: 'azure_{{ mso_site | default("ansible_test") }}' + apic_username: '{{ azure_apic_username }}' + apic_password: '{{ azure_apic_password }}' + apic_site_id: '{{ azure_site_id | default(103) }}' + urls: + - https://{{ azure_apic_hostname }} + state: present + +- name: Ensure sites removed from tenant ansible_test + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: '{{ item }}' + state: absent + loop: + - '{{ mso_site | default("ansible_test") }}' + - 'aws_{{ mso_site | default("ansible_test") }}' + - 'azure_{{ mso_site | default("ansible_test") }}' + +- name: Ensure tenant ansible_test exists + mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + state: present + +- name: Associate non-cloud site with ansible_test again in normal mode + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: '{{ mso_site | default("ansible_test") }}' + state: present + +- name: Associate aws site with ansible_test in normal mode + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'aws_{{ mso_site | default("ansible_test") }}' + cloud_account: "000000000000" + aws_trusted: false + aws_access_key: "1" + secret_key: "0" + state: present + register: aaws_nm + +- name: Associate azure site with access_type not present, with ansible_test in normal mode + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'azure_{{ mso_site | default("ansible_test") }}' + cloud_account: uni/tn-ansible_test/act-[100]-vendor-azure + state: present + register: aazure_shared_nm + +- name: Ensure schema 1 with Template 1, and Template 2 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: '{{item.template}}' + state: present + loop: + - { template: Template 1} + - { template: Template 2} + - { template: Template 3} + +- name: Ensure schema 2 with Template 4 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template 4 + state: present + +- name: Add cloud site to a schema + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{item.site}}' + template: '{{item.template}}' + state: present + loop: + - { site: 'azure_{{ mso_site | default("ansible_test") }}', template: 'Template 1' } + - { site: 'aws_{{ mso_site | default("ansible_test") }}', template: 'Template 2' } + +- name: Add physical site to a schema + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 3 + state: present + +- name: Ensure VRF1 exists + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 3 + vrf: VRF1 + state: present + +- name: Add BD1 + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 3 + bd: BD1 + vrf: + name: VRF1 + state: present + +- name: Ensure ANPs exist at template level + mso_schema_template_anp: + <<: *mso_info + schema: '{{item.schema}}' + template: '{{ item.template }}' + anp: '{{ item.anp }}' + state: present + loop: + - { schema: '{{ mso_schema | default("ansible_test") }}', template: 'Template 1', anp: 'ANP' } + - { schema: '{{ mso_schema | default("ansible_test") }}', template: 'Template 2', anp: 'ANP_2' } + - { schema: '{{ mso_schema | default("ansible_test") }}', template: 'Template 3', anp: 'ANP_3' } + - { schema: '{{ mso_schema | default("ansible_test") }}', template: 'Template 3', anp: 'ANP_3_1' } + - { schema: '{{ mso_schema | default("ansible_test") }}', template: 'Template 3', anp: 'ANP_3_2' } + - { schema: '{{ mso_schema | default("ansible_test") }}_2', template: 'Template 4', anp: 'ANP_4' } + +- name: Ensure EPGs exist at template level + mso_schema_template_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 3 + anp: ANP_3 + epg: ansible_test_3 + vrf: + name: VRF1 + schema: ansible_test + template: Template 3 + bd: + name: BD1 + schema: ansible_test + template: Template 3 + state: present + +- name: Add ANP to site azure (check_mode) + mso_schema_site_anp: + <<: *mso_info + site: 'azure_{{ mso_site | default("ansible_test") }}' + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + state: present + check_mode: yes + register: cm_add_anp + +- name: Add ANP to site azure (normal mode) + mso_schema_site_anp: + <<: *mso_info + site: 'azure_{{ mso_site | default("ansible_test") }}' + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + state: present + register: nm_add_anp + +- name: Verify add_anp values + assert: + that: + - cm_add_anp.current.anpRef.anpName == 'ANP' + - nm_add_anp.current.anpRef.anpName == 'ANP' + +- name: Verify add_anp change + assert: + that: + - cm_add_anp is changed + - nm_add_anp is changed + when: version.current.version is version('4.0', '<') # no change in NDO4.0 because site will already be present when template is defined + +- name: Add ANP to site aws + mso_schema_site_anp: + <<: *mso_info + site: 'aws_{{ mso_site | default("ansible_test") }}' + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + anp: ANP_2 + state: present + register: add_anp + +- name: Verify add_anp value + assert: + that: + - add_anp.current.anpRef.anpName == 'ANP_2' + +- name: Verify add_anp change + assert: + that: + - add_anp is changed + when: version.current.version is version('4.0', '<') # no change in NDO4.0 because site will already be present when template is defined + +- name: Add ANPs to site + mso_schema_site_anp: + <<: *mso_info + site: '{{ item.site }}' + schema: '{{ item.schema }}' + template: '{{ item.template }}' + anp: '{{ item.anp }}' + state: present + loop: + - { site: '{{ mso_site | default("ansible_test") }}', schema: '{{ mso_schema | default("ansible_test") }}', template: 'Template 3', anp: 'ANP_3' } + - { site: '{{ mso_site | default("ansible_test") }}', schema: '{{ mso_schema | default("ansible_test") }}', template: 'Template 3', anp: 'ANP_3_1' } + - { site: '{{ mso_site | default("ansible_test") }}', schema: '{{ mso_schema | default("ansible_test") }}', template: 'Template 3', anp: 'ANP_3_2' } + +- name: Add a new site EPG for idempotency check + mso_schema_site_anp_epg: &idempotency_vmm + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: 'Template 3' + anp: 'ANP_3' + site: '{{ mso_site | default("ansible_test") }}' + epg: ansible_test_3 + state: present + +# Test due to inconsistency in attributes REQUEST/RESPONSE API +# MSO Error 400: Bad Request: (0)(0)(0)(0)/deploymentImmediacy error.path.missing +- name: Add new site domain to site EPG for idempotency check + mso_schema_site_anp_epg_domain: + <<: *idempotency_vmm + domain_association_type: vmmDomain + domain_profile: 'VMware-VMM' + deployment_immediacy: lazy + resolution_immediacy: pre-provision + state: present + +- name: Add ANPs to site again + mso_schema_site_anp: + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + schema: '{{ mso_schema | default("ansible_test") }}' + template: 'Template 3' + anp: 'ANP_3' + state: present + register: add_anp_again + +- name: Verify add_anp_again + assert: + that: + - add_anp_again is not changed + - add_anp_again.current.anpRef.anpName == 'ANP_3' + +# QUERY ANPs +- name: Query specific ANP (normal mode) + mso_schema_site_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 3 + anp: ANP_3 + state: query + register: query_anp + +- name: Verify query_anp + assert: + that: + - query_anp is not changed + +- name: Query all ANPs (normal mode) + mso_schema_site_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 3 + state: query + register: query_all + +- name: Verify query_all + assert: + that: + - query_all is not changed + - query_all | length >= 3 + +# DELETE the ANP +- name: Delete ANP3 (normal mode) + mso_schema_site_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 3 + anp: ANP_3 + state: absent + register: delete_anp + +- name: Verify delete_anp + assert: + that: + - delete_anp is changed + - delete_anp.current == {} + +- name: Delete ANP1 again + mso_schema_site_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 3 + anp: ANP_3 + state: absent + register: delete_anp_again + +- name: Verify delete_anp_again + assert: + that: + - delete_anp_again is not changed + - delete_anp_again.current == {} + +# QUERY NON-EXISTING ANP +- name: Query non-existing ANP (normal mode) + mso_schema_site_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 3 + anp: non_existing_anp + state: query + ignore_errors: yes + register: nm_query_non_anp + +- name: Verify query_non_anp + assert: + that: + - nm_query_non_anp is not changed + - nm_query_non_anp.msg == "ANP 'non_existing_anp' not found" + +# USE A NON-EXISTING STATE +- name: Non-existing state (normal_mode) + mso_schema_site_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + state: non-existing-state + ignore_errors: yes + register: nm_non_existing_state + +- name: Verify non_existing_state + assert: + that: + - nm_non_existing_state is not changed + - nm_non_existing_state.msg == "value of state must be one of{{':'}} absent, present, query, got{{':'}} non-existing-state" + +# USE A NON-EXISTING SCHEMA +- name: Non-existing schema (normal_mode) + mso_schema_site_anp: + <<: *mso_info + schema: non-existing-schema + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + state: query + ignore_errors: yes + register: nm_non_existing_schema + +- name: Verify non_existing_schema + assert: + that: + - nm_non_existing_schema is not changed + - nm_non_existing_schema.msg == "Provided schema 'non-existing-schema' does not exist." + +# USE A NON-EXISTING SITE +- name: Non-existing site (normal_mode) + mso_schema_site_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: non-existing-site + template: Template 1 + anp: ANP + state: query + ignore_errors: yes + register: nm_non_existing_site + +- name: Verify non_existing_site + assert: + that: + - nm_non_existing_site is not changed + - nm_non_existing_site.msg == "Site 'non-existing-site' is not a valid site name." + +# USE A TEMPLATE WITHOUT ANY SITE +- name: Add ANP to Template without any site associated (normal mode) + mso_schema_site_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + site: 'azure_{{ mso_site | default("ansible_test") }}' + template: Template 4 + anp: ANP_4 + state: present + ignore_errors: yes + register: nm_no_site_associated + +- name: Verify cm_no_site_associated and nm_no_site_associated + assert: + that: + - nm_no_site_associated is not changed + - nm_no_site_associated.msg == "No site associated with template 'Template4'. Associate the site with the template using mso_schema_site." + +# USE A NON-EXISTING SITE-TEMPLATE +- name: Non-existing site-template (normal_mode) + mso_schema_site_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 2 + anp: ANP_2 + state: query + ignore_errors: yes + register: nm_non_existing_site_template + +- name: Verify non_existing_site_template + assert: + that: + - nm_non_existing_site_template is not changed + - nm_non_existing_site_template.msg is match("Provided site/siteId/template 'ansible_test/[0-9a-zA-Z]*/Template2' does not exist. Existing siteIds/templates{{':'}} [0-9a-zA-Z]*/Template1, [0-9a-zA-Z]*/Template2, [0-9a-zA-Z]*/Template3")
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_anp_epg/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_anp_epg/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_anp_epg/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/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_anp_epg/tasks/main.yml new file mode 100644 index 00000000..ae7885d9 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_anp_epg/tasks/main.yml @@ -0,0 +1,705 @@ +# Test code for the MSO modules +# Copyright: (c) 2021, Anvitha Jain (@anvitha-jain) <anvjain@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") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Remove schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Ensure site exists + mso_site: + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + apic_username: '{{ apic_username }}' + apic_password: '{{ apic_password }}' + apic_site_id: '{{ apic_site_id | default(101) }}' + urls: + - https://{{ apic_hostname }} + state: present + ignore_errors: yes + +- name: Ensure tenant ansible_test exists + mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + state: present + +- name: Ensure sites removed from tenant ansible_test + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: '{{ item }}' + state: absent + loop: + - '{{ mso_site | default("ansible_test") }}' + - 'aws_{{ mso_site | default("ansible_test") }}' + - 'azure_{{ mso_site | default("ansible_test") }}' + +- name: Associate non-cloud site with ansible_test again in normal mode + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: '{{ mso_site | default("ansible_test") }}' + state: present + +- name: Associate aws site with ansible_test in normal mode + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'aws_{{ mso_site | default("ansible_test") }}' + cloud_account: "000000000000" + aws_trusted: false + aws_access_key: "1" + secret_key: "0" + state: present + register: aaws_nm + +- name: Associate azure site with access_type not present, with ansible_test in normal mode + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'azure_{{ mso_site | default("ansible_test") }}' + cloud_account: uni/tn-ansible_test/act-[100]-vendor-azure + state: present + register: aazure_shared_nm + +- name: Ensure schema 1 with Template 1, and Template 2 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: '{{item.template}}' + state: present + loop: + - { template: Template 1} + - { template: Template 2} + - { template: Template 3} + +- name: Ensure schema 2 with Template 4 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template 4 + state: present + +- name: Add cloud site to a schema + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{item.site}}' + template: '{{item.template}}' + state: present + loop: + - { site: 'azure_{{ mso_site | default("ansible_test") }}', template: 'Template 1' } + - { site: 'aws_{{ mso_site | default("ansible_test") }}', template: 'Template 2' } + when: version.current.version is version('3', '<') or version.current.version is version('3.2', '>=') + +- name: Add physical site to a schema + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: '{{ item.template }}' + state: present + loop: + - { template: 'Template 3' } + - { template: 'Template 1' } + +- name: Ensure VRF1 exists + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: '{{ item.template }}' + vrf: VRF1 + state: present + loop: + - { template: 'Template 1' } + - { template: 'Template 3' } + +- name: Add BD1 + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: '{{ item.template }}' + bd: BD1 + vrf: + name: VRF1 + state: present + loop: + - { template: 'Template 1' } + - { template: 'Template 3' } + +- name: Ensure ANPs exist at template level + mso_schema_template_anp: + <<: *mso_info + schema: '{{item.schema}}' + template: '{{ item.template }}' + anp: '{{ item.anp }}' + state: present + loop: + - { schema: '{{ mso_schema | default("ansible_test") }}', template: 'Template 1', anp: 'ANP' } + - { schema: '{{ mso_schema | default("ansible_test") }}', template: 'Template 2', anp: 'ANP_2' } + - { schema: '{{ mso_schema | default("ansible_test") }}_2', template: 'Template 4', anp: 'ANP_4' } + +- name: Ensure ANP exist at template level + mso_schema_template_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 3 + anp: ANP_3 + state: present + +- name: Ensure EPGs exist at template level + mso_schema_template_anp_epg: + <<: *mso_info + schema: '{{ item.schema }}' + template: '{{ item.template }}' + anp: '{{ item.anp }}' + epg: '{{ item.epg }}' + vrf: + name: VRF1 + schema: ansible_test + template: Template 1 + bd: + name: BD1 + schema: ansible_test + template: Template 1 + state: present + loop: + - { schema: '{{ mso_schema | default("ansible_test") }}', template: 'Template 1', anp: 'ANP', epg: 'ansible_test_1' } + - { schema: '{{ mso_schema | default("ansible_test") }}', template: 'Template 2', anp: 'ANP_2', epg: 'ansible_test_2' } + - { schema: '{{ mso_schema | default("ansible_test") }}_2', template: 'Template 4', anp: 'ANP_4', epg: 'ansible_test_4' } + +- name: Ensure EPGs exist at template level + mso_schema_template_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 3 + anp: ANP_3 + epg: ansible_test_3 + vrf: + name: VRF1 + schema: ansible_test + template: Template 3 + bd: + name: BD1 + schema: ansible_test + template: Template 3 + state: present + +- name: Add ANP to site + mso_schema_site_anp: + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 3 + anp: ANP_3 + state: present + +# ADD ANP EPGs to SITE +- name: Add new EPG to site after adding ANP to site (check_mode) + mso_schema_site_anp_epg: + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 3 + anp: ANP_3 + epg: ansible_test_3 + state: present + check_mode: yes + register: cm_add_epg + +- name: Add new EPG to site after adding ANP to site (normal mode) + mso_schema_site_anp_epg: + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 3 + anp: ANP_3 + epg: ansible_test_3 + state: present + register: nm_add_epg + +- name: Verify add_epg + assert: + that: + - cm_add_epg is changed + - nm_add_epg is changed + - cm_add_epg.current.epgRef.anpName == 'ANP_3' + - nm_add_epg.current.epgRef.anpName == 'ANP_3' + - cm_add_epg.current.epgRef.epgName == 'ansible_test_3' + - nm_add_epg.current.epgRef.epgName == 'ansible_test_3' + when: version.current.version is version('4.0', '<') # no change in NDO4.0 because site will already be present when template is defined + +- name: Add new EPG to site after adding ANP to site again + mso_schema_site_anp_epg: &idempotency_vmm + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 3 + anp: ANP_3 + epg: ansible_test_3 + state: present + register: add_epg_again + +- name: Verify add_epg_again + assert: + that: + - add_epg_again is not changed + - add_epg_again.current.epgRef.anpName == 'ANP_3' + - add_epg_again.current.epgRef.epgName == 'ansible_test_3' + +# Test due to inconsistency in attributes REQUEST/RESPONSE API +# MSO Error 400: Bad Request: (0)(0)(0)(0)/deploymentImmediacy error.path.missing +- name: Add new site domain to site EPG for idempotency check + mso_schema_site_anp_epg_domain: + <<: *idempotency_vmm + domain_association_type: vmmDomain + domain_profile: 'VMware-VMM' + deployment_immediacy: lazy + resolution_immediacy: pre-provision + state: present + +- name: Add new EPG to site after adding ANP to site again + mso_schema_site_anp_epg: + <<: *idempotency_vmm + register: add_epg_again_with_vmm + +- name: Verify add_epg_again with vmm + assert: + that: + - add_epg_again is not changed + - add_epg_again.current.epgRef.anpName == 'ANP_3' + - add_epg_again.current.epgRef.epgName == 'ansible_test_3' + +- name: Add new EPG to site without adding ANPs to site + mso_schema_site_anp_epg: + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + state: present + register: add_epg_no_anp + +- name: Verify add_epg_no_anp + assert: + that: + - add_epg_no_anp is changed + - add_epg_no_anp.current.epgs.0.epgRef.anpName == 'ANP' + - add_epg_no_anp.current.epgs.0.epgRef.epgName == 'ansible_test_1' + when: version.current.version is version('4.0', '<') # no change in NDO4.0 because site will already be present when template is defined + +- name: Add new EPG to site without adding ANPs to site again (ANP already exists from previous run) + mso_schema_site_anp_epg: + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + state: present + register: add_epg_no_anp_again + +- name: Verify add_epg_no_anp_again + assert: + that: + - add_epg_no_anp_again is not changed + - add_epg_no_anp_again.current.epgRef.anpName == 'ANP' + - add_epg_no_anp_again.current.epgRef.epgName == 'ansible_test_1' + +# QUERY EPGs +- name: Query all EPGs with ANP (normal mode) + mso_schema_site_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 3 + anp: ANP_3 + state: query + register: query_all + +- name: Verify query_all + assert: + that: + - query_all is not changed + +- name: Query specific EPG1 (normal mode) + mso_schema_site_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + state: query + register: query_epg + +- name: Verify query_epg + assert: + that: + - query_epg is not changed + +# DELETE the EPG +- name: Delete EPG1 (normal mode) + mso_schema_site_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + state: absent + register: delete_epg + +- name: Verify delete_epg + assert: + that: + - delete_epg is changed + - delete_epg.current == {} + when: version.current.version is version('4.0', '<') # no change in NDO4.0 because site will already be present when template is defined + +- name: Delete EPG1 again + mso_schema_site_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + state: absent + register: delete_epg_again + +- name: Verify delete_epg_again + assert: + that: + - delete_epg_again is not changed + - delete_epg_again.current == {} + +# QUERY NON-EXISTING EPG +- name: Query non-existing EPG in template (normal mode) + mso_schema_site_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 3 + anp: ANP_3 + epg: non_existing_epg + state: query + ignore_errors: yes + register: nm_query_non_epg + +- name: Verify query_non_epg + assert: + that: + - nm_query_non_epg is not changed + - nm_query_non_epg.msg == "Provided EPG 'non_existing_epg' does not exist. Existing EPGs{{':'}} ansible_test_3" + +# QUERY NON-EXISTING EPG +- name: Query non-existing EPG in site level + mso_schema_site_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + state: query + ignore_errors: yes + register: query_non_epg + +- name: Verify query_non_epg + assert: + that: + - query_non_epg is not changed + - query_non_epg.msg == "EPG 'ansible_test_1' not found" + when: version.current.version is version('4.0', '<') # no change in NDO4.0 because site will already be present when template is defined + +- name: Delete anp + mso_schema_site_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 3 + anp: ANP_3 + state: absent + +# QUERY NON-EXISTING ANP +- name: Query non-existing ANP in template(normal mode) + mso_schema_site_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 3 + anp: non_existing_anp + epg: ansible_test_3 + state: query + ignore_errors: yes + register: nm_query_non_anp + +- name: Verify query_non_anp + assert: + that: + - nm_query_non_anp is not changed + - nm_query_non_anp.msg == "Provided anp 'non_existing_anp' does not exist. Existing anps{{':'}} ANP_3" + +# QUERY NON-EXISTING ANP +- name: Query non-existing ANP at site level(normal mode) + mso_schema_site_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 3 + anp: ANP_3 + site: '{{ mso_site | default("ansible_test") }}' + state: query + ignore_errors: yes + register: nm_query_non_anp + +- name: Verify query_non_anp + assert: + that: + - nm_query_non_anp is not changed + - nm_query_non_anp.msg == "Provided anp 'ANP_3' does not exist at site level." + when: version.current.version is version('4.0', '<') # no change in NDO4.0 because site will already be present when template is defined + +# USE A NON-EXISTING STATE +- name: Non-existing state (normal_mode) + mso_schema_site_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + state: non-existing-state + ignore_errors: yes + register: nm_non_existing_state + +- name: Verify non_existing_state + assert: + that: + - nm_non_existing_state is not changed + - nm_non_existing_state.msg == "value of state must be one of{{':'}} absent, present, query, got{{':'}} non-existing-state" + +# # USE A NON-EXISTING TEMPLATE +- name: Non-existing template (normal_mode) + mso_schema_site_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: non-existing-template + anp: ANP + epg: ansible_test_1 + state: query + ignore_errors: yes + register: nm_non_existing_template + +- name: Verify non_existing_template + assert: + that: + - nm_non_existing_template is not changed + - nm_non_existing_template.msg == "Provided template 'non-existing-template' does not exist. Existing templates{{':'}} Template1, Template2, Template3" + +# USE A NON-EXISTING SCHEMA +- name: Non-existing schema (normal_mode) + mso_schema_site_anp_epg: + <<: *mso_info + schema: non-existing-schema + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + state: query + ignore_errors: yes + register: nm_non_existing_schema + +- name: Verify non_existing_schema + assert: + that: + - nm_non_existing_schema is not changed + - nm_non_existing_schema.msg == "Provided schema 'non-existing-schema' does not exist." + +# USE A NON-EXISTING SITE +- name: Non-existing site (normal_mode) + mso_schema_site_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: non-existing-site + template: Template 1 + anp: ANP + epg: ansible_test_1 + state: query + ignore_errors: yes + register: nm_non_existing_site + +- name: Verify non_existing_site + assert: + that: + - nm_non_existing_site is not changed + - nm_non_existing_site.msg == "Site 'non-existing-site' is not a valid site name." + +# USE A NON-EXISTING SITE-TEMPLATE +- name: Non-existing site-template (normal_mode) + mso_schema_site_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 2 + anp: ANP_2 + epg: ansible_test_2 + state: query + ignore_errors: yes + register: nm_non_existing_site_template + +- name: Verify non_existing_site_template + assert: + that: + - nm_non_existing_site_template is not changed + - nm_non_existing_site_template.msg is match("Provided site/siteId/template 'ansible_test/[0-9a-zA-Z]*/Template2' does not exist. Existing siteIds/templates{{':'}} [0-9a-zA-Z]*/Template1, [0-9a-zA-Z]*/Template2, [0-9a-zA-Z]*/Template3, [0-9a-zA-Z]*/Template1") + when: version.current.version is version('3', '<') or version.current.version is version('3.2', '>=') + +- name: Verify non_existing_site_template + assert: + that: + - nm_non_existing_site_template is not changed + - nm_non_existing_site_template.msg is match("Provided site/siteId/template 'ansible_test/[0-9a-zA-Z]*/Template2' does not exist. Existing siteIds/templates{{':'}} [0-9a-zA-Z]*/Template3, [0-9a-zA-Z]*/Template1") + when: version.current.version is version('3', '>=') and version.current.version is version('3.2', '<') + +# USE A TEMPLATE WITHOUT ANY SITE +- name: Add EPG to Template without any site associated (normal mode) + mso_schema_site_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + site: 'azure_{{ mso_site | default("ansible_test") }}' + template: Template 4 + anp: ANP_4 + epg: ansible_test_1 + state: present + ignore_errors: yes + register: nm_no_site_associated + +- name: Verify cm_no_site_associated and nm_no_site_associated + assert: + that: + - nm_no_site_associated is not changed + - nm_no_site_associated.msg == "No site associated with template 'Template4'. Associate the site with the template using mso_schema_site." + +# ADDING PRIVATE LINK LABEL +# Add private link label when MSO version >= 3.3 +- name: Execute tasks only for MSO version >= 3.3 + when: version.current.version is version('3.3', '>=') + block: + - name: Remove physical site from schema + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: 'Template 1' + state: absent + + - name: Ensure region for VRF1 at site level exists + mso_schema_site_vrf_region_cidr: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'azure_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + cidr: 10.0.0.0/16 + state: present + + - name: Ensure Private Link Label in Azure VRF subnet exist (MSO >3.3) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'azure_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + cidr: 10.0.0.0/16 + subnet: 10.0.0.0/24 + private_link_label: 'New_Private_Link_Label' + zone: null + + - name: Ensure another Private Link Label in Azure VRF subnet exist (MSO >3.3) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'azure_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + cidr: 10.0.0.0/16 + subnet: 10.0.1.0/26 + private_link_label: 'PLL' + + - name: Add new EPG service type parameters (for version greater than 3.3) + mso_schema_template_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + vrf: + name: VRF1 + schema: ansible_test + template: Template 1 + epg_type: 'service' + deployment_type: 'cloud_native' + service_type: 'Azure-Storage' + access_type: 'private' + state: present + + - name: Add private link label to the EPG (for version greater than 3.3) + mso_schema_site_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + site: 'azure_{{ mso_site | default("ansible_test") }}' + private_link_label: 'New_Private_Link_Label' + state: present + + - name: Change private link label in the EPG (for version greater than 3.3) + mso_schema_site_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + site: 'azure_{{ mso_site | default("ansible_test") }}' + private_link_label: 'PLL' + state: present
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_anp_epg_domain/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_anp_epg_domain/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_anp_epg_domain/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_domain/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_anp_epg_domain/tasks/main.yml new file mode 100644 index 00000000..2b8f0023 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_anp_epg_domain/tasks/main.yml @@ -0,0 +1,1000 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Lionel Hercot (@lhercot) <lhercot@cisco.com> +# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> (based on mso_site test case) +# Copyright: (c) 2020, Shreyas Srish (@shrsr) <ssrish@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") }}' + +- name: Remove Schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Ensure site exists + mso_site: + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + apic_username: '{{ apic_username }}' + apic_password: '{{ apic_password }}' + apic_site_id: '{{ apic_site_id | default(101) }}' + urls: + - https://{{ apic_hostname }} + state: present + +- name: Ensure sites removed from tenant ansible_test + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: '{{ item }}' + state: absent + loop: + - '{{ mso_site | default("ansible_test") }}' + - 'aws_{{ mso_site | default("ansible_test") }}' + - 'azure_{{ mso_site | default("ansible_test") }}' + +- name: Ensure tenant ansible_test exist + mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + sites: + - '{{ mso_site | default("ansible_test") }}' + state: present + +- name: Ensure schema 1 with Template 1 and 2 exists + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: '{{ item }}' + state: present + loop: + - Template 1 + - Template 2 + +- name: Ensure schema 2 with Template 3 exists + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template 3 + state: present + +- name: Add a new site to a schema + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + state: present + +- name: Ensure VRF1 exists + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF1 + state: present + +- name: Add BD1 + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + bd: BD1 + vrf: + name: VRF1 + state: present + +- name: Ensure Template 1 with AP1 exists + mso_schema_template_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: AP1 + state: present + +- name: Ensure Template 1 and AP1 with EPG1 exists + mso_schema_template_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: AP1 + epg: EPG1 + bd: + name: BD1 + vrf: + name: VRF1 + state: present + +- name: Ensure Template 1 and AP1 with EPG3 exists + mso_schema_template_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: AP1 + epg: EPG3 + bd: + name: BD1 + vrf: + name: VRF1 + state: present + +- name: Ensure Template 1 with AP2 exists + mso_schema_template_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: AP2 + state: present + +- name: Ensure Template 1 and AP2 with EPG2 exists + mso_schema_template_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: AP2 + epg: EPG2 + bd: + name: BD1 + vrf: + name: VRF1 + state: present + +- name: Ensure Template 1 and AP2 with EPG4 exists + mso_schema_template_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: AP2 + epg: EPG4 + bd: + name: BD1 + vrf: + name: VRF1 + state: present + +# ADD DOMAINS +- name: Add domain 1 to site EPG1 with AP1 (check mode) + mso_schema_site_anp_epg_domain: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP1 + epg: EPG1 + domain_association_type: vmmDomain + domain_profile: VMware-VMM + deployment_immediacy: lazy + resolution_immediacy: pre-provision + state: present + check_mode: yes + register: cm_add_dom1e1 + +- name: Verify cm_add_dom1e1 + assert: + that: + - cm_add_dom1e1 is changed + - cm_add_dom1e1.previous == {} + - cm_add_dom1e1.current.deploymentImmediacy == 'lazy' + - cm_add_dom1e1.current.domainType == 'vmmDomain' + - cm_add_dom1e1.current.dn == 'uni/vmmp-VMware/dom-VMware-VMM' + - cm_add_dom1e1.current.resolutionImmediacy == 'pre-provision' + +- name: Add domain 1 to site EPG1 with AP1 (normal mode) + mso_schema_site_anp_epg_domain: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP1 + epg: EPG1 + domain_association_type: vmmDomain + domain_profile: 'VMware-VMM' + deployment_immediacy: lazy + resolution_immediacy: pre-provision + state: present + register: nm_add_dom1e1 + +- name: Verify nm_add_dom1e1 + assert: + that: + - nm_add_dom1e1 is changed + - nm_add_dom1e1.previous == {} + - nm_add_dom1e1.current.deploymentImmediacy == 'lazy' + - nm_add_dom1e1.current.domainType == 'vmmDomain' + - nm_add_dom1e1.current.dn == 'uni/vmmp-VMware/dom-VMware-VMM' + - nm_add_dom1e1.current.resolutionImmediacy == 'pre-provision' + +- name: Add domain 2 to site EPG1 with AP1 (normal mode) + mso_schema_site_anp_epg_domain: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP1 + epg: EPG1 + domain_association_type: physicalDomain + domain_profile: phys + deployment_immediacy: lazy + resolution_immediacy: pre-provision + state: present + register: nm_add_dom2e1 + +- name: Verify nm_add_dom2e1 + assert: + that: + - nm_add_dom2e1 is changed + - nm_add_dom2e1.previous == {} + - nm_add_dom2e1.current.deploymentImmediacy == 'lazy' + - nm_add_dom2e1.current.domainType == 'physicalDomain' + - nm_add_dom2e1.current.dn == 'uni/phys-phys' + - nm_add_dom2e1.current.resolutionImmediacy == 'pre-provision' + +- name: Add domain 3 to site EPG1 with AP1 (normal mode) + mso_schema_site_anp_epg_domain: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP1 + epg: EPG1 + domain_association_type: physicalDomain + domain_profile: phys + deployment_immediacy: lazy + resolution_immediacy: lazy + state: present + register: nm_add_dom3e1 + +- name: Verify nm_add_dom3e1 + assert: + that: + - nm_add_dom3e1 is changed + - nm_add_dom3e1.previous != {} + - nm_add_dom3e1.current.deploymentImmediacy == 'lazy' + - nm_add_dom3e1.current.domainType == 'physicalDomain' + - nm_add_dom3e1.current.dn == 'uni/phys-phys' + - nm_add_dom3e1.current.resolutionImmediacy == 'lazy' + +- name: Add domain1 to site EPG3 with AP1 (normal mode) + mso_schema_site_anp_epg_domain: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP1 + epg: EPG3 + domain_association_type: vmmDomain + domain_profile: 'VMware-VMM' + deployment_immediacy: lazy + resolution_immediacy: lazy + state: present + register: nm_add_dom1e3 + +- name: Verify nm_add_dom1e2 + assert: + that: + - nm_add_dom1e3 is changed + - nm_add_dom1e3.previous == {} + - nm_add_dom1e3.current.deploymentImmediacy == 'lazy' + - nm_add_dom1e3.current.domainType == 'vmmDomain' + - nm_add_dom1e3.current.dn == 'uni/vmmp-VMware/dom-VMware-VMM' + - nm_add_dom1e3.current.resolutionImmediacy == 'lazy' + +- name: Add domain 2 to EPG2 (check mode) + mso_schema_site_anp_epg_domain: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP2 + epg: EPG2 + domain_association_type: physicalDomain + domain_profile: phys + deployment_immediacy: lazy + resolution_immediacy: pre-provision + state: present + check_mode: yes + register: cm_add_dom2e2 + +- name: Verify cm_add_dom2e2 + assert: + that: + - cm_add_dom2e2 is changed + - cm_add_dom2e2.previous == {} + - cm_add_dom2e2.current.deploymentImmediacy == 'lazy' + - cm_add_dom2e2.current.domainType == 'physicalDomain' + - cm_add_dom2e2.current.dn == 'uni/phys-phys' + - cm_add_dom2e2.current.resolutionImmediacy == 'pre-provision' + +# QUERY DOMAINS +- name: Query domains of site EPG1 with AP1 (normal mode) + mso_schema_site_anp_epg_domain: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP1 + epg: EPG1 + state: query + register: nm_query_domse1 + +- name: Verify nm_query_domse1 + assert: + that: + - nm_query_domse1 is not changed + +# QUERY A DOMAIN +- name: Query domain3 of site EPG1 with AP1 (normal mode) + mso_schema_site_anp_epg_domain: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP1 + epg: EPG1 + domain_association_type: physicalDomain + domain_profile: phys + deployment_immediacy: lazy + resolution_immediacy: pre-provision + state: query + register: nm_query_dom3e1 + +- name: Verify nm_query_dom3e1 + assert: + that: + - nm_query_dom3e1 is not changed + +# QUERY REMOVED DOMAIN +- name: Add domain 2 to site EPG2 (normal mode) + mso_schema_site_anp_epg_domain: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP2 + epg: EPG2 + domain_association_type: physicalDomain + domain_profile: phys + deployment_immediacy: lazy + resolution_immediacy: pre-provision + state: present + register: nm_add_dom2e2 + +- name: Verify nm_add_dom2e2 + assert: + that: + - nm_add_dom2e2 is changed + - nm_add_dom2e2.previous == {} + - nm_add_dom2e2.current.deploymentImmediacy == 'lazy' + - nm_add_dom2e2.current.domainType == 'physicalDomain' + - nm_add_dom2e2.current.dn == 'uni/phys-phys' + - nm_add_dom2e2.current.resolutionImmediacy == 'pre-provision' + +- name: Remove domain2 from EPG2 (normal mode) + mso_schema_site_anp_epg_domain: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP2 + epg: EPG2 + domain_association_type: physicalDomain + domain_profile: phys + deployment_immediacy: lazy + resolution_immediacy: pre-provision + state: absent + register: nm_remove_dom2e2 + +- name: Verify nm_remove_dom2e2 + assert: + that: + - nm_remove_dom2e2 is changed + +- name: Query removed domain2 from EPG2 (normal mode) + mso_schema_site_anp_epg_domain: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP2 + epg: EPG2 + domain_association_type: physicalDomain + domain_profile: phys + deployment_immediacy: lazy + resolution_immediacy: pre-provision + state: query + ignore_errors: yes + register: nm_non_existent_dom2e2 + +- name: Verify non_existing_domain + assert: + that: + - nm_non_existent_dom2e2 is not changed + - nm_non_existent_dom2e2.msg == "Domain association 'physicalDomain/phys' not found" + +- name: Remove domain2 from EPG2 again(normal mode) + mso_schema_site_anp_epg_domain: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP2 + epg: EPG2 + domain_association_type: physicalDomain + domain_profile: phys + deployment_immediacy: lazy + resolution_immediacy: pre-provision + state: absent + ignore_errors: yes + register: nm_remove_again_dom2e2 + +- name: Verify nm_remove_again_dom2e2 + assert: + that: + - nm_remove_again_dom2e2 is not changed + +# ADD EXISTING DOMAIN +- name: Add domain 1 to site EPG1 again (normal mode) + mso_schema_site_anp_epg_domain: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP1 + epg: EPG1 + domain_association_type: vmmDomain + domain_profile: 'VMware-VMM' + deployment_immediacy: lazy + resolution_immediacy: pre-provision + state: present + register: nm_add_dom1e1_2 + +- name: Verify nm_add_dom1e1_2 + assert: + that: + - nm_add_dom1e1_2 is not changed + +# ADD DOMAIN WITH NO STATE +- name: Add domain 1 to site EPG1 again with no state (normal mode) + mso_schema_site_anp_epg_domain: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP1 + epg: EPG1 + domain_association_type: vmmDomain + domain_profile: 'VMware-VMM' + deployment_immediacy: lazy + resolution_immediacy: pre-provision + ignore_errors: yes + register: nm_add_stateless_dom1e1_2 + +- name: Verify nm_add_stateless_dom1e1_2 + assert: + that: + - nm_add_stateless_dom1e1_2 is not changed + +# ADD OTHER DOMAIN OPTIONS +- name: Add domain l3ExtDomain to site EPG1 with AP1 (normal mode) + mso_schema_site_anp_epg_domain: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP1 + epg: EPG1 + domain_association_type: l3ExtDomain + domain_profile: 'ansible_l3domain' + deployment_immediacy: lazy + resolution_immediacy: lazy + state: present + register: nm_add_doml3 + +- name: Verify nm_add_doml3 + assert: + that: + - nm_add_doml3 is changed + - nm_add_doml3.previous == {} + - nm_add_doml3.current.deploymentImmediacy == 'lazy' + - nm_add_doml3.current.domainType == 'l3ExtDomain' + - nm_add_doml3.current.dn =='uni/l3dom-ansible_l3domain' + - nm_add_doml3.current.resolutionImmediacy == 'lazy' + +- name: Add domain l2ExtDomain to site EPG1 with AP1 (normal mode) + mso_schema_site_anp_epg_domain: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP1 + epg: EPG1 + domain_association_type: l2ExtDomain + domain_profile: 'ansible_l2domain' + deployment_immediacy: lazy + resolution_immediacy: lazy + state: present + ignore_errors: yes + register: nm_add_doml2 + +- name: Verify nm_add_doml2 + assert: + that: + - nm_add_doml2 is changed + - nm_add_doml2.previous == {} + - nm_add_doml2.current.deploymentImmediacy == 'lazy' + - nm_add_doml2.current.domainType == 'l2ExtDomain' + - nm_add_doml2.current.dn =='uni/l2dom-ansible_l2domain' + - nm_add_doml2.current.resolutionImmediacy == 'lazy' + +- name: Add domain fibreChannel to site EPG1 with AP1 (normal mode) + mso_schema_site_anp_epg_domain: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP1 + epg: EPG1 + domain_association_type: fibreChannelDomain + domain_profile: 'ansible_fibreChanneldomain' + deployment_immediacy: lazy + resolution_immediacy: lazy + state: present + register: nm_add_domfc + +- name: Verify nm_add_domfc + assert: + that: + - nm_add_domfc is changed + - nm_add_domfc.previous == {} + - nm_add_domfc.current.domainType == 'fibreChannelDomain' + - nm_add_domfc.current.dn =='uni/fc-ansible_fibreChanneldomain' + - nm_add_domfc.current.resolutionImmediacy == 'lazy' + - nm_add_domfc.current.deploymentImmediacy == 'lazy' + +# USE OTHER ATTRIBUTES OF VMM DOMAIN +- name: Add domain vmm to site EPG2 with AP1 (normal mode) + mso_schema_site_anp_epg_domain: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP2 + epg: EPG2 + domain_association_type: vmmDomain + domain_profile: 'VMware-VMM' + deployment_immediacy: lazy + resolution_immediacy: lazy + micro_seg_vlan_type: 'vlan' + micro_seg_vlan: 100 + port_encap_vlan_type: 'vlan' + port_encap_vlan: 100 + vlan_encap_mode: static + allow_micro_segmentation: yes + switch_type: 'default' + switching_mode: native + enhanced_lagpolicy_name: 'ansible_check' + enhanced_lagpolicy_dn: 'ansible_check' + state: present + ignore_errors: yes + register: nm_add_domvmprop + +- name: Verify nm_add_domvmprop + assert: + that: + - nm_add_domvmprop is changed + - nm_add_domvmprop.previous == {} + +- name: Add domain vmm to site EPG4 with AP2 (normal mode) + mso_schema_site_anp_epg_domain: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP2 + epg: EPG4 + domain_association_type: vmmDomain + domain_profile: 'VMware-VMM' + deployment_immediacy: lazy + resolution_immediacy: lazy + micro_seg_vlan: 100 + port_encap_vlan_type: 'vlan' + port_encap_vlan: 100 + vlan_encap_mode: static + allow_micro_segmentation: yes + switch_type: 'default' + switching_mode: native + enhanced_lagpolicy_name: 'ansible_check' + enhanced_lagpolicy_dn: 'ansible_check' + state: present + ignore_errors: yes + register: nm_add_domvmprop1 + +- name: Verify nm_add_domvmprop1 + assert: + that: + - nm_add_domvmprop1 is not changed + - nm_add_domvmprop1.previous == {} + - nm_add_domvmprop1.msg == "micro_seg_vlan_type is required when micro_seg_vlan is provided." + +- name: Add domain vmm to site EPG4 with AP2 (normal mode) + mso_schema_site_anp_epg_domain: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP2 + epg: EPG4 + domain_association_type: vmmDomain + domain_profile: 'VMware-VMM' + deployment_immediacy: lazy + resolution_immediacy: lazy + micro_seg_vlan_type: 'vlan' + port_encap_vlan_type: 'vlan' + port_encap_vlan: 100 + vlan_encap_mode: static + allow_micro_segmentation: yes + switch_type: 'default' + switching_mode: native + enhanced_lagpolicy_name: 'ansible_check' + enhanced_lagpolicy_dn: 'ansible_check' + state: present + ignore_errors: yes + register: nm_add_domvmprop2 + +- name: Verify nm_add_domvmprop2 + assert: + that: + - nm_add_domvmprop2 is not changed + - nm_add_domvmprop2.msg == "micro_seg_vlan is required when micro_seg_vlan_type is provided." + +- name: Add domain vmm to site EPG4 with AP2 (normal mode) + mso_schema_site_anp_epg_domain: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP2 + epg: EPG4 + domain_association_type: vmmDomain + domain_profile: 'VMware-VMM' + deployment_immediacy: lazy + resolution_immediacy: lazy + micro_seg_vlan_type: 'vlan' + micro_seg_vlan: 100 + port_encap_vlan: 100 + vlan_encap_mode: static + allow_micro_segmentation: yes + switch_type: 'default' + switching_mode: native + enhanced_lagpolicy_name: 'ansible_check' + enhanced_lagpolicy_dn: '' + state: present + ignore_errors: yes + register: nm_add_domvmprop3 + +- name: Verify nm_add_domvmprop3 + assert: + that: + - nm_add_domvmprop3 is not changed + - nm_add_domvmprop3.msg == "port_encap_vlan_type is required when port_encap_vlan is provided." + +- name: Add domain vmm to site EPG4 with AP2 (normal mode) + mso_schema_site_anp_epg_domain: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP2 + epg: EPG4 + domain_association_type: vmmDomain + domain_profile: 'VMware-VMM' + deployment_immediacy: lazy + resolution_immediacy: lazy + micro_seg_vlan_type: 'vlan' + micro_seg_vlan: 100 + port_encap_vlan_type: 'vlan' + vlan_encap_mode: static + allow_micro_segmentation: yes + switch_type: 'default' + switching_mode: native + enhanced_lagpolicy_name: 'ansible_check' + enhanced_lagpolicy_dn: 'ansible_check' + state: present + ignore_errors: yes + register: nm_add_domvmprop4 + +- name: Verify nm_add_domvmprop4 + assert: + that: + - nm_add_domvmprop4 is not changed + - nm_add_domvmprop4.msg == "port_encap_vlan is required when port_encap_vlan_type is provided." + +- name: Add domain vmm to site EPG4 with AP2 (normal mode) + mso_schema_site_anp_epg_domain: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP2 + epg: EPG4 + domain_association_type: vmmDomain + domain_profile: 'VMware-VMM' + deployment_immediacy: lazy + resolution_immediacy: lazy + micro_seg_vlan_type: 'vlan' + micro_seg_vlan: 100 + port_encap_vlan_type: 'vlan' + port_encap_vlan: 100 + vlan_encap_mode: static + allow_micro_segmentation: yes + switch_type: 'default' + switching_mode: native + enhanced_lagpolicy_dn: 'ansible_check' + state: present + ignore_errors: yes + register: nm_add_domvmprop5 + +- name: Verify nm_add_domvmprop5 + assert: + that: + - nm_add_domvmprop5 is not changed + - nm_add_domvmprop5.msg == "enhanced_lagpolicy_name is required when enhanced_lagpolicy_dn is provided." + +- name: Add domain vmm to site EPG4 with AP2 (normal mode) + mso_schema_site_anp_epg_domain: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP2 + epg: EPG4 + domain_association_type: vmmDomain + domain_profile: 'VMware-VMM' + deployment_immediacy: lazy + resolution_immediacy: lazy + micro_seg_vlan_type: 'vlan' + micro_seg_vlan: 100 + port_encap_vlan_type: 'vlan' + port_encap_vlan: 100 + vlan_encap_mode: static + allow_micro_segmentation: yes + switch_type: 'default' + switching_mode: native + enhanced_lagpolicy_name: 'ansible_check' + state: present + ignore_errors: yes + register: nm_add_domvmprop6 + +- name: Verify nm_add_domvmprop6 + assert: + that: + - nm_add_domvmprop6 is not changed + - nm_add_domvmprop6.msg == "enhanced_lagpolicy_dn is required when enhanced_lagpolicy_name is provided." + +# USE NON-EXISTING EPG and ANP AT TEMPLATE LEVEL +- name: Add domain 1 to non-existent site EPG5 (normal mode) + mso_schema_site_anp_epg_domain: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP5 + epg: EPG5 + domain_association_type: vmmDomain + domain_profile: 'VMware-VMM' + deployment_immediacy: lazy + resolution_immediacy: pre-provision + state: present + ignore_errors: yes + register: nm_add_dom1e5 + +- name: Verify nm_add_dom1e5 + assert: + that: + - nm_add_dom1e5 is not changed + +# USE NON-EXISTING EPG AT TEMPLATE LEVEL +- name: Add domain 1 to non-existent site EPG5 (normal mode) + mso_schema_site_anp_epg_domain: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP1 + epg: EPG6 + domain_association_type: vmmDomain + domain_profile: 'VMware-VMM' + deployment_immediacy: lazy + resolution_immediacy: pre-provision + state: present + ignore_errors: yes + register: nm_add_dom1e6 + +- name: Verify nm_add_dom1e6 + assert: + that: + - nm_add_dom1e6 is not changed + +# USE A NON-EXISTING SCHEMA +- name: Non-existing schema for domain (check_mode) + mso_schema_site_anp_epg_domain: + <<: *mso_info + schema: non_existing_schema + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP1 + epg: EPG1 + domain_association_type: vmmDomain + domain_profile: 'VMware-VMM' + deployment_immediacy: lazy + resolution_immediacy: pre-provision + check_mode: yes + ignore_errors: yes + register: cm_non_existing_schema + +- name: Non-existing schema for domain (normal_mode) + mso_schema_site_anp_epg_domain: + <<: *mso_info + schema: non_existing_schema + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP1 + epg: EPG1 + domain_association_type: vmmDomain + domain_profile: 'VMware-VMM' + deployment_immediacy: lazy + resolution_immediacy: pre-provision + ignore_errors: yes + register: nm_non_existing_schema + +- name: Verify non_existing_schema + assert: + that: + - cm_non_existing_schema is not changed + - nm_non_existing_schema is not changed + - cm_non_existing_schema == nm_non_existing_schema + - cm_non_existing_schema.msg == nm_non_existing_schema.msg == "Provided schema 'non_existing_schema' does not exist." + +# USE A NON-EXISTING TEMPLATE +- name: Non-existing template for domain (check_mode) + mso_schema_site_anp_epg_domain: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: non_existing_template + anp: AP1 + epg: EPG1 + domain_association_type: vmmDomain + domain_profile: 'VMware-VMM' + deployment_immediacy: lazy + resolution_immediacy: pre-provision + check_mode: yes + ignore_errors: yes + register: cm_non_existing_template + +- name: Non-existing template for domain (normal_mode) + mso_schema_site_anp_epg_domain: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: non_existing_template + anp: AP1 + epg: EPG1 + domain_association_type: vmmDomain + domain_profile: 'VMware-VMM' + deployment_immediacy: lazy + resolution_immediacy: pre-provision + ignore_errors: yes + register: nm_non_existing_template + +- name: Verify non_existing_template + assert: + that: + - cm_non_existing_template is not changed + - nm_non_existing_template is not changed + - cm_non_existing_template == nm_non_existing_template + - cm_non_existing_template.msg == nm_non_existing_template.msg == "Provided template 'non_existing_template' does not exist. Existing templates{{':'}} Template1, Template2" + +# USE A NON-EXISTING SITE +- name: Non-existing site for domain (check_mode) + mso_schema_site_anp_epg_domain: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 2 + anp: AP1 + epg: EPG1 + domain_association_type: vmmDomain + domain_profile: 'VMware-VMM' + deployment_immediacy: lazy + resolution_immediacy: pre-provision + check_mode: yes + ignore_errors: yes + register: cm_non_existing_site + +- name: Non-existing site for domain (normal_mode) + mso_schema_site_anp_epg_domain: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 2 + anp: AP1 + epg: EPG1 + domain_association_type: vmmDomain + domain_profile: 'VMware-VMM' + deployment_immediacy: lazy + resolution_immediacy: pre-provision + ignore_errors: yes + register: nm_non_existing_site + +- name: Verify non_existing_site + assert: + that: + - cm_non_existing_site is not changed + - nm_non_existing_site is not changed + - cm_non_existing_site == nm_non_existing_site + - cm_non_existing_site.msg is match("Provided site/siteId/template 'ansible_test/[0-9a-zA-Z]*/Template2' does not exist. Existing siteIds/templates{{':'}} [0-9a-zA-Z]*/Template1") + - nm_non_existing_site.msg is match("Provided site/siteId/template 'ansible_test/[0-9a-zA-Z]*/Template2' does not exist. Existing siteIds/templates{{':'}} [0-9a-zA-Z]*/Template1") + +# USE A TEMPLATE WITHOUT ANY SITE +- name: Add site EPG domain association to Schema 2 Template 3 without any site associated (check mode) + mso_schema_site_anp_epg_domain: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 3 + anp: AP1 + epg: EPG1 + domain_association_type: vmmDomain + domain_profile: 'VMware-VMM' + deployment_immediacy: lazy + resolution_immediacy: pre-provision + ignore_errors: yes + check_mode: yes + register: cm_no_site_associated + +- name: Add site EPG domain association to Template 3 without any site associated (normal mode) + mso_schema_site_anp_epg_domain: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 3 + anp: AP1 + epg: EPG1 + domain_association_type: vmmDomain + domain_profile: 'VMware-VMM' + deployment_immediacy: lazy + resolution_immediacy: pre-provision + ignore_errors: yes + register: nm_no_site_associated + +- name: Verify cm_no_site_associated and nm_no_site_associated + assert: + that: + - cm_no_site_associated is not changed + - nm_no_site_associated is not changed + - cm_no_site_associated.msg == nm_no_site_associated.msg == "No site associated with template 'Template3'. Associate the site with the template using mso_schema_site."
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_anp_epg_selector/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_anp_epg_selector/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_anp_epg_selector/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_selector/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_anp_epg_selector/tasks/main.yml new file mode 100644 index 00000000..ab7eada7 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_anp_epg_selector/tasks/main.yml @@ -0,0 +1,1103 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Cindy Zhao (@cizhao) <cizhao@cisco.com> +# Copyright: (c) 2020, Lionel Hercot (@lhercot) <lhercot@cisco.com> +# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> (based on mso_site test case) + +# 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") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Remove schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Ensure azure site exists + mso_site: + <<: *mso_info + site: 'azure_{{ mso_site | default("ansible_test") }}' + apic_username: '{{ azure_apic_username }}' + apic_password: '{{ azure_apic_password }}' + apic_site_id: '{{ azure_site_id | default(103) }}' + urls: + - https://{{ azure_apic_hostname }} + state: present + +- name: Ensure aws site exists + mso_site: + <<: *mso_info + site: 'aws_{{ mso_site | default("ansible_test") }}' + apic_username: '{{ aws_apic_username }}' + apic_password: '{{ aws_apic_password }}' + apic_site_id: '{{ aws_site_id | default(102) }}' + urls: + - https://{{ aws_apic_hostname }} + state: present + +- name: Ensure sites removed from tenant ansible_test + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: '{{ item }}' + state: absent + loop: + - '{{ mso_site | default("ansible_test") }}' + - 'aws_{{ mso_site | default("ansible_test") }}' + - 'azure_{{ mso_site | default("ansible_test") }}' + +- name: Ensure tenant ansible_test exists + mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + # sites: + # - '{{ mso_site | default("ansible_test") }}' + state: present + +- name: Associate aws site with ansible_test in normal mode + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'aws_{{ mso_site | default("ansible_test") }}' + cloud_account: "000000000000" + aws_trusted: false + aws_access_key: "1" + secret_key: "0" + state: present + register: aaws_nm + +- name: Associate azure site with access_type not present, with ansible_test in normal mode + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'azure_{{ mso_site | default("ansible_test") }}' + cloud_account: uni/tn-ansible_test/act-[100]-vendor-azure + state: present + register: aazure_shared_nm + +- name: Ensure schema 1 with Template 1, and Template 2, Template 3 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: '{{item.template}}' + state: present + loop: + - { template: Template 1} + - { template: Template 2} + - { template: Template 3} + +- name: Ensure schema 2 with Template 3 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template 3 + state: present + +- name: Add aws site to a schema + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: '{{item.template}}' + state: present + loop: + - { template: Template 1} + - { template: Template 2} + when: version.current.version is version('3', '<') + +- name: Add azure site to a schema + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'azure_{{ mso_site | default("ansible_test") }}' + template: '{{item.template}}' + state: present + loop: + - { template: Template 1} + - { template: Template 2} + when: version.current.version is version('3', '<') + +- name: Ensure VRF1 exists + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF1 + state: present + +- name: Ensure ANP exist + mso_schema_template_anp: + <<: *mso_info + schema: '{{ item.schema }}' + template: '{{ item.template }}' + anp: ANP + state: present + loop: + - { schema: '{{ mso_schema | default("ansible_test") }}', template: 'Template 1' } + - { schema: '{{ mso_schema | default("ansible_test") }}', template: 'Template 2' } + +- name: Add a new CIDR in VRF1 at site level + mso_schema_site_vrf_region_cidr: &mso_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: '{{ item }}' + vrf: VRF1 + region: us-west-1 + cidr: 10.0.0.0/16 + primary: true + state: present + loop: + - 'aws_{{ mso_site | default("ansible_test") }}' + - 'azure_{{ mso_site | default("ansible_test") }}' + +# ADD EPGs +- name: Ensure EPGs exist + mso_schema_template_anp_epg: + <<: *mso_info + schema: '{{ item.schema }}' + template: '{{ item.template }}' + anp: ANP + epg: '{{ item.epg }}' + vrf: + name: VRF1 + schema: ansible_test + template: Template 1 + state: present + loop: + - { schema: '{{ mso_schema | default("ansible_test") }}', template: 'Template 1', epg: 'ansible_test_1' } + - { schema: '{{ mso_schema | default("ansible_test") }}', template: 'Template 1', epg: 'ansible_test_2' } + +- name: Add Selector to EPG (normal_mode) + mso_schema_template_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: selector_1 + state: present + register: nm_add_selector_1 + +- name: Verify nm_add_selector_1 + assert: + that: + - nm_add_selector_1 is changed + - nm_add_selector_1.previous == {} + - nm_add_selector_1.current.name == "selector_1" + - nm_add_selector_1.current.expressions == [] + +- name: Add Selector 2 to EPG (normal_mode) + mso_schema_template_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: selector_2 + expressions: + - type: expression_2_template + operator: in + value: test + state: present + register: nm_add_selector_2 + +- name: Verify nm_add_selector_2 + assert: + that: + - nm_add_selector_2 is changed + - nm_add_selector_2.previous == {} + - nm_add_selector_2.current.name == "selector_2" + - nm_add_selector_2.current.expressions[0].key == "Custom:expression_2_template" + - nm_add_selector_2.current.expressions[0].operator == "in" + - nm_add_selector_2.current.expressions[0].value == "test" + +# ADD SELECTORS to site EPG +- name: Add selector site_selector_1 to site EPG ansible_test_1 with ANP (check_mode) + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: site_selector_1 + state: present + check_mode: yes + register: cm_add_site_selector_1 + +- name: Verify cm_add_site_selector_1 + assert: + that: + - cm_add_site_selector_1.current.name == "site_selector_1" + - cm_add_site_selector_1.current.expressions == [] + - cm_add_site_selector_1 is changed + - cm_add_site_selector_1.previous == {} + +- name: Add selector site_selector_1 to site EPG ansible_test_1 with ANP (normal_mode) + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: site_selector_1 + state: present + register: nm_add_site_selector_1 + +- name: Verify nm_add_site_selector_1 + assert: + that: + - nm_add_site_selector_1.current.name == "site_selector_1" + - nm_add_site_selector_1.current.expressions == [] + - nm_add_site_selector_1 is changed + - nm_add_site_selector_1.previous == {} + +# Add selector 1 again +- name: Add selector site_selector_1 to site EPG ansible_test_1 with ANP again (normal_mode) + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: site_selector_1 + state: present + register: nm_add_site_selector_1_again + +- name: Verify nm_add_site_selector_1_again + assert: + that: + - nm_add_site_selector_1_again is not changed + - nm_add_site_selector_1_again.current.name == "site_selector_1" == nm_add_site_selector_1_again.previous.name + - nm_add_site_selector_1_again.current.expressions == [] == nm_add_site_selector_1_again.previous.expressions + +- name: Add Selector 1 to site EPG with space in selector name (normal_mode) + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: selector 1 + state: present + ignore_errors: yes + register: nm_add_selector1_with_space_in_name + +- name: Verify nm_add_selector1_with_space_in_name + assert: + that: + - nm_add_selector1_with_space_in_name is not changed + - nm_add_selector1_with_space_in_name.msg == "There should not be any space in selector name." + +- name: Add Selector 2 to site EPG with space in expression type (normal_mode) + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: selector_2 + expressions: + - type: expression 2 + operator: in + value: test + state: present + ignore_errors: yes + register: nm_add_selector2_with_space_in_expression_type + +- name: Verify nm_add_selector2_with_space_in_expression_type + assert: + that: + - nm_add_selector2_with_space_in_expression_type is not changed + - nm_add_selector2_with_space_in_expression_type.msg == "There should not be any space in 'type' attribute of expression 'expression 2'" + +- name: Add Selector 2 to site EPG (check_mode) + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: site_selector_2 + expressions: + - type: expression_2 + operator: in + value: test + state: present + check_mode: yes + register: cm_add_site_selector_2 + +- name: Verify cm_add_selector_2 + assert: + that: + - cm_add_site_selector_2 is changed + - cm_add_site_selector_2.previous == {} + - cm_add_site_selector_2.current.name == "site_selector_2" + - cm_add_site_selector_2.current.expressions[0].key == "Custom:expression_2" + - cm_add_site_selector_2.current.expressions[0].operator == "in" + - cm_add_site_selector_2.current.expressions[0].value == "test" + +- name: Add Selector_2 to site EPG (normal_mode) + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: site_selector_2 + expressions: + - type: expression_2 + operator: in + value: test + state: present + register: nm_add_site_selector_2 + +- name: Verify nm_add_site_selector_2 + assert: + that: + - nm_add_site_selector_2 is changed + - nm_add_site_selector_2.previous == {} + - nm_add_site_selector_2.current.name == "site_selector_2" + - nm_add_site_selector_2.current.expressions[0].key == "Custom:expression_2" + - nm_add_site_selector_2.current.expressions[0].operator == "in" + - nm_add_site_selector_2.current.expressions[0].value == "test" + +- name: Change Selector 2 - keyExist(normal_mode) + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: site_selector_2 + expressions: + - type: expression_5 + operator: has_key + value: test + state: present + ignore_errors: yes + register: nm_change_site_selector_2_key_exist + +- name: Verify nm_change_site_selector_2_key_exist + assert: + that: + - nm_change_site_selector_2_key_exist is not changed + - nm_change_site_selector_2_key_exist.msg == "Attribute 'value' is not supported for operator 'has_key' in expression 'expression_5'" + +- name: Change Selector 2 - keyNotExist (normal_mode) + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: site_selector_2 + expressions: + - type: expression_6 + operator: does_not_have_key + value: test + state: present + ignore_errors: yes + register: nm_change_site_selector_2_key_not_exist + +- name: Verify nm_change_site_selector_2_key_not_exist + assert: + that: + - nm_change_site_selector_2_key_not_exist is not changed + - nm_change_site_selector_2_key_not_exist.msg == "Attribute 'value' is not supported for operator 'does_not_have_key' in expression 'expression_6'" + +- name: Change Selector 2 - equals (normal_mode) + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: site_selector_2 + expressions: + - type: expression_6 + operator: equals + state: present + ignore_errors: yes + register: nm_change_site_selector_2_equals + +- name: Verify nm_change_site_selector_2_equals + assert: + that: + - nm_change_site_selector_2_equals is not changed + - nm_change_site_selector_2_equals.msg == "Attribute 'value' needed for operator 'equals' in expression 'expression_6'" + +# Remove site ANP +- name: Remove site ANP (normal_mode) + mso_schema_site_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + state: absent + +- name: Query site ANP + mso_schema_site_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + state: query + ignore_errors: yes + register: query_site_ANP + +- name: Verify query_site_ANP + assert: + that: + - query_site_ANP.msg == "ANP 'ANP' not found" + when: version.current.version is version('4.0', '<') # no error msg is returned in NDO4.0 because site will be present when template is defined + +# Query without site ANP +- name: Query site_selectors without site ANP + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + state: query + ignore_errors: yes + register: query_without_site_ANP + +- name: Verify query_without_site_ANP + assert: + that: + - query_without_site_ANP is not changed + - query_without_site_ANP.msg == "Anp 'ANP' does not exist in site level." + when: version.current.version is version('4.0', '<') # no error msg is returned in NDO4.0 because site will be present when template is defined + +# - name: Add selector without ANP exist in site level +- name: Add site selector 3 without site ANP exist (normal_mode) + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: site_selector_3 + expressions: + - type: expression_3 + operator: in + value: test + state: present + register: nm_add_site_selector_3_without_anp + +- name: Verify nm_add_site_selector_3_without_anp + assert: + that: + - nm_add_site_selector_3_without_anp is changed + - nm_add_site_selector_3_without_anp.previous == {} + - nm_add_site_selector_3_without_anp.current.name == "site_selector_3" + - nm_add_site_selector_3_without_anp.current.expressions[0].key == "Custom:expression_3" + - nm_add_site_selector_3_without_anp.current.expressions[0].operator == "in" + - nm_add_site_selector_3_without_anp.current.expressions[0].value == "test" + +# Remove site level EPG +- name: Remove site EPG + mso_schema_site_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + state: absent + +# Query without site level EPG +- name: Query site_selectors without site EPG + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + state: query + ignore_errors: yes + register: query_without_site_EPG + +- name: Verify query_without_site_EPG + assert: + that: + - query_without_site_EPG is not changed + - query_without_site_EPG.msg == "Epg 'ansible_test_1' does not exist in site level." + when: version.current.version is version('4.0', '<') # no error msg is returned in NDO4.0 because site will be present when template is defined + +- name: Add site selector 1 without site EPG exist (normal_mode) + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: site_selector_1 + state: present + register: nm_add_site_selector_1_without_epg + +- name: Verify nm_add_site_selector_1_without_epg + assert: + that: + - nm_add_site_selector_1_without_epg is changed + - nm_add_site_selector_1_without_epg.previous == {} + - nm_add_site_selector_1_without_epg.current.name == "site_selector_1" + - nm_add_site_selector_1_without_epg.current.expressions == [] + +- name: Add site_selector_1 site_selector_2 site_selector_3 again + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: '{{ item.selector }}' + expressions: + - type: '{{ item.type }}' + operator: in + value: test + state: present + loop: + - {selector: 'site_selector_1', type: 'expression_1'} + - {selector: 'site_selector_2', type: 'expression_2'} + - {selector: 'site_selector_3', type: 'expression_3'} + register: nm_add_site_selectors_again + +- name: Verify nm_add_site_selectors_again + assert: + that: + - nm_add_site_selectors_again is changed + +# Query all selectors +- name: Query selectors to site EPG + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + state: query + register: query_all_site_selectors + +- name: Verify query_all_site_selectors + assert: + that: + - query_all_site_selectors is not changed + - query_all_site_selectors.current | length == 3 + - query_all_site_selectors.current[0].name == "site_selector_1" + - query_all_site_selectors.current[0].expressions[0].key == "Custom:expression_1" + - query_all_site_selectors.current[0].expressions[0].operator == "in" + - query_all_site_selectors.current[0].expressions[0].value == "test" + - query_all_site_selectors.current[1].name == "site_selector_2" + - query_all_site_selectors.current[1].expressions[0].key == "Custom:expression_2" + - query_all_site_selectors.current[1].expressions[0].operator == "in" + - query_all_site_selectors.current[1].expressions[0].value == "test" + - query_all_site_selectors.current[2].name == "site_selector_3" + - query_all_site_selectors.current[2].expressions[0].key == "Custom:expression_3" + - query_all_site_selectors.current[2].expressions[0].operator == "in" + - query_all_site_selectors.current[2].expressions[0].value == "test" + +# Query sepecific seletor to site EPG +- name: Query selector to site EPG + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: site_selector_1 + state: query + register: query_site_selector_1 + +- name: Verify query_site_selector_1 + assert: + that: + - query_site_selector_1 is not changed + - query_site_selector_1.current.name == "site_selector_1" + - query_site_selector_1.current.expressions[0].key == "Custom:expression_1" + - query_site_selector_1.current.expressions[0].operator == "in" + - query_site_selector_1.current.expressions[0].value == "test" + +- name: Remove site selector 3 (normal_mode) + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: site_selector_3 + state: absent + register: nm_remove_site_selector_3 + +- name: Verify nm_remove_site_selector_3 + assert: + that: + - nm_remove_site_selector_3 is changed + - nm_remove_site_selector_3.current == {} + +- name: Remove site selector 3 again (normal_mode) + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: site_selector_3 + state: absent + register: nm_remove_site_selector_3_again + +- name: Verify nm_remove_site_selector_3_again + assert: + that: + - nm_remove_site_selector_3_again is not changed + - nm_remove_site_selector_3_again.current == {} + +# QUERY NON-EXISTING Selector to EPG +- name: Query non-existing selector (check_mode) + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: non_existing_selector + state: query + check_mode: yes + ignore_errors: yes + register: cm_query_non_selector + +- name: Query non-existing selector (normal mode) + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: non_existing_selector + state: query + ignore_errors: yes + register: nm_query_non_selector + +- name: Verify cm_query_non_selector and nm_query_non_selector + assert: + that: + - cm_query_non_selector is not changed + - nm_query_non_selector is not changed + - cm_query_non_selector == nm_query_non_selector + - cm_query_non_selector.msg == "Selector 'non_existing_selector' not found" + - nm_query_non_selector.msg == "Selector 'non_existing_selector' not found" + +# QUERY NON-EXISTING EPG +- name: Query non-existing EPG (check_mode) + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: non_existing_epg + selector: site_selector_1 + state: query + check_mode: yes + ignore_errors: yes + register: cm_query_non_epg + +- name: Query non-existing EPG (normal mode) + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: non_existing_epg + selector: site_selector_1 + state: query + ignore_errors: yes + register: nm_query_non_epg + +- name: Verify query_non_epg + assert: + that: + - cm_query_non_epg is not changed + - nm_query_non_epg is not changed + - cm_query_non_epg == nm_query_non_epg + - cm_query_non_epg.msg == nm_query_non_epg.msg == "Provided EPG 'non_existing_epg' does not exist. Existing EPGs{{':'}} ansible_test_1, ansible_test_2" + +# QUERY NON-EXISTING ANP +- name: Query non-existing ANP (check_mode) + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: non_existing_anp + epg: ansible_test_1 + selector: site_selector_1 + state: query + check_mode: yes + ignore_errors: yes + register: cm_query_non_anp + +- name: Query non-existing ANP (normal mode) + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: non_existing_anp + epg: ansible_test_1 + selector: site_selector_1 + state: query + ignore_errors: yes + register: nm_query_non_anp + +- name: Verify query_non_anp + assert: + that: + - cm_query_non_anp is not changed + - nm_query_non_anp is not changed + - cm_query_non_anp == nm_query_non_anp + - cm_query_non_anp.msg == nm_query_non_anp.msg == "Provided anp 'non_existing_anp' does not exist. Existing anps{{':'}} ANP" + +# USE A NON-EXISTING STATE +- name: Non-existing state (check_mode) + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: site_selector_1 + state: non-existing-state + check_mode: yes + ignore_errors: yes + register: cm_non_existing_state + +- name: Non-existing state (normal_mode) + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: site_selector_1 + state: non-existing-state + ignore_errors: yes + register: nm_non_existing_state + +- name: Verify non_existing_state + assert: + that: + - cm_non_existing_state is not changed + - nm_non_existing_state is not changed + - cm_non_existing_state == nm_non_existing_state + - cm_non_existing_state.msg == nm_non_existing_state.msg == "value of state must be one of{{':'}} absent, present, query, got{{':'}} non-existing-state" + +# USE A NON-EXISTING TEMPLATE +- name: Non-existing template (check_mode) + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: non-existing-template + anp: ANP + epg: ansible_test_1 + selector: site_selector_1 + state: query + check_mode: yes + ignore_errors: yes + register: cm_non_existing_template + +- name: Non-existing template (normal_mode) + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: non-existing-template + anp: ANP + epg: ansible_test_1 + selector: site_selector_1 + state: query + ignore_errors: yes + register: nm_non_existing_template + +- name: Verify non_existing_template + assert: + that: + - cm_non_existing_template is not changed + - nm_non_existing_template is not changed + - cm_non_existing_template == nm_non_existing_template + - cm_non_existing_template.msg == nm_non_existing_template.msg == "Provided template 'non-existing-template' does not exist. Existing templates{{':'}} Template1, Template2, Template3" + +# USE A NON-EXISTING SCHEMA +- name: Non-existing schema (check_mode) + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: non-existing-schema + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: site_selector_1 + state: query + check_mode: yes + ignore_errors: yes + register: cm_non_existing_schema + +- name: Non-existing schema (normal_mode) + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: non-existing-schema + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: site_selector_1 + state: query + ignore_errors: yes + register: nm_non_existing_schema + +- name: Verify non_existing_schema + assert: + that: + - cm_non_existing_schema is not changed + - nm_non_existing_schema is not changed + - cm_non_existing_schema == nm_non_existing_schema + - cm_non_existing_schema.msg == nm_non_existing_schema.msg == "Provided schema 'non-existing-schema' does not exist." + +# USE A NON-EXISTING SITE +- name: Non-existing site (check_mode) + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: non-existing-site + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: site_selector_1 + state: query + check_mode: yes + ignore_errors: yes + register: cm_non_existing_site + +- name: Non-existing site (normal_mode) + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: non-existing-site + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: site_selector_1 + state: query + ignore_errors: yes + register: nm_non_existing_site + +- name: Verify non_existing_site + assert: + that: + - cm_non_existing_site is not changed + - nm_non_existing_site is not changed + - cm_non_existing_site == nm_non_existing_site + - cm_non_existing_site.msg == nm_non_existing_site.msg == "Site 'non-existing-site' is not a valid site name." + +# USE A NON-EXISTING SITE-TEMPLATE +- name: Non-existing site-template (check_mode) + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 3 + anp: ANP + epg: ansible_test_1 + selector: site_selector_1 + state: query + check_mode: yes + ignore_errors: yes + register: cm_non_existing_site_template + +- name: Non-existing site-template (normal_mode) + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 3 + anp: ANP + epg: ansible_test_1 + selector: site_selector_1 + state: query + ignore_errors: yes + register: nm_non_existing_site_template + +- name: Verify non_existing_site_template + assert: + that: + - cm_non_existing_site_template is not changed + - nm_non_existing_site_template is not changed + - cm_non_existing_site_template == nm_non_existing_site_template + - cm_non_existing_site_template.msg == nm_non_existing_site_template.msg == "Provided site-template association 'aws_{{ mso_site | default("ansible_test") }}-Template3' does not exist." + +- name: Add Selector_4 to site EPG (normal_mode) + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: site_selector_4 + expressions: + - type: ip_address + operator: has_key + state: present + ignore_errors: yes + register: nm_add_site_selector_4 + +- name: Verify nm_add_site_selector_4 + assert: + that: + - nm_add_site_selector_4 is not changed + - nm_add_site_selector_4.msg == "Operator 'has_key' is not supported when expression type is 'ip_address'" + +- name: Add Selector_4 to site EPG again (normal_mode) + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: site_selector_4 + expressions: + - type: ip_address + operator: in + value: test + state: present + register: nm_add_site_selector_4_again + +- name: Verify nm_add_site_selector_4 + assert: + that: + - nm_add_site_selector_4_again is changed + - nm_add_site_selector_4_again.current.name == "site_selector_4" + +- name: Add azure site_selector_1 to site EPG (normal_mode) + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'azure_{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: site_selector_1 + expressions: + - type: zone + operator: in + value: test + state: present + ignore_errors: yes + register: nm_add_azure_site_selector_1 + +- name: Verify nm_add_azure_site_selector_1 + assert: + that: + - nm_add_azure_site_selector_1 is not changed + - nm_add_azure_site_selector_1.msg == "Type 'zone' is only supported for aws" + +# USE A TEMPLATE WITHOUT ANY SITE +- name: Add site EPG selector to Schema 2 Template 3 without any site associated (check mode) + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + site: 'azure_{{ mso_site | default("ansible_test") }}' + template: Template 3 + anp: ANP + epg: ansible_test_1 + selector: site_selector_1 + expressions: + - type: zone + operator: in + value: test + state: present + ignore_errors: yes + check_mode: yes + register: cm_no_site_associated + +- name: Add site EPG selector to Template 3 without any site associated (normal mode) + mso_schema_site_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + site: 'azure_{{ mso_site | default("ansible_test") }}' + template: Template 3 + anp: ANP + epg: ansible_test_1 + selector: site_selector_1 + expressions: + - type: zone + operator: in + value: test + state: present + ignore_errors: yes + register: nm_no_site_associated + +- name: Verify cm_no_site_associated and nm_no_site_associated + assert: + that: + - cm_no_site_associated is not changed + - nm_no_site_associated is not changed + - cm_no_site_associated.msg == nm_no_site_associated.msg == "No site associated with template 'Template3'. Associate the site with the template using mso_schema_site."
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_anp_epg_staticport/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_anp_epg_staticport/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_anp_epg_staticport/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_staticport/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_anp_epg_staticport/tasks/main.yml new file mode 100644 index 00000000..ba7d6658 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_anp_epg_staticport/tasks/main.yml @@ -0,0 +1,870 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Lionel Hercot (@lhercot) <lhercot@cisco.com> +# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> (based on mso_site test case) +# Copyright: (c) 2020, Shreyas Srish (@shrsr) <ssrish@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") }}' + +- name: Remove Schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Ensure site exists + mso_site: + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + apic_username: '{{ apic_username }}' + apic_password: '{{ apic_password }}' + apic_site_id: '{{ apic_site_id | default(101) }}' + urls: + - https://{{ apic_hostname }} + state: present + +- name: Ensure sites removed from tenant ansible_test + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: '{{ item }}' + state: absent + loop: + - '{{ mso_site | default("ansible_test") }}' + - 'aws_{{ mso_site | default("ansible_test") }}' + - 'azure_{{ mso_site | default("ansible_test") }}' + +- name: Ensure tenant ansible_test exist + mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + sites: + - '{{ mso_site | default("ansible_test") }}' + state: present + +- name: Ensure schema 1 with Template 1 and 2 exists + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: '{{ item }}' + state: present + loop: + - Template 1 + - Template 2 + +- name: Ensure schema 2 with Template 3 exists + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template 3 + state: present + +- name: Add a new site to a schema + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + state: present + +- name: Ensure VRF1 exists + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF1 + state: present + +- name: Add BD1 + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + bd: BD1 + vrf: + name: VRF1 + state: present + +- name: Ensure Template 1 with AP1 exists + mso_schema_template_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: AP1 + state: present + +- name: Ensure Template 1 and AP1 with EPG1 exists + mso_schema_template_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: AP1 + epg: EPG1 + bd: + name: BD1 + vrf: + name: VRF1 + state: present + +- name: Ensure Template 1 and AP1 with EPG3 exists + mso_schema_template_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: AP1 + epg: EPG3 + bd: + name: BD1 + vrf: + name: VRF1 + state: present + +- name: Ensure Template 1 with AP2 exists + mso_schema_template_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: AP2 + state: present + +- name: Ensure Template 1 and AP2 with EPG2 exists + mso_schema_template_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: AP2 + epg: EPG2 + bd: + name: BD1 + vrf: + name: VRF1 + state: present + +- name: Ensure Template 1 and AP2 with EPG4 exists + mso_schema_template_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: AP2 + epg: EPG4 + bd: + name: BD1 + vrf: + name: VRF1 + state: present + +- name: Ensure Template 1 and AP2 with EPG6 exists + mso_schema_template_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: AP2 + epg: EPG6 + bd: + name: BD1 + vrf: + name: VRF1 + state: present + +# ADD STATIC PORTS +- name: Add static port 1 to site EPG1 of AP1 (check mode) + mso_schema_site_anp_epg_staticport: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP1 + epg: EPG1 + pod: pod-1 + leaf: 101 + path: eth1/1 + vlan: 126 + mode: 'native' + type: port + deployment_immediacy: immediate + state: present + check_mode: yes + register: cm_add_stat1e1 + +- name: Verify cm_add_stat1e1 + assert: + that: + - cm_add_stat1e1 is changed + - cm_add_stat1e1.previous == {} + - cm_add_stat1e1.current.deploymentImmediacy == 'immediate' + - cm_add_stat1e1.current.portEncapVlan == 126 + - cm_add_stat1e1.current.path == 'topology/pod-1/paths-101/pathep-[eth1/1]' + - cm_add_stat1e1.current.mode == 'native' + - cm_add_stat1e1.current.type == 'port' + +- name: Add static port 1 to site EPG1 of AP1 (normal mode) + mso_schema_site_anp_epg_staticport: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP1 + epg: EPG1 + pod: pod-1 + leaf: 101 + path: eth1/1 + vlan: 126 + mode: 'native' + deployment_immediacy: immediate + state: present + register: nm_add_stat1e1 + +- name: Verify nm_add_stat1e1 + assert: + that: + - nm_add_stat1e1 is changed + - nm_add_stat1e1.previous == {} + - nm_add_stat1e1.current.deploymentImmediacy == 'immediate' + - nm_add_stat1e1.current.portEncapVlan == 126 + - nm_add_stat1e1.current.path == 'topology/pod-1/paths-101/pathep-[eth1/1]' + - nm_add_stat1e1.current.mode == 'native' + - nm_add_stat1e1.current.type == 'port' + +- name: Add static port 2 to site EPG1 of AP1 (normal mode) + mso_schema_site_anp_epg_staticport: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP1 + epg: EPG1 + pod: pod-2 + leaf: 102 + path: eth1/2 + vlan: 100 + mode: 'regular' + type: port + primary_micro_segment_vlan: 199 + deployment_immediacy: immediate + state: present + register: nm_add_stat2e1 + +- name: Verify nm_add_stat2e1 + assert: + that: + - nm_add_stat2e1 is changed + - nm_add_stat2e1.previous == {} + - nm_add_stat2e1.current.deploymentImmediacy == 'immediate' + - nm_add_stat2e1.current.portEncapVlan == 100 + - nm_add_stat2e1.current.path == 'topology/pod-2/paths-102/pathep-[eth1/2]' + - nm_add_stat2e1.current.mode == 'regular' + - nm_add_stat2e1.current.type == 'port' + + +- name: Add static port 3 (vpc) to site EPG1 of AP1 (normal mode) + mso_schema_site_anp_epg_staticport: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP1 + epg: EPG1 + pod: pod-3 + leaf: 103-104 + path: ansible_polgrp + vlan: 101 + type: vpc + mode: untagged + deployment_immediacy: lazy + state: present + register: nm_add_stat3e1 + +- name: Verify nm_add_stat3e1 + assert: + that: + - nm_add_stat3e1 is changed + - nm_add_stat3e1.previous == {} + - nm_add_stat3e1.current.deploymentImmediacy == 'lazy' + - nm_add_stat3e1.current.portEncapVlan == 101 + - nm_add_stat3e1.current.path == 'topology/pod-3/protpaths-103-104/pathep-[ansible_polgrp]' + - nm_add_stat3e1.current.mode == 'untagged' + - nm_add_stat3e1.current.type == 'vpc' + +- name: Add static port 1 to site EPG3 of AP1 (normal mode) + mso_schema_site_anp_epg_staticport: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP1 + epg: EPG3 + pod: pod-1 + leaf: 101 + path: eth1/1 + vlan: 126 + mode: 'native' + type: port + deployment_immediacy: immediate + state: present + register: nm_add_stat1e3 + +- name: Verify nm_add_stat1e3 + assert: + that: + - nm_add_stat1e3 is changed + - nm_add_stat1e3.previous == {} + - nm_add_stat1e3.current.deploymentImmediacy == 'immediate' + - nm_add_stat1e3.current.portEncapVlan == 126 + - nm_add_stat1e3.current.path == 'topology/pod-1/paths-101/pathep-[eth1/1]' + - nm_add_stat1e3.current.mode == 'native' + - nm_add_stat1e3.current.type == 'port' + +- name: Add static port 2 (dpc) to EPG6 of AP2 (normal mode) + mso_schema_site_anp_epg_staticport: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP2 + epg: EPG6 + pod: pod-2 + leaf: 102 + path: eth1/2 + vlan: 100 + deployment_immediacy: lazy + mode: regular + type: dpc + primary_micro_segment_vlan: 199 + state: present + register: nm_add_stat2e6 + +- name: Verify nm_add_stat2e6 + assert: + that: + - nm_add_stat2e6 is changed + - nm_add_stat2e6.previous == {} + - nm_add_stat2e6.current.deploymentImmediacy == 'lazy' + - nm_add_stat2e6.current.portEncapVlan == 100 + - nm_add_stat2e6.current.microSegVlan == 199 + - nm_add_stat2e6.current.path == 'topology/pod-2/paths-102/pathep-[eth1/2]' + - nm_add_stat2e6.current.mode == 'regular' + - nm_add_stat2e6.current.type == 'dpc' + +# QUERY STATIC PORTS +- name: Query STATIC PORTS of site EPG1 with AP1 (normal mode) + mso_schema_site_anp_epg_staticport: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP1 + epg: EPG1 + state: query + register: nm_query_statse1 + +- name: Verify nm_query_statse1 + assert: + that: + - nm_query_statse1 is not changed + +# QUERY A STATIC PORT +- name: Query static port 3 (vpc) of site EPG1 with AP1 (normal mode) + mso_schema_site_anp_epg_staticport: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP1 + epg: EPG1 + pod: pod-3 + leaf: 103-104 + path: ansible_polgrp + vlan: 101 + mode: untagged + type: vpc + deployment_immediacy: immediate + state: query + register: nm_query_stat3e1 + +- name: Verify nm_query_stat3e1 + assert: + that: + - nm_query_stat3e1 is not changed + +# QUERY REMOVED STATIC PORT +- name: Add static port 2 to site EPG2 (normal mode) + mso_schema_site_anp_epg_staticport: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP2 + epg: EPG2 + pod: pod-2 + leaf: 102 + path: eth1/2 + vlan: 100 + mode: regular + type: port + deployment_immediacy: immediate + state: present + register: nm_add_stat2e2 + +- name: Verify nm_add_stat2e2 + assert: + that: + - nm_add_stat2e2 is changed + - nm_add_stat2e2.previous == {} + - nm_add_stat2e2.current.deploymentImmediacy == 'immediate' + - nm_add_stat2e2.current.portEncapVlan == 100 + - nm_add_stat2e2.current.path == 'topology/pod-2/paths-102/pathep-[eth1/2]' + - nm_add_stat2e2.current.mode == 'regular' + - nm_add_stat2e2.current.type == 'port' + +- name: Remove static port 2 from EPG2 (normal mode) + mso_schema_site_anp_epg_staticport: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP2 + epg: EPG2 + pod: pod-2 + leaf: 102 + path: eth1/2 + vlan: 100 + mode: regular + type: port + deployment_immediacy: immediate + state: absent + register: nm_remove_stat2e2 + +- name: Verify nm_remove_stat2e2 + assert: + that: + - nm_remove_stat2e2 is changed + +- name: Query removed static port 2 from EPG2 (normal mode) + mso_schema_site_anp_epg_staticport: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP2 + epg: EPG2 + pod: pod-2 + leaf: 102 + path: eth1/2 + vlan: 100 + mode: regular + type: port + deployment_immediacy: immediate + state: query + ignore_errors: yes + register: nm_non_existent_dom2e2 + +- name: Verify non_existing_domain + assert: + that: + - nm_non_existent_dom2e2 is not changed + - nm_non_existent_dom2e2.msg == "Static port 'topology/pod-2/paths-102/pathep-[eth1/2]' not found" + +- name: Remove static port 2 from EPG2 again(normal mode) + mso_schema_site_anp_epg_staticport: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP2 + epg: EPG2 + pod: pod-2 + leaf: 101 + path: eth1/2 + vlan: 100 + mode: regular + type: port + deployment_immediacy: immediate + state: absent + ignore_errors: yes + register: nm_remove_again_stat2e2 + +- name: Verify nm_remove_again_stat2e2 + assert: + that: + - nm_remove_again_stat2e2 is not changed + +# ADD EXISTING STATIC PORT +- name: Add static port 1 to site EPG1 again (normal mode) + mso_schema_site_anp_epg_staticport: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP1 + epg: EPG1 + pod: pod-1 + leaf: 101 + path: eth1/1 + vlan: 126 + mode: 'native' + type: port + deployment_immediacy: immediate + state: present + register: nm_add_stat1e1_2 + +- name: Verify nm_add_stat1e1_2 + assert: + that: + - nm_add_stat1e1_2 is not changed + +# ADD STATIC PORT WITH NO STATE +- name: Add static port 1 to site EPG1 again with no state (normal mode) + mso_schema_site_anp_epg_staticport: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP1 + epg: EPG1 + pod: pod-1 + leaf: 101 + path: eth1/1 + vlan: 126 + mode: native + type: port + deployment_immediacy: immediate + ignore_errors: yes + register: nm_add_stateless_stat1e1_2 + +- name: Verify nm_add_stateless_stat1e1_2 + assert: + that: + - nm_add_stateless_stat1e1_2 is not changed + +# ADD STATIC FEX PORT +- name: Add static fex port to site EPG1 with AP1 (normal mode) + mso_schema_site_anp_epg_staticport: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP1 + epg: EPG1 + pod: pod-4 + leaf: 101 + path: eth1/1 + vlan: 126 + fex: 151 + type: port + mode: native + deployment_immediacy: lazy + state: present + register: nm_add_statfex + +- name: Verify nm_add_statfex + assert: + that: + - nm_add_statfex is changed + - nm_add_statfex.previous == {} + - nm_add_statfex.current.deploymentImmediacy == 'lazy' + - nm_add_statfex.current.portEncapVlan == 126 + - nm_add_statfex.current.path == 'topology/pod-4/paths-101/extpaths-151/pathep-[eth1/1]' + - nm_add_statfex.current.mode == 'native' + - nm_add_statfex.current.type == 'port' + +# VERIFY NON EXISTENT DEPLOYMENT IMMEDIACY +- name: Add static port 1 to site EPG4 with AP2 with no deployment immediacy (normal mode) + mso_schema_site_anp_epg_staticport: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP2 + epg: EPG4 + pod: pod-4 + leaf: 101 + path: eth1/1 + vlan: 126 + type: port + mode: native + state: present + register: nm_add_stat_di + +- name: Verify nm_add_stat_di + assert: + that: + - nm_add_stat_di.current.deploymentImmediacy == 'lazy' + +# VERIFY NON EXISTENT MODE +- name: Add static port 1 to site EPG4 with AP2 with no mode (normal mode) + mso_schema_site_anp_epg_staticport: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP2 + epg: EPG4 + pod: pod-4 + leaf: 101 + path: eth1/1 + vlan: 126 + type: port + deployment_immediacy: lazy + state: present + register: nm_add_stat_mode + +- name: Verify nm_add_stat_mode + assert: + that: + - nm_add_stat_mode.current.mode == 'untagged' + +# USE NON-EXISTING EPG and ANP AT TEMPLATE LEVEL +- name: Add static port 1 to non-existent site EPG5 (normal mode) + mso_schema_site_anp_epg_staticport: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP5 + epg: EPG5 + pod: pod-1 + leaf: 101 + path: eth1/1 + vlan: 126 + mode: native + type: port + deployment_immediacy: immediate + state: present + ignore_errors: yes + register: nm_add_stat1e5 + +- name: Verify nm_add_stat1e5 + assert: + that: + - nm_add_stat1e5 is not changed + +# USE NON-EXISTING EPG AT TEMPLATE LEVEL +- name: Add static port 1 to non-existent site EPG5 (normal mode) + mso_schema_site_anp_epg_staticport: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP1 + epg: EPG6 + pod: pod-1 + leaf: 101 + path: eth1/1 + vlan: 126 + mode: native + deployment_immediacy: immediate + state: present + ignore_errors: yes + register: nm_add_stat1e6 + +- name: Verify nm_add_stat1e6 + assert: + that: + - nm_add_stat1e6 is not changed + +# USE A NON-EXISTING SCHEMA +- name: Non-existing schema for static port (check_mode) + mso_schema_site_anp_epg_staticport: + <<: *mso_info + schema: non_existing_schema + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP1 + epg: EPG1 + pod: pod-1 + leaf: 101 + path: eth1/1 + vlan: 126 + mode: native + type: port + deployment_immediacy: immediate + check_mode: yes + ignore_errors: yes + register: cm_non_existing_schema + +- name: Non-existing schema for static port (normal_mode) + mso_schema_site_anp_epg_staticport: + <<: *mso_info + schema: non_existing_schema + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + anp: AP1 + epg: EPG1 + pod: pod-1 + leaf: 101 + path: eth1/1 + vlan: 126 + type: port + mode: native + deployment_immediacy: immediate + ignore_errors: yes + register: nm_non_existing_schema + +- name: Verify non_existing_schema + assert: + that: + - cm_non_existing_schema is not changed + - nm_non_existing_schema is not changed + - cm_non_existing_schema == nm_non_existing_schema + - cm_non_existing_schema.msg == nm_non_existing_schema.msg == "Provided schema 'non_existing_schema' does not exist." + +# USE A NON-EXISTING TEMPLATE +- name: Non-existing template for static port (check_mode) + mso_schema_site_anp_epg_staticport: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: non_existing_template + anp: AP1 + epg: EPG1 + pod: pod-1 + leaf: 101 + path: eth1/1 + vlan: 126 + type: port + mode: native + deployment_immediacy: immediate + check_mode: yes + ignore_errors: yes + register: cm_non_existing_template + +- name: Non-existing template for static port (normal_mode) + mso_schema_site_anp_epg_staticport: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: non_existing_template + anp: AP1 + epg: EPG1 + pod: pod-1 + leaf: 101 + path: eth1/1 + vlan: 126 + type: port + mode: native + deployment_immediacy: immediate + ignore_errors: yes + register: nm_non_existing_template + +- name: Verify non_existing_template + assert: + that: + - cm_non_existing_template is not changed + - nm_non_existing_template is not changed + - cm_non_existing_template == nm_non_existing_template + - cm_non_existing_template.msg == nm_non_existing_template.msg == "Provided template 'non_existing_template' does not exist. Existing templates{{':'}} Template1, Template2" + +# USE A NON-EXISTING SITE +- name: Non-existing site for static port (check_mode) + mso_schema_site_anp_epg_staticport: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 2 + anp: AP1 + epg: EPG1 + pod: pod-1 + leaf: 101 + path: eth1/1 + vlan: 126 + type: port + mode: native + deployment_immediacy: immediate + check_mode: yes + ignore_errors: yes + register: cm_non_existing_site + +- name: Non-existing site for static port (normal_mode) + mso_schema_site_anp_epg_staticport: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 2 + anp: AP1 + epg: EPG1 + pod: pod-1 + leaf: 101 + path: eth1/1 + vlan: 126 + type: port + mode: native + deployment_immediacy: immediate + ignore_errors: yes + register: nm_non_existing_site + +- name: Verify non_existing_site + assert: + that: + - cm_non_existing_site is not changed + - nm_non_existing_site is not changed + - cm_non_existing_site == nm_non_existing_site + - cm_non_existing_site.msg is match("Provided site/siteId/template 'ansible_test/[0-9a-zA-Z]*/Template2' does not exist. Existing siteIds/templates{{':'}} [0-9a-zA-Z]*/Template1") + - nm_non_existing_site.msg is match("Provided site/siteId/template 'ansible_test/[0-9a-zA-Z]*/Template2' does not exist. Existing siteIds/templates{{':'}} [0-9a-zA-Z]*/Template1") + +# USE A TEMPLATE WITHOUT ANY SITE +- name: Add site EPG static port association to Schema 2 Template 3 without any site associated (check mode) + mso_schema_site_anp_epg_staticport: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 3 + anp: AP1 + epg: EPG1 + pod: pod-1 + leaf: 101 + path: eth1/1 + vlan: 126 + type: port + mode: native + deployment_immediacy: immediate + ignore_errors: yes + check_mode: yes + register: cm_no_site_associated + +- name: Add site EPG static port association to Template 3 without any site associated (normal mode) + mso_schema_site_anp_epg_staticport: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 3 + anp: AP1 + epg: EPG1 + pod: pod-1 + leaf: 101 + path: eth1/1 + vlan: 126 + type: port + mode: native + deployment_immediacy: immediate + ignore_errors: yes + register: nm_no_site_associated + +- name: Verify cm_no_site_associated and nm_no_site_associated + assert: + that: + - cm_no_site_associated is not changed + - nm_no_site_associated is not changed + - cm_no_site_associated.msg == nm_no_site_associated.msg == "No site associated with template 'Template3'. Associate the site with the template using mso_schema_site."
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_bd/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_bd/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_bd/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_bd/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_bd/tasks/main.yml new file mode 100644 index 00000000..3e3bbb03 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_bd/tasks/main.yml @@ -0,0 +1,749 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Lionel Hercot (@lhercot) <lhercot@cisco.com> +# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> (based on mso_site test case) +# Copyright: (c) 2020, Shreyas Srish (@shrsr) <ssrish@cisco.com> +# Copyright: (c) 2020, Cindy Zhao (@cizhao) <cizhao@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") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Ensure site exists + mso_site: + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + apic_username: '{{ apic_username }}' + apic_password: '{{ apic_password }}' + apic_site_id: '{{ apic_site_id | default(101) }}' + urls: + - https://{{ apic_hostname }} + state: present + ignore_errors: yes + +- name: Remove schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Ensure sites removed from tenant ansible_test + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: '{{ item }}' + state: absent + loop: + - '{{ mso_site | default("ansible_test") }}' + - 'aws_{{ mso_site | default("ansible_test") }}' + - 'azure_{{ mso_site | default("ansible_test") }}' + +- name: Ensure tenant ansible_test exists + mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + sites: + - '{{ mso_site | default("ansible_test") }}' + state: present + +- name: Ensure schema 1 with Template 1, and Template 2, Template 3 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: '{{item.template}}' + state: present + loop: + - { template: Template 1} + - { template: Template 2} + - { template: Template 3} + +- name: Ensure schema 2 with Template 3 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template 3 + state: present + +- name: Add physical site to a schema + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: '{{item.template}}' + state: present + loop: + - { template: Template 1} + - { template: Template 2} + +- name: Ensure VRF1 exists + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF1 + layer3_multicast: true + state: present + +- name: Ensure ansible_test_1 BD does not exist + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + bd: ansible_test_1 + vrf: + name: VRF1 + state: absent + +- name: Add template BD + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + bd: ansible_test_1 + vrf: + name: VRF1 + state: present + register: nm_add_bd + +- name: Verify nm_add_bd + assert: + that: + - nm_add_bd is changed + - nm_add_bd.previous == {} + - nm_add_bd.current.name == "ansible_test_1" + - nm_add_bd.current.vrfRef.templateName == "Template1" + - nm_add_bd.current.vrfRef.vrfName == "VRF1" + +- name: Add template BD 2 + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + bd: ansible_test_2 + vrf: + name: VRF1 + template: Template 1 + state: present + register: nm_add_bd_2 + +- name: Verify nm_add_bd_2 + assert: + that: + - nm_add_bd_2 is changed + - nm_add_bd_2.previous == {} + - nm_add_bd_2.current.name == "ansible_test_2" + - nm_add_bd_2.current.vrfRef.templateName == "Template1" + - nm_add_bd_2.current.vrfRef.vrfName == "VRF1" + +- name: Add template BD 3 + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + bd: ansible_test_3 + vrf: + name: VRF1 + template: Template 1 + state: present + register: nm_add_bd_3 + +- name: Verify nm_add_bd_3 + assert: + that: + - nm_add_bd_3 is changed + - nm_add_bd_3.previous == {} + - nm_add_bd_3.current.name == "ansible_test_3" + - nm_add_bd_3.current.vrfRef.templateName == "Template1" + - nm_add_bd_3.current.vrfRef.vrfName == "VRF1" + +- name: Add template BD 4 + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + bd: ansible_test_4 + vrf: + name: VRF1 + template: Template 1 + state: present + register: nm_add_bd_4 + +- name: Verify nm_add_bd_4 + assert: + that: + - nm_add_bd_4 is changed + - nm_add_bd_4.previous == {} + - nm_add_bd_4.current.name == "ansible_test_4" + - nm_add_bd_4.current.vrfRef.templateName == "Template1" + - nm_add_bd_4.current.vrfRef.vrfName == "VRF1" + +- name: Add site BD (check_mode) + mso_schema_site_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + bd: ansible_test_1 + state: present + check_mode: yes + register: cm_add_site_bd + +- name: Verify cm_add_site_bd + assert: + that: + - cm_add_site_bd.current.bdRef.bdName == "ansible_test_1" + - cm_add_site_bd.current.bdRef.templateName == "Template1" + - cm_add_site_bd.current.hostBasedRouting == false + +- name: Verify cm_add_site_bd + assert: + that: + - cm_add_site_bd is changed + - cm_add_site_bd.previous == {} + when: version.current.version is version('4.0', '<') # no change in NDO4.0 because site will already be present when template is defined + +- name: Add site BD (normal_mode) + mso_schema_site_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + bd: ansible_test_1 + state: present + register: nm_add_site_bd + +- name: Verify nm_add_site_bd + assert: + that: + - nm_add_site_bd.current.bdRef.bdName == "ansible_test_1" + - nm_add_site_bd.current.bdRef.templateName == "Template1" + - nm_add_site_bd.current.hostBasedRouting == false + - cm_add_site_bd.current.bdRef.schemaId == nm_add_site_bd.current.bdRef.schemaId + +- name: Verify nm_add_site_bd + assert: + that: + - nm_add_site_bd is changed + - nm_add_site_bd.previous == {} + when: version.current.version is version('4.0', '<') # no change in NDO4.0 because site will already be present when template is defined + +- name: Add site BD again (check_mode) + mso_schema_site_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + bd: ansible_test_1 + state: present + check_mode: yes + register: cm_add_site_bd_again + +- name: Add site BD again (normal_mode) + mso_schema_site_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + bd: ansible_test_1 + state: present + register: nm_add_site_bd_again + +- name: Verify cm_add_site_bd_again and nm_add_site_bd_again + assert: + that: + - cm_add_site_bd_again is not changed + - nm_add_site_bd_again is not changed + - cm_add_site_bd_again.previous.bdRef.bdName == nm_add_site_bd_again.previous.bdRef.bdName == cm_add_site_bd_again.current.bdRef.bdName == nm_add_site_bd_again.current.bdRef.bdName == "ansible_test_1" + +- name: Change site BD (check_mode) + mso_schema_site_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + bd: ansible_test_1 + host_route: true + state: present + check_mode: yes + register: cm_change_site_bd + +- name: Change site BD (normal_mode) + mso_schema_site_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + bd: ansible_test_1 + host_route: true + state: present + register: nm_change_site_bd + +- name: Verify cm_change_site_bd and nm_change_site_bd + assert: + that: + - cm_change_site_bd is changed + - nm_change_site_bd is changed + - cm_change_site_bd.previous.bdRef == cm_change_site_bd.current.bdRef + - nm_change_site_bd.previous.bdRef == nm_change_site_bd.current.bdRef + - cm_change_site_bd.previous.hostBasedRouting == false + - cm_change_site_bd.current.hostBasedRouting == true + - nm_change_site_bd.previous.hostBasedRouting == false + - nm_change_site_bd.current.hostBasedRouting == true + +- name: Add site BD with host_route (check_mode) + mso_schema_site_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 2 + bd: ansible_test_2 + host_route: true + state: present + check_mode: yes + register: cm_add_site_bd_with_host_route + +- name: Add site BD with host_route (normal_mode) + mso_schema_site_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 2 + bd: ansible_test_2 + host_route: true + state: present + register: nm_add_site_bd_with_host_route + +- name: Verify cm_add_site_bd_with_host_route and nm_add_site_bd_with_host_route + assert: + that: + - cm_add_site_bd_with_host_route is changed + - nm_add_site_bd_with_host_route is changed + - cm_add_site_bd_with_host_route.current.hostBasedRouting == true + - nm_add_site_bd_with_host_route.current.hostBasedRouting == true + +- name: Verify cm_add_site_bd_with_host_route and nm_add_site_bd_with_host_route + assert: + that: + - cm_add_site_bd_with_host_route.previous == {} + - nm_add_site_bd_with_host_route.previous == {} + when: version.current.version is version('4.0', '<') # already present when template is defined, thus previous exists + +- name: Add site BD 3 (normal_mode) + mso_schema_site_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + bd: ansible_test_3 + host_route: true + state: present + register: nm_add_site_bd_3 + +- name: Verify nm_add_site_bd_3 + assert: + that: + - nm_add_site_bd_3 is changed + - nm_add_site_bd_3.current.hostBasedRouting == true + - nm_add_site_bd_3.current.bdRef.bdName == "ansible_test_3" + - nm_add_site_bd_3.current.bdRef.templateName == "Template1" + +- name: Verify nm_add_site_bd_3 + assert: + that: + - nm_add_site_bd_3.previous == {} + when: version.current.version is version('4.0', '<') # already be present when template is defined, thus previous exists + +- name: Add site BD 4 (normal_mode) + mso_schema_site_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + bd: ansible_test_4 + svi_mac: 00:22:23:F1:21:F9 + state: present + register: nm_add_site_bd_4 + +- name: Verify nm_add_site_bd_4 + assert: + that: + - nm_add_site_bd_4 is changed + - nm_add_site_bd_4.current.mac == "00:22:23:F1:21:F9" + - nm_add_site_bd_4.current.bdRef.bdName == "ansible_test_4" + - nm_add_site_bd_4.current.bdRef.templateName == "Template1" + +- name: Verify nm_add_site_bd_4 + assert: + that: + - nm_add_site_bd_4.previous == {} + when: version.current.version is version('4.0', '<') # already be present when template is defined, thus previous exists + +- name: Query a specific BD (check_mode) + mso_schema_site_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 2 + bd: ansible_test_2 + state: query + check_mode: yes + register: cm_query_bd_2 + +- name: Query a specific BD (normal_mode) + mso_schema_site_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 2 + bd: ansible_test_2 + state: query + register: nm_query_bd_2 + +- name: Verify cm_query_bd_2 and nm_query_bd_2 + assert: + that: + - cm_query_bd_2 is not changed + - nm_query_bd_2 is not changed + - cm_query_bd_2.current.bdRef.bdName == "ansible_test_2" == nm_query_bd_2.current.bdRef.bdName + - cm_query_bd_2.current.bdRef.schemaId == nm_query_bd_2.current.bdRef.schemaId + - cm_query_bd_2.current.bdRef.templateName == nm_query_bd_2.current.bdRef.templateName == "Template2" + - cm_query_bd_2.current.hostBasedRouting == nm_query_bd_2.current.hostBasedRouting == true + +- name: Query all BDs (check_mode) + mso_schema_site_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + state: query + check_mode: yes + register: cm_query_all_bd + +- name: Query all BDs (normal_mode) + mso_schema_site_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + state: query + register: nm_query_all_bd + +- name: Verify cm_query_all_bd and cm_query_all_bd + assert: + that: + - cm_query_all_bd is not changed + - nm_query_all_bd is not changed + - cm_query_all_bd.current[0].bdRef.bdName == nm_query_all_bd.current[0].bdRef.bdName == "ansible_test_1" + - cm_query_all_bd.current[0].bdRef.schemaId == nm_query_all_bd.current[0].bdRef.schemaId + - cm_query_all_bd.current[0].bdRef.templateName == nm_query_all_bd.current[0].bdRef.templateName == "Template1" + - cm_query_all_bd.current[1].bdRef.bdName == nm_query_all_bd.current[1].bdRef.bdName == "ansible_test_3" + - cm_query_all_bd.current[1].bdRef.schemaId == nm_query_all_bd.current[1].bdRef.schemaId + - cm_query_all_bd.current[1].bdRef.templateName == nm_query_all_bd.current[1].bdRef.templateName == "Template1" + +- name: Remove BD 2 (check_mode) + mso_schema_site_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 2 + bd: ansible_test_2 + state: absent + check_mode: yes + register: cm_remove_site_bd_2 + +- name: Remove BD 2 (normal_mode) + mso_schema_site_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 2 + bd: ansible_test_2 + state: absent + register: nm_remove_site_bd_2 + +- name: Verify cm_remove_site_bd_2 and nm_remove_site_bd_2 + assert: + that: + - cm_remove_site_bd_2 is changed + - nm_remove_site_bd_2 is changed + - cm_remove_site_bd_2.previous.bdRef.bdName == nm_remove_site_bd_2.previous.bdRef.bdName == "ansible_test_2" + - cm_remove_site_bd_2.previous.bdRef.schemaId == nm_remove_site_bd_2.previous.bdRef.schemaId + - cm_remove_site_bd_2.previous.bdRef.templateName == nm_remove_site_bd_2.previous.bdRef.templateName == "Template2" + - cm_remove_site_bd_2.current == nm_remove_site_bd_2.current == {} + +- name: Remove BD 2 again(normal_mode) + mso_schema_site_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 2 + bd: ansible_test_2 + state: absent + register: nm_remove_site_bd_2_again + +- name: Verify nm_remove_site_bd_2_again + assert: + that: + - nm_remove_site_bd_2_again is not changed + - nm_remove_site_bd_2_again.previous == nm_remove_site_bd_2_again.current == {} + when: version.current.version is version('4.0', '<') # no change in NDO4.0 because site will already be present when template is defined + +- name: Query site without BD (normal_mode) + mso_schema_site_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 2 + state: query + register: nm_query_without_bd + +- name: Verify nm_query_without_bd + assert: + that: + - nm_query_without_bd is not changed + - nm_query_without_bd.current == [] + when: version.current.version is version('4.0', '<') # no change in NDO4.0 because site will already be present when template is defined + + +# QUERY NON-EXISTING BD +- name: Query non-existing BD (check_mode) + mso_schema_site_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + bd: non_existing_bd + state: query + check_mode: yes + ignore_errors: yes + register: cm_query_non_bd + +- name: Query non-existing BD (normal_mode) + mso_schema_site_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + bd: non_existing_bd + state: query + ignore_errors: yes + register: nm_query_non_bd + +- name: Verify cm_query_non_bd and nm_query_non_bd + assert: + that: + - cm_query_non_bd is not changed + - nm_query_non_bd is not changed + - cm_query_non_bd.msg == nm_query_non_bd.msg == "BD 'non_existing_bd' not found" + +# USE NON-EXISTING STATE +- name: non_existing_state state (check_mode) + mso_schema_site_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + bd: ansible_test_1 + state: non_existing_state + ignore_errors: yes + register: cm_non_existing_state + +- name: non_existing_state state (normal_mode) + mso_schema_site_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + bd: ansible_test_1 + state: non_existing_state + ignore_errors: yes + register: nm_non_existing_state + +- name: Verify cm_non_existing_state and nm_non_existing_state + assert: + that: + - cm_non_existing_state is not changed + - nm_non_existing_state is not changed + - cm_non_existing_state.msg == nm_non_existing_state.msg == "value of state must be one of{{':'}} absent, present, query, got{{':'}} non_existing_state" + +# USE A NON_EXISTING_TEMPLATE +- name: non_existing_template (check_mode) + mso_schema_site_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: non_existing_template + bd: ansible_test_1 + state: query + check_mode: yes + ignore_errors: yes + register: cm_non_existing_template + +- name: non_existing_template (normal_mode) + mso_schema_site_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: non_existing_template + bd: ansible_test_1 + state: query + ignore_errors: yes + register: nm_non_existing_template + +- name: Verify cm_non_existing_template and nm_non_existing_template + assert: + that: + - cm_non_existing_template is not changed + - nm_non_existing_template is not changed + - cm_non_existing_template.msg == nm_non_existing_template.msg == "Provided template 'non_existing_template' does not exist. Existing templates{{':'}} Template1, Template2, Template3" + +# USE A NON_EXISTING_SCHEMA +- name: non_existing_schema (check_mode) + mso_schema_site_bd: + <<: *mso_info + schema: non_existing_schema + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + bd: ansible_test_1 + state: query + check_mode: yes + ignore_errors: yes + register: cm_non_existing_schema + +- name: non_existing_schema (normal_mode) + mso_schema_site_bd: + <<: *mso_info + schema: non_existing_schema + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + bd: ansible_test_1 + state: query + ignore_errors: yes + register: nm_non_existing_schema + +- name: Verify cm_non_existing_schema and nm_non_existing_schema + assert: + that: + - cm_non_existing_schema is not changed + - nm_non_existing_schema is not changed + - cm_non_existing_schema.msg == nm_non_existing_schema.msg == "Provided schema 'non_existing_schema' does not exist." + +# USE A NON_EXISTING_SITE +- name: non_existing_site (check_mode) + mso_schema_site_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: non_existing_site + template: Template 1 + bd: ansible_test_1 + state: query + check_mode: yes + ignore_errors: yes + register: cm_non_existing_site + +- name: non_existing_site (normal_mode) + mso_schema_site_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: non_existing_site + template: Template 1 + bd: ansible_test_1 + state: query + ignore_errors: yes + register: nm_non_existing_site + +- name: Verify cm_non_existing_site and nm_non_existing_site + assert: + that: + - cm_non_existing_site is not changed + - nm_non_existing_site is not changed + - cm_non_existing_site.msg == nm_non_existing_site.msg == "Site 'non_existing_site' is not a valid site name." + +# USE A NON_EXISTING_SITE_TEMPLATE +- name: non_existing_site_template (check_mode) + mso_schema_site_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 3 + bd: ansible_test_1 + state: query + check_mode: yes + ignore_errors: yes + register: cm_non_existing_site_template + +- name: non_existing_site_template (normal_mode) + mso_schema_site_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 3 + bd: ansible_test_1 + state: query + ignore_errors: yes + register: nm_non_existing_site_template + +- name: Verify cm_non_existing_site_template and nm_non_existing_site_template + assert: + that: + - cm_non_existing_site_template is not changed + - nm_non_existing_site_template is not changed + - cm_non_existing_site_template.msg == nm_non_existing_site_template.msg == "Provided site-template association 'ansible_test-Template3' does not exist." + +# USE A TEMPLATE WITHOUT ANY SITE +- name: Add site BD to Schema 2 Template 3 without any site associated (check mode) + mso_schema_site_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 3 + bd: ansible_test_1 + state: present + check_mode: yes + ignore_errors: yes + register: cm_no_site_associated + +- name: Add site BD to Template 3 without any site associated (normal mode) + mso_schema_site_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 3 + bd: ansible_test_1 + state: present + ignore_errors: yes + register: nm_no_site_associated + +- name: Verify cm_no_site_associated and nm_no_site_associated + assert: + that: + - cm_no_site_associated is not changed + - nm_no_site_associated is not changed + - cm_no_site_associated.msg == nm_no_site_associated.msg == "No site associated with template 'Template3'. Associate the site with the template using mso_schema_site."
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_bd_l3out/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_bd_l3out/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_bd_l3out/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_bd_l3out/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_bd_l3out/tasks/main.yml new file mode 100644 index 00000000..df0cd372 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_bd_l3out/tasks/main.yml @@ -0,0 +1,441 @@ +# Test code for the MSO modules +# Copyright: (c) 2021, Anvitha Jain (@anvitha-jain) <anvjain@cisco.com> +# Copyright: (c) 2022, 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: 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") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Remove schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + ignore_errors: yes + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Ensure site exists + mso_site: + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + apic_username: '{{ apic_username }}' + apic_password: '{{ apic_password }}' + apic_site_id: '{{ apic_site_id | default(101) }}' + urls: + - https://{{ apic_hostname }} + state: present + +- name: Ensure sites removed from tenant ansible_test + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: '{{ item }}' + state: absent + loop: + - '{{ mso_site | default("ansible_test") }}' + - 'aws_{{ mso_site | default("ansible_test") }}' + - 'azure_{{ mso_site | default("ansible_test") }}' + +- name: Ensure tenant ansible_test exists + mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + sites: + - '{{ mso_site | default("ansible_test") }}' + state: present + +- name: Ensure schema with Template1 and Template2 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: '{{item.template}}' + state: present + loop: + - { template: Template1} + - { template: Template2} + +- name: Ensure schema 2 with Template3 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template3 + state: present + +- name: Add physical site to a schema + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + state: present + +- name: Add physical site to a schema2 + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + site: '{{ mso_site | default("ansible_test") }}' + template: Template3 + state: present + +- name: Ensure VRF1 exists + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + vrf: VRF1 + state: present + +- name: Ensure VRF2 exists + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template2 + vrf: VRF2 + state: present + +- name: Ensure VRF3 exists + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template3 + vrf: VRF3 + state: present + +- name: Add template BD + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + vrf: + name: VRF1 + state: present + register: nm_add_bd + +- name: Verify nm_add_bd + assert: + that: + - nm_add_bd is changed + - nm_add_bd.previous == {} + - nm_add_bd.current.name == "ansible_test_1" + - nm_add_bd.current.vrfRef.templateName == "Template1" + - nm_add_bd.current.vrfRef.vrfName == "VRF1" + +- name: Add a new L3out + mso_schema_template_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + l3out: L3out1 + vrf: + name: VRF1 + state: present + register: nm_add_l3out + +- name: Add a new L3out2 in different template + mso_schema_template_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template2 + l3out: L3out2 + vrf: + name: VRF2 + state: present + register: nm_add_l3out + +- name: Add a new L3out3 in different schema + mso_schema_template_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template3 + l3out: L3out3 + vrf: + name: VRF3 + state: present + register: nm_add_l3out + +- name: Verify nm_add_l3out + assert: + that: + - nm_add_l3out is changed + - nm_add_l3out.previous == {} + +- name: Add BD to site + mso_schema_site_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + state: present + register: nm_add_site_bd + +- name: Verify nm_add_site_bd + assert: + that: + - nm_add_site_bd.current.bdRef.bdName == "ansible_test_1" + - nm_add_site_bd.current.bdRef.templateName == "Template1" + - nm_add_site_bd.current.hostBasedRouting == false + +- name: Verify nm_add_site_bd + assert: + that: + - nm_add_site_bd is changed + - nm_add_site_bd.previous == {} + when: version.current.version is version('4.0', '<') # no change in NDO4.0 because site will already be present when template is defined + +- name: Add l3out to BD Site + mso_schema_site_bd_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + l3out: + name: L3out1 + state: present + register: nm_bd_site_l3out + +- name: Verify nm_bd_site_l3out + assert: + that: + - nm_bd_site_l3out is changed + - nm_bd_site_l3out.previous == {} + - nm_bd_site_l3out.current.l3outName == "L3out1" + +- name: Query a specific BD site l3out + mso_schema_site_bd_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + l3out: + name: L3out1 + state: query + register: query_result + +- name: Verify query_result + assert: + that: + - query_result is not changed + - nm_bd_site_l3out.current.l3outName == "L3out1" + +- name: Add l3out2 from different template to BD Site + mso_schema_site_bd_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + l3out: + name: L3out2 + template: Template2 + state: present + register: nm_bd_site_l3out2 + +- name: Add l3out3 from different schema to BD Site + mso_schema_site_bd_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + l3out: + name: L3out3 + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template3 + state: present + register: nm_bd_site_l3out3 + +- name: Verify nm_bd_site_l3out2 and nm_bd_site_l3out3 + assert: + that: + - nm_bd_site_l3out2 is changed + - nm_bd_site_l3out2.previous == {} + - nm_bd_site_l3out2.current.l3outName == "L3out2" + - nm_bd_site_l3out3 is changed + - nm_bd_site_l3out3.previous == {} + - nm_bd_site_l3out3.current.l3outName == "L3out3" + +- name: Query all BD site l3outs + mso_schema_site_bd_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + state: query + register: query_all + +- name: Verify query_all + assert: + that: + - query_all is not changed + - query_all.current.0.l3outName == "L3out1" + - query_all.current.1.l3outName == "L3out2" + - query_all.current.2.l3outName == "L3out3" + +# Checking error conditions +- name: Use non_existing template + mso_schema_site_bd_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: non_existing_template + bd: ansible_test_1 + l3out: + name: L3out1 + state: query + ignore_errors: yes + register: non_existing_template + +- name: Use non_existing BD + mso_schema_site_bd_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + bd: BD1 + state: query + ignore_errors: yes + register: non_existing_bd + +- name: Query non_existing BD site L3out + mso_schema_site_bd_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + l3out: + name: non_existing_L3out + state: query + ignore_errors: yes + register: non_existing_l3out + +- name: Verify error query + assert: + that: + - non_existing_template is not changed + - non_existing_template.msg == "Provided template 'non_existing_template' not matching existing template(s){{':'}} Template1, Template2" + - non_existing_bd is not changed + - non_existing_bd.msg == "Provided BD 'BD1' not matching existing bd(s){{':'}} ansible_test_1" + - non_existing_l3out is not changed + - non_existing_l3out.msg == "L3out 'non_existing_L3out' not found" + +# Check addition of l3out to Site BD without adding BD to site +- name: Remove l3out from BD Site + mso_schema_site_bd_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + l3out: + name: L3out1 + state: absent + register: remove_bd_site_l3out + +- name: Verify remove_bd_site_l3out + assert: + that: + - remove_bd_site_l3out is changed + - remove_bd_site_l3out.previous.l3outName == "L3out1" + - remove_bd_site_l3out.current == {} + +- name: Remove BD from site + mso_schema_site_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + state: absent + register: nm_remove_site_bd + +- name: Verify nm_remove_site_bd + assert: + that: + - nm_remove_site_bd is changed + - nm_remove_site_bd.previous.bdRef.bdName == "ansible_test_1" + - nm_remove_site_bd.previous.bdRef.templateName == "Template1" + - nm_remove_site_bd.current == {} + +- name: Remove template BD + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + state: absent + register: nm_remove_bd + +- name: Verify nm_remove_bd + assert: + that: + - nm_remove_bd is changed + - nm_remove_bd.current == {} + +- name: Add new template BD + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_bd + vrf: + name: VRF1 + state: present + register: nm_add_bd_template + +- name: Verify nm_add_bd_template + assert: + that: + - nm_add_bd_template is changed + - nm_add_bd_template.previous == {} + +- name: Add a new l3 out to BD (BD not associated to Site) + mso_schema_site_bd_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + bd: ansible_bd + l3out: + name: L3out1 + state: present + register: add_bd_site_l3out + +- name: Verify add_bd_site_l3out + assert: + that: + - add_bd_site_l3out is changed + - add_bd_site_l3out.previous == {} + - add_bd_site_l3out.current.l3outName == "L3out1" diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_bd_subnet/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_bd_subnet/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_bd_subnet/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_bd_subnet/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_bd_subnet/tasks/main.yml new file mode 100644 index 00000000..3bb2d4d3 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_bd_subnet/tasks/main.yml @@ -0,0 +1,665 @@ +# Test code for the MSO modules +# Copyright: (c) 2022, Akini Ross (@akinross) <akinross@cisco.com> +# Copyright: (c) 2020, Cindy Zhao (@cizhao) <cizhao@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") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Remove schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Ensure site exists + mso_site: + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + apic_username: '{{ apic_username }}' + apic_password: '{{ apic_password }}' + apic_site_id: '{{ apic_site_id | default(101) }}' + urls: + - https://{{ apic_hostname }} + state: present + +- name: Ensure sites removed from tenant ansible_test + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: '{{ item }}' + state: absent + loop: + - '{{ mso_site | default("ansible_test") }}' + - 'aws_{{ mso_site | default("ansible_test") }}' + - 'azure_{{ mso_site | default("ansible_test") }}' + +- name: Ensure tenant ansible_test exists + mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + sites: + - '{{ mso_site | default("ansible_test") }}' + state: present + +- name: Ensure schema 1 with Template1, Template2, Template4 and Template5 + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: '{{ item }}' + state: present + loop: + - Template1 + - Template2 + - Template4 + - Template5 + +- name: Ensure schema 2 with Template3 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template3 + state: present + +- name: Add physical site to templates + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: '{{ item }}' + state: present + loop: + - Template1 + - Template2 + - Template5 + +- name: Ensure VRF1 exists + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + vrf: VRF1 + layer3_multicast: true + state: present + +- name: Add template BD to Template1 for create in site subnet + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_site_bd_from_subnet + layer2_stretch: false + vrf: + name: VRF1 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + state: present + +- name: Add template BD to Template3 + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template3 + bd: ansible_test_3 + vrf: + name: VRF1 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + state: present + register: nm_add_bd_template_3 + +- name: Add template BD to Template2 + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template2 + bd: ansible_test_2 + vrf: + name: VRF1 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + state: present + register: nm_add_bd_template_2 + +- name: Add template BD to Template4 + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template4 + bd: ansible_test_4 + vrf: + name: VRF1 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + state: present + register: nm_add_bd_template_4 + +- name: Add template BD to Template1 without disabling layer2_stretch + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + vrf: + name: VRF1 + state: present + register: nm_add_bd + +- name: Add site BD + mso_schema_site_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + state: present + register: nm_add_site_bd + +- name: Add site BD subnet with layer2_stretch enabled + mso_schema_site_bd_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + subnet: 10.1.0.1/16 + state: present + ignore_errors: yes + register: add_site_bd_subnet_with_l2Stretch_enabled + +- name: Verify add_site_bd_subnet_with_l2Stretch_enabled + assert: + that: + - add_site_bd_subnet_with_l2Stretch_enabled.msg == "The l2Stretch of template bd should be false in order to create a site bd subnet. Set l2Stretch as false using mso_schema_template_bd" + +- name: Disable layer2_stretch in template BD + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + layer2_stretch: false + vrf: + name: VRF1 + state: present + register: nm_add_bd + +- name: Add site BD subnet with layer2_stretch disabled (check_mode) + mso_schema_site_bd_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + subnet: 10.1.0.1/16 + state: present + check_mode: yes + register: cm_add_site_bd_subnet + +- name: Verify cm_add_site_bd_subnet + assert: + that: + - cm_add_site_bd_subnet is changed + - cm_add_site_bd_subnet.previous == {} + - cm_add_site_bd_subnet.current.ip == "10.1.0.1/16" + - cm_add_site_bd_subnet.current.scope == "private" + - cm_add_site_bd_subnet.current.description == "10.1.0.1/16" + - cm_add_site_bd_subnet.current.shared == False + - cm_add_site_bd_subnet.current.noDefaultGateway == False + - cm_add_site_bd_subnet.current.querier == False + +- name: Add site BD subnet with layer2_stretch disabled (normal_mode) + mso_schema_site_bd_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + subnet: 10.1.0.1/16 + state: present + register: nm_add_site_bd_subnet + +- name: Verify nm_add_site_bd_subnet + assert: + that: + - nm_add_site_bd_subnet is changed + - nm_add_site_bd_subnet.previous == {} + - nm_add_site_bd_subnet.current.ip == "10.1.0.1/16" + - nm_add_site_bd_subnet.current.scope == "private" + - nm_add_site_bd_subnet.current.description == "10.1.0.1/16" + - nm_add_site_bd_subnet.current.shared == False + - nm_add_site_bd_subnet.current.noDefaultGateway == False + - nm_add_site_bd_subnet.current.querier == False + +- name: Add site BD subnet again + mso_schema_site_bd_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + subnet: 10.1.0.1/16 + state: present + register: nm_add_site_bd_subnet_again + +- name: Verify nm_add_site_bd_subnet_again + assert: + that: + - nm_add_site_bd_subnet_again is not changed + +- name: Add another site BD subnet + mso_schema_site_bd_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + subnet: 10.10.10.1/16 + description: another subnet + scope: public + shared: true + no_default_gateway: true + querier: true + state: present + register: nm_add_another_site_bd_subnet + +- name: Verify nm_add_another_site_bd_subnet + assert: + that: + - nm_add_another_site_bd_subnet is changed + - nm_add_another_site_bd_subnet.previous == {} + - nm_add_another_site_bd_subnet.current.description == "another subnet" + - nm_add_another_site_bd_subnet.current.scope == "public" + - nm_add_another_site_bd_subnet.current.shared == true + - nm_add_another_site_bd_subnet.current.noDefaultGateway == true + - nm_add_another_site_bd_subnet.current.querier == true + +- name: Add BD ansible_test_5 to Schema1, template5 + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template5 + bd: ansible_test_5 + layer2_stretch: false + vrf: + name: VRF1 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + state: present + +- name: Add site BD5 + mso_schema_site_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template5 + bd: ansible_test_5 + state: present + +- name: Add site BD5 subnet with layer2_stretch disabled (normal_mode) + mso_schema_site_bd_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template5 + bd: ansible_test_5 + subnet: 10.1.0.5/16 + is_virtual_ip: true + scope: public + shared: true + no_default_gateway: true + querier: true + primary: true + state: present + register: nm_add_site_bd_subnet5 + +- name: Verify nm_add_site_bd_subnet5 for a version that's < 3.1 + assert: + that: + - nm_add_site_bd_subnet5 is changed + - nm_add_site_bd_subnet5.previous == {} + - nm_add_site_bd_subnet5.current.ip == "10.1.0.5/16" + - nm_add_site_bd_subnet5.current.scope == "public" + - nm_add_site_bd_subnet5.current.description == "10.1.0.5/16" + - nm_add_site_bd_subnet5.current.shared == True + - nm_add_site_bd_subnet5.current.noDefaultGateway == True + - nm_add_site_bd_subnet5.current.querier == True + when: version.current.version is version('3.1.1g', '<') + +- name: Verify nm_add_site_bd_subnet5 for a version that's >= 3.1 + assert: + that: + - nm_add_site_bd_subnet5 is changed + - nm_add_site_bd_subnet5.previous == {} + - nm_add_site_bd_subnet5.current.ip == "10.1.0.5/16" + - nm_add_site_bd_subnet5.current.scope == "public" + - nm_add_site_bd_subnet5.current.description == "10.1.0.5/16" + - nm_add_site_bd_subnet5.current.shared == True + - nm_add_site_bd_subnet5.current.noDefaultGateway == True + - nm_add_site_bd_subnet5.current.querier == True + - nm_add_site_bd_subnet5.current.virtual == True + when: version.current.version is version('3.1.1g', '>=') + +- name: Verify nm_add_site_bd_subnet5 for a version that's >= 3.1.1h + assert: + that: + - nm_add_site_bd_subnet5.current.primary == True + when: version.current.version is version('3.1.1h', '>=') + +- name: Add site BD subnet with non existing site bd (normal_mode) + mso_schema_site_bd_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + bd: ansible_test_site_bd_from_subnet + subnet: 10.1.0.1/16 + state: present + register: nm_add_site_bd_subnet_and_site_bd + +- name: Verify nm_add_site_bd_subnet_and_site_bd + assert: + that: + - nm_add_site_bd_subnet_and_site_bd is changed + - nm_add_site_bd_subnet_and_site_bd.previous == {} + - nm_add_site_bd_subnet_and_site_bd.current.ip == "10.1.0.1/16" + - nm_add_site_bd_subnet_and_site_bd.current.scope == "private" + - nm_add_site_bd_subnet_and_site_bd.current.description == "10.1.0.1/16" + - nm_add_site_bd_subnet_and_site_bd.current.shared == False + - nm_add_site_bd_subnet_and_site_bd.current.noDefaultGateway == False + - nm_add_site_bd_subnet_and_site_bd.current.querier == False + +- name: Query site bd + mso_schema_site_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + bd: ansible_test_site_bd_from_subnet + state: query + register: query_site_bd + +- name: Verify query_site_bd + assert: + that: + - query_site_bd.current.bdRef.bdName == "ansible_test_site_bd_from_subnet" + +- name: Add site BD subnet with now existing site bd again (normal_mode) + mso_schema_site_bd_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + bd: ansible_test_site_bd_from_subnet + subnet: 10.1.0.1/16 + state: present + register: nm_add_site_bd_subnet_and_site_bd_again + +- name: Verify nm_add_site_bd_subnet_and_site_bd_again + assert: + that: + - nm_add_site_bd_subnet_and_site_bd_again is not changed + +- name: Query all subnets + mso_schema_site_bd_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + state: query + register: query_all + +- name: Verify query_all + assert: + that: + - query_all is not changed + - query_all.current | length == 2 + - query_all.current.0.ip == "10.1.0.1/16" + - query_all.current.1.ip == "10.10.10.1/16" + +- name: Query a specific site BD subnet + mso_schema_site_bd_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + subnet: 10.1.0.1/16 + state: query + register: query_subnet + +- name: Verify query_subnet + assert: + that: + - query_subnet is not changed + - query_subnet.current.ip == "10.1.0.1/16" + +- name: Query a specific site BD5 subnet + mso_schema_site_bd_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template5 + bd: ansible_test_5 + subnet: 10.1.0.5/16 + state: query + register: query_subnet5 + +- name: Verify query_subnet5 for version before 3.1 + assert: + that: + - query_subnet5 is not changed + - query_subnet5.current.ip == "10.1.0.5/16" + when: version.current.version is version('3.1.1g', '<') + +- name: Verify query_subnet5 for 3.1 version and later + assert: + that: + - query_subnet5 is not changed + - query_subnet5.current.ip == "10.1.0.5/16" + - query_subnet5.current.virtual == true + when: version.current.version is version('3.1.1g', '>=') + +- name: Verify query_subnet5 for 3.1.1h version and later + assert: + that: + - query_subnet5.current.primary == true + when: version.current.version is version('3.1.1h', '>=') + +- name: Remove a site BD subnet + mso_schema_site_bd_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + subnet: 10.1.0.1/16 + state: absent + register: rm_subnet + +- name: Verify rm_subnet + assert: + that: + - rm_subnet is changed + - rm_subnet.current == {} + - rm_subnet.previous.ip == "10.1.0.1/16" + +- name: Remove the site BD subnet again + mso_schema_site_bd_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + subnet: 10.1.0.1/16 + state: absent + register: rm_subnet_again + +- name: Verify rm_subnet_again + assert: + that: + - rm_subnet_again is not changed + - rm_subnet_again.previous == rm_subnet_again.current == {} + +- name: Remove a site BD 5 subnet + mso_schema_site_bd_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template5 + bd: ansible_test_5 + subnet: 10.1.0.5/16 + state: absent + register: rm_subnet5 + +- name: Verify rm_subnet5 + assert: + that: + - rm_subnet5 is changed + - rm_subnet5.current == {} + - rm_subnet5.previous.ip == "10.1.0.5/16" + +# Use non_existing_schema +- name: Query subnet by non_existing_schema + mso_schema_site_bd_subnet: + <<: *mso_info + schema: non_existing_schema + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + subnet: 10.1.0.1/16 + state: query + ignore_errors: yes + register: non_existing_schema + +- name: Verify non_existing_schema + assert: + that: + - non_existing_schema.msg == "Provided schema 'non_existing_schema' does not exist." + +# Use non_existing_template +- name: Query subnet by non_existing_template + mso_schema_site_bd_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: non_existing_template + bd: ansible_test_1 + subnet: 10.1.0.1/16 + state: query + ignore_errors: yes + register: non_existing_template + +- name: Verify non_existing_template + assert: + that: + - non_existing_template.msg == "Provided template 'non_existing_template' not matching existing template(s){{':'}} Template1, Template2, Template4, Template5" + +# Use non_existing_template_bd +- name: Query subnet by non_existing_template_bd + mso_schema_site_bd_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + bd: non_existing_template_bd + subnet: 10.1.0.1/16 + state: query + ignore_errors: yes + register: non_existing_template_bd + +- name: Verify non_existing_template_bd + assert: + that: + - non_existing_template_bd.msg == "Provided BD 'non_existing_template_bd' not matching existing bd(s){{':'}} ansible_test_site_bd_from_subnet, ansible_test_1" + +# Use template without site associated +- name: Query with no site associated to template + mso_schema_site_bd_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + site: '{{ mso_site | default("ansible_test") }}' + template: Template3 + bd: ansible_test_3 + subnet: 10.1.0.1/16 + state: query + ignore_errors: yes + register: template_without_sites + +- name: Verify template_without_sites + assert: + that: + - template_without_sites.msg == "No sites associated with schema 'ansible_test_2'. Associate the site with the schema using (M) mso_schema_site." + +# Use non_existing_subnet +- name: Query with non_existing_subnet + mso_schema_site_bd_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + subnet: non_existing_subnet + state: query + ignore_errors: yes + register: non_existing_subnet + +- name: Verify non_existing_subnet + assert: + that: + - non_existing_subnet.msg.startswith("Provided subnet 'non_existing_subnet' not matching existing site bd subnet(s){{':'}}") + +# Use non_existing_site_template_association +- name: Query with non_existing_site_template_association + mso_schema_site_bd_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template4 + bd: ansible_test_4 + subnet: 10.1.0.1/16 + state: query + ignore_errors: yes + register: non_existing_site_template_association + +- name: Verify non_existing_site_template_association + assert: + that: + - non_existing_site_template_association.msg == "Provided site 'ansible_test' not associated with template 'Template4'. Site is currently associated with template(s){{':'}} Template1, Template2, Template5" + +- name: Remove schemas for next ci test case + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_external_epg/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_external_epg/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_external_epg/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_external_epg/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_external_epg/tasks/main.yml new file mode 100644 index 00000000..fb15f042 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_external_epg/tasks/main.yml @@ -0,0 +1,710 @@ +# Test code for the MSO modules +# Copyright: (c) 2021, Anvitha Jain (@anvitha-jain) <anvjain@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") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Remove schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Ensure site exists + mso_site: + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + apic_username: '{{ apic_username }}' + apic_password: '{{ apic_password }}' + apic_site_id: '{{ apic_site_id | default(101) }}' + urls: + - https://{{ apic_hostname }} + state: present + +- name: Ensure sites removed from tenant ansible_test + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: '{{ item }}' + state: absent + loop: + - '{{ mso_site | default("ansible_test") }}' + - 'aws_{{ mso_site | default("ansible_test") }}' + - 'azure_{{ mso_site | default("ansible_test") }}' + +- name: Ensure tenant ansible_test exist + mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + sites: + - '{{ mso_site | default("ansible_test") }}' + state: present + ignore_errors: yes + +- name: Associate non-cloud site with ansible_test + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: '{{ mso_site | default("ansible_test") }}' + state: present + register: add_ncs + +- name: Verify add_ncs + assert: + that: + - add_ncs is not changed + +- name: Remove a site from a schema with Template1 + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: '{{ item }}' + state: absent + ignore_errors: yes + loop: + - Template2 + - Template1 + +- name: Remove schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +# Ensure pre requisites exist +- name: Ensure schema 1 with Template1 and 2 exists + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: '{{ item }}' + state: present + loop: + - Template1 + - Template2 + - Template3 + +- name: Ensure VRF1 exists + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + vrf: VRF1 + state: present + +- name: Ensure VRF2 exists + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template2 + vrf: VRF2 + state: present + +- name: Ensure L3Out1 Exists + mso_schema_template_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + vrf: + name: VRF1 + l3out: L3out1 + state: present + +- name: Ensure L3Out2 Exists + mso_schema_template_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template2 + vrf: + name: VRF2 + l3out: L3out2 + state: present + +# ADD external EPG to template +- name: Add external EPG at template level(check_mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + external_epg: ansible_test_1 + vrf: + name: VRF1 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + l3out: + name: L3out1 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + state: present + check_mode: yes + register: cm_add_epg + +- name: Verify cm_add_epg + assert: + that: + - cm_add_epg is changed + - cm_add_epg.previous == {} + - cm_add_epg.current.name == "ansible_test_1" + - cm_add_epg.current.vrfRef.templateName == "Template1" + - cm_add_epg.current.vrfRef.vrfName == "VRF1" + +- name: Add external EPG at template level(normal mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + external_epg: ansible_test_1 + vrf: + name: VRF1 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + l3out: + name: L3out1 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + state: present + register: nm_add_epg + +- name: Verify nm_add_epg + assert: + that: + - nm_add_epg is changed + - nm_add_epg.previous == {} + - nm_add_epg.current.name == "ansible_test_1" + - nm_add_epg.current.vrfRef.templateName == "Template1" + - nm_add_epg.current.vrfRef.vrfName == "VRF1" + - cm_add_epg.current.vrfRef.schemaId == nm_add_epg.current.vrfRef.schemaId + +# Add External EPG to Site when MSO version >= 3.3 +- name: Execute tasks only for MSO version >= 3.3 + when: version.current.version is version('3.3', '>=') + block: + # Associate site to schema/template after creating External EPG + - name: Add non-cloud site to a schema + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + state: present + register: add_site + + - name: Verify add_site + assert: + that: + - add_site.current.siteId is match ("[0-9a-zA-Z]*") + - add_site.current.templateName == "Template1" + + - name: Add site L3Out (normal_mode) + mso_schema_site_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + l3out: '{{item.l3out}}' + vrf: + name: VRF1 + template: Template1 + schema: '{{ mso_schema | default("ansible_test") }}' + state: present + loop: + - { l3out: L3out1} + + # ADD External EPGs to site + - name: ADD External EPG1 to site (check_mode) + mso_schema_site_external_epg: + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + external_epg: ansible_test_1 + l3out: L3out1 + state: present + check_mode: yes + register: cm_add_epg + + - name: Verify cm_add_epg + assert: + that: + - cm_add_epg.current.externalEpgRef.externalEpgName == "ansible_test_1" + - cm_add_epg.current.externalEpgRef.templateName == "Template1" + + - name: Verify cm_add_epg + assert: + that: + - cm_add_epg is changed + - cm_add_epg.previous == {} + when: version.current.version is version('4.0', '<') # no change in NDO4.0 because site will already be present when template is defined + + - name: Add external EPG to site (normal mode) + mso_schema_site_external_epg: + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + external_epg: ansible_test_1 + l3out: L3out1 + state: present + register: nm_add_epg + + - name: Verify nm_add_epg + assert: + that: + - nm_add_epg.current.externalEpgRef.externalEpgName == "ansible_test_1" + - nm_add_epg.current.externalEpgRef.templateName == "Template1" + - cm_add_epg.current.externalEpgRef.schemaId == nm_add_epg.current.externalEpgRef.schemaId + + - name: Verify nm_add_epg + assert: + that: + - nm_add_epg is changed + - nm_add_epg.previous == {} + when: version.current.version is version('4.0', '<') # no change in NDO4.0 because site will already be present when template is defined + + - name: ADD External EPG1 to site again + mso_schema_site_external_epg: + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + external_epg: ansible_test_1 + l3out: L3out1 + state: present + register: add_epg_again + + - name: Verify add_epg_again + assert: + that: + - add_epg_again is not changed + - add_epg_again.current.externalEpgRef.externalEpgName == "ansible_test_1" + - add_epg_again.current.externalEpgRef.templateName == "Template1" + + # QUERY ALL EPG + - name: Query all external EPGs in site (check_mode) + mso_schema_site_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + state: query + check_mode: yes + register: cm_query_all_epgs + + - name: Query all EPG (normal mode) + mso_schema_site_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + state: query + register: nm_query_all_epgs + + - name: Verify query_all_epgs + assert: + that: + - cm_query_all_epgs is not changed + - nm_query_all_epgs is not changed + + # QUERY AN EPG + - name: Query epg 1(check_mode) + mso_schema_site_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + external_epg: ansible_test_1 + l3out: L3out1 + state: query + check_mode: yes + register: cm_query_epg_1 + + - name: Query epg 1(normal_mode) + mso_schema_site_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + external_epg: ansible_test_1 + l3out: L3out1 + state: query + register: nm_query_epg_1 + + - name: Verify cm_query_epg_1 and nm_query_epg_1 + assert: + that: + - cm_query_epg_1 is not changed + - nm_query_epg_1 is not changed + + # REMOVE EPG + - name: Remove EPG (check_mode) + mso_schema_site_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + external_epg: ansible_test_1 + l3out: L3out1 + state: absent + check_mode: yes + register: cm_remove_epg + + - name: Verify cm_remove_epg + assert: + that: + - cm_remove_epg is changed + - cm_remove_epg.current == {} + + - name: Remove EPG (normal_mode) + mso_schema_site_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + external_epg: ansible_test_1 + l3out: L3out1 + state: absent + register: nm_remove_epg + + - name: Remove external EPG at template level + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + external_epg: ansible_test_1 + state: absent + register: nm_remove_epg + + - name: Verify nm_remove_epg + assert: + that: + - nm_remove_epg is changed + - nm_remove_epg.current == {} + + # Associate site to schema/template before creating External EPG + - name: Add non-cloud site to a schema + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template2 + state: present + when: version.current.version is version('3.3', '>=') + register: add_site + + - name: Verify add_site + assert: + that: + - add_site.current.siteId is match ("[0-9a-zA-Z]*") + - add_site.current.templateName == "Template2" + + # Create template External EPG after site association + - name: Add external EPG (at template level) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template2 + external_epg: ansible_test_2 + vrf: + name: VRF2 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template2 + l3out: + name: L3out2 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template2 + state: present + register: nm_add_ex_epg + + - name: Verify nm_add_ex_epg + assert: + that: + - nm_add_ex_epg is changed + - nm_add_ex_epg.previous == {} + - nm_add_ex_epg.current.name == "ansible_test_2" + - nm_add_ex_epg.current.vrfRef.vrfName == "VRF2" + + - name: Add external EPG to site (normal mode) + mso_schema_site_external_epg: + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template2 + external_epg: ansible_test_2 + l3out: L3out2 + state: present + register: nm_add_epg + + - name: Verify nm_add_epg + assert: + that: + - nm_add_epg.current.externalEpgRef.externalEpgName == "ansible_test_2" + - nm_add_epg.current.externalEpgRef.templateName == "Template2" + + - name: Verify nm_add_epg + assert: + that: + - nm_add_epg is changed + - nm_add_epg.previous == {} + when: version.current.version is version('4.0', '<') # no change in NDO4.0 because site will already be present when template is defined + + # QUERY NON-EXISTING external EPG + - name: Query non-existing External EPG (check_mode) + mso_schema_site_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + external_epg: non_existing_epg + l3out: L3out1 + state: query + check_mode: yes + ignore_errors: yes + register: cm_query_non_external_epg + + - name: Query non-existing External EPG (normal_mode) + mso_schema_site_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + external_epg: non_existing_epg + l3out: L3out1 + state: query + ignore_errors: yes + register: nm_query_non_external_epg + + - name: Verify cm_query_non_external_epg and nm_query_non_external_epg + assert: + that: + - cm_query_non_external_epg is not changed + - nm_query_non_external_epg is not changed + - cm_query_non_external_epg.msg == nm_query_non_external_epg.msg == "External EPG 'non_existing_epg' not found" + + # USE NON-EXISTING STATE + - name: non_existing_state state (check_mode) + mso_schema_site_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + external_epg: ansible_test_2 + l3out: L3out1 + state: non_existing_state + ignore_errors: yes + register: cm_non_existing_state + + - name: non_existing_state state (normal_mode) + mso_schema_site_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + external_epg: ansible_test_2 + l3out: L3out1 + state: non_existing_state + ignore_errors: yes + register: nm_non_existing_state + + - name: Verify cm_non_existing_state and nm_non_existing_state + assert: + that: + - cm_non_existing_state is not changed + - nm_non_existing_state is not changed + - cm_non_existing_state.msg == nm_non_existing_state.msg == "value of state must be one of{{':'}} absent, present, query, got{{':'}} non_existing_state" + + # USE A NON_EXISTING_TEMPLATE + - name: non_existing_template (check_mode) + mso_schema_site_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: non_existing_template + external_epg: ansible_test_2 + l3out: L3out1 + state: query + check_mode: yes + ignore_errors: yes + register: cm_non_existing_template + + - name: non_existing_template (normal_mode) + mso_schema_site_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: non_existing_template + external_epg: ansible_test_2 + l3out: L3out1 + state: query + ignore_errors: yes + register: nm_non_existing_template + + - name: Verify cm_non_existing_template and nm_non_existing_template + assert: + that: + - cm_non_existing_template is not changed + - nm_non_existing_template is not changed + - cm_non_existing_template.msg == nm_non_existing_template.msg == "Provided template 'non_existing_template' does not exist. Existing templates{{':'}} Template1, Template2, Template3" + + # USE A NON_EXISTING_SCHEMA + - name: non_existing_schema (check_mode) + mso_schema_site_external_epg: + <<: *mso_info + schema: non_existing_schema + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + external_epg: ansible_test_2 + l3out: L3out1 + state: query + check_mode: yes + ignore_errors: yes + register: cm_non_existing_schema + + - name: non_existing_schema (normal_mode) + mso_schema_site_external_epg: + <<: *mso_info + schema: non_existing_schema + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + external_epg: ansible_test_2 + l3out: L3out1 + state: query + ignore_errors: yes + register: nm_non_existing_schema + + - name: Verify cm_non_existing_schema and nm_non_existing_schema + assert: + that: + - cm_non_existing_schema is not changed + - nm_non_existing_schema is not changed + - cm_non_existing_schema.msg == nm_non_existing_schema.msg == "Provided schema 'non_existing_schema' does not exist." + + # USE A NON_EXISTING_SITE + - name: non_existing_site (check_mode) + mso_schema_site_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: non_existing_site + template: Template1 + external_epg: ansible_test_2 + l3out: L3out1 + state: query + check_mode: yes + ignore_errors: yes + register: cm_non_existing_site + + - name: non_existing_site (normal_mode) + mso_schema_site_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: non_existing_site + template: Template1 + external_epg: ansible_test_2 + l3out: L3out1 + state: query + ignore_errors: yes + register: nm_non_existing_site + + - name: Verify cm_non_existing_site and nm_non_existing_site + assert: + that: + - cm_non_existing_site is not changed + - nm_non_existing_site is not changed + - cm_non_existing_site.msg == nm_non_existing_site.msg == "Site 'non_existing_site' is not a valid site name." + + # USE A NON_EXISTING_SITE_TEMPLATE + - name: non_existing_site_template (check_mode) + mso_schema_site_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template3 + external_epg: ansible_test_2 + l3out: L3out1 + state: query + check_mode: yes + ignore_errors: yes + register: cm_non_existing_site_template + + - name: non_existing_site_template (normal_mode) + mso_schema_site_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template3 + external_epg: ansible_test_2 + l3out: L3out1 + state: query + ignore_errors: yes + register: nm_non_existing_site_template + + - name: Verify cm_non_existing_site_template and nm_non_existing_site_template + assert: + that: + - cm_non_existing_site_template is not changed + - nm_non_existing_site_template is not changed + - cm_non_existing_site_template.msg == nm_non_existing_site_template.msg == "Provided template 'Template3' does not exist. Existing templates{{':'}} Template1, Template2, Template3" + + # USE A TEMPLATE WITHOUT ANY SITE + - name: Add site L3Out to Schema Template2 without any site associated (check mode) + mso_schema_site_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template3 + external_epg: ansible_test_2 + l3out: L3out1 + state: present + check_mode: yes + ignore_errors: yes + register: cm_no_site_associated + + - name: Add site L3Out to Template2 without any site associated (normal mode) + mso_schema_site_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template3 + external_epg: ansible_test_2 + l3out: L3out1 + state: present + ignore_errors: yes + register: nm_no_site_associated + + - name: Verify cm_no_site_associated and nm_no_site_associated + assert: + that: + - cm_no_site_associated is not changed + - nm_no_site_associated is not changed + - cm_no_site_associated.msg == nm_no_site_associated.msg == "Provided template 'Template3' does not exist. Existing templates{{':'}} Template1, Template2, Template3" diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_external_epg_selector/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_external_epg_selector/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_external_epg_selector/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_external_epg_selector/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_external_epg_selector/tasks/main.yml new file mode 100644 index 00000000..5ea55502 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_external_epg_selector/tasks/main.yml @@ -0,0 +1,533 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Lionel Hercot (@lhercot) <lhercot@cisco.com> +# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> (based on mso_site test case) +# Copyright: (c) 2020, Shreyas Srish (@shrsr) <ssrish@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") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Ensure azure site exists + mso_site: + <<: *mso_info + site: 'azure_{{ mso_site | default("ansible_test") }}' + apic_username: '{{ azure_apic_username }}' + apic_password: '{{ azure_apic_password }}' + apic_site_id: '{{ azure_site_id | default(103) }}' + urls: + - https://{{ azure_apic_hostname }} + state: present + +- name: Ensure aws site exists + mso_site: + <<: *mso_info + site: 'aws_{{ mso_site | default("ansible_test") }}' + apic_username: '{{ aws_apic_username }}' + apic_password: '{{ aws_apic_password }}' + apic_site_id: '{{ aws_site_id | default(102) }}' + urls: + - https://{{ aws_apic_hostname }} + state: present + +- name: Remove schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Ensure sites removed from tenant ansible_test + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: '{{ item }}' + state: absent + loop: + - '{{ mso_site | default("ansible_test") }}' + - 'aws_{{ mso_site | default("ansible_test") }}' + - 'azure_{{ mso_site | default("ansible_test") }}' + +- name: Ensure tenant ansible_test exist + mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + sites: + - '{{ mso_site | default("ansible_test") }}' + state: present + +- name: Associate aws site with ansible_test + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'aws_{{ mso_site | default("ansible_test") }}' + cloud_account: "000000000000" + aws_trusted: false + aws_access_key: "1" + secret_key: "0" + state: present + +- name: Associate azure site with ansible_test + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'azure_{{ mso_site | default("ansible_test") }}' + cloud_account: uni/tn-ansible_test/act-[100]-vendor-azure + state: present + +- name: Ensure schema 1 with Template 1 and 2 exists + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: '{{ item }}' + state: present + loop: + - Template 1 + - Template 2 + +- name: Ensure schema 2 with Template 3 exists + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template 3 + state: present + +- name: Ensure VRF1 exists + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF1 + state: present + +- name: Ensure Template 1 with AP1 exists + mso_schema_template_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: AP1 + state: present + +- name: Ensure L3Out Exists + mso_schema_template_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: + name: VRF1 + l3out: L3out1 + state: present + +- name: Ensure External EPG1 exists + mso_schema_template_externalepg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + externalepg: extEPG1 + vrf: + name: VRF1 + template: Template 1 + schema: '{{ mso_schema | default("ansible_test") }}' + l3out: + name: L3out1 + template: Template 1 + schema: '{{ mso_schema | default("ansible_test") }}' + anp: + name: AP1 + template: Template 1 + schema: '{{ mso_schema | default("ansible_test") }}' + state: present + +- name: Ensure External EPG2 exists + mso_schema_template_externalepg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + externalepg: extEPG2 + vrf: + name: VRF1 + template: Template 1 + schema: '{{ mso_schema | default("ansible_test") }}' + l3out: + name: L3out1 + template: Template 1 + schema: '{{ mso_schema | default("ansible_test") }}' + anp: + name: AP1 + template: Template 1 + schema: '{{ mso_schema | default("ansible_test") }}' + state: present + +- name: Add Azure site to a schema + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'azure_{{ mso_site | default("ansible_test") }}' + template: Template 1 + state: present + when: version.current.version is version('3', '<') + +- name: Add AWS site to a schema + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + state: present + when: version.current.version is version('3', '<') + +- name: Add a new CIDR in VRF1 at site level + mso_schema_site_vrf_region_cidr: &mso_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: '{{ item }}' + vrf: VRF1 + region: us-west-1 + cidr: 10.0.0.0/16 + primary: true + state: present + loop: + - 'aws_{{ mso_site | default("ansible_test") }}' + - 'azure_{{ mso_site | default("ansible_test") }}' + +# ADD SELECTORS +- name: Add a selector to Azure in check mode + mso_schema_site_external_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'azure_{{ mso_site | default("ansible_test") }}' + external_epg: extEPG1 + selector: e1 + expressions: + - type: ip_address + operator: equals + value: 10.0.0.0 + state: present + check_mode: yes + register: cm_azure_e1 + +- name: Verify cm_azure_e1 + assert: + that: + - cm_azure_e1 is changed + - cm_azure_e1.previous == {} + - cm_azure_e1.current.subnets[0].ip == '10.0.0.0' + - cm_azure_e1.current.subnets[0].name == 'e1' + + +- name: Add a selector to Azure in normal mode + mso_schema_site_external_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'azure_{{ mso_site | default("ansible_test") }}' + external_epg: extEPG1 + selector: e1 + expressions: + - type: ip_address + operator: equals + value: 10.0.0.0 + state: present + register: nm_azure_e1 + +- name: Verify nm_azure_e1 + assert: + that: + - nm_azure_e1 is changed + - nm_azure_e1.previous == {} + - nm_azure_e1.current.subnets[0].ip == '10.0.0.0' + - nm_azure_e1.current.subnets[0].name == 'e1' + +- name: Add a selector to AWS in normal mode + mso_schema_site_external_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + external_epg: extEPG2 + selector: e2 + expressions: + - type: ip_address + operator: equals + value: 10.1.1.1 + state: present + register: nm_aws_e2 + +- name: Verify nm_aws_e2 + assert: + that: + - nm_aws_e2 is changed + - nm_aws_e2.previous == {} + - nm_aws_e2.current.subnets[0].ip == '10.1.1.1' + - nm_aws_e2.current.subnets[0].name == 'e2' + +- name: Add a selector to AWS in normal mode again + mso_schema_site_external_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + external_epg: extEPG2 + selector: e2 + expressions: + - type: ip_address + operator: equals + value: 10.1.1.1 + state: present + register: nm_aws_e1_again + +- name: Verify nm_aws_e1_again + assert: + that: + - nm_aws_e1_again is not changed + +- name: Add a selector to AWS in normal mode again with no expressions + mso_schema_site_external_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + external_epg: extEPG2 + selector: e2 + state: present + ignore_errors: yes + register: nm_aws_e1_again_noexp + +- name: Verify nm_aws_e1_again_noexp + assert: + that: + - nm_aws_e1_again_noexp is not changed + - nm_aws_e1_again_noexp.msg == "Missing expressions in selector" + +# QUERY A SELECTOR +- name: Query a selector of Azure + mso_schema_site_external_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'azure_{{ mso_site | default("ansible_test") }}' + external_epg: extEPG1 + selector: e1 + state: query + register: query_azure_e1 + +- name: Verify query_azure_e1 + assert: + that: + - query_azure_e1 is not changed + +# QUERY ALL +- name: Query all selectors of Azure + mso_schema_site_external_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'azure_{{ mso_site | default("ansible_test") }}' + external_epg: extEPG1 + state: query + register: query_all + +- name: Verify query_all + assert: + that: + - query_all is not changed + +# REMOVE A SELECTOR +- name: Remove a selector of Azure + mso_schema_site_external_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'azure_{{ mso_site | default("ansible_test") }}' + external_epg: extEPG1 + selector: e1 + state: absent + register: remove_azure_e1 + +- name: Verify remove_azure_e1 + assert: + that: + - remove_azure_e1 is changed + +- name: Remove a selector of Azure again + mso_schema_site_external_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'azure_{{ mso_site | default("ansible_test") }}' + external_epg: extEPG1 + selector: e1 + state: absent + ignore_errors: yes + register: remove_azure_e1_again + +- name: Verify remove_azure_e1_again + assert: + that: + - remove_azure_e1_again is not changed + +# QUERY REMOVED SELECTOR +- name: Query a removed selector of Azure + mso_schema_site_external_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'azure_{{ mso_site | default("ansible_test") }}' + external_epg: extEPG1 + selector: e1 + state: query + ignore_errors: yes + register: query_removed_azure_e1 + +- name: Verify query_removed_azure_e1 + assert: + that: + - query_removed_azure_e1 is not changed + +# USE A NON-EXISTING SCHEMA +- name: Non-existing schema for selector (check_mode) + mso_schema_site_external_epg_selector: + <<: *mso_info + schema: non_existing_schema + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + external_epg: extEPG2 + check_mode: yes + ignore_errors: yes + register: cm_non_existing_schema + +- name: Non-existing schema for selector (normal_mode) + mso_schema_site_external_epg_selector: + <<: *mso_info + schema: non_existing_schema + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + external_epg: extEPG2 + ignore_errors: yes + register: nm_non_existing_schema + +- name: Verify non_existing_schema + assert: + that: + - cm_non_existing_schema is not changed + - nm_non_existing_schema is not changed + - cm_non_existing_schema == nm_non_existing_schema + - cm_non_existing_schema.msg == nm_non_existing_schema.msg == "Provided schema 'non_existing_schema' does not exist." + +# USE A NON-EXISTING TEMPLATE +- name: Non-existing template for selector (check_mode) + mso_schema_site_external_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: non_existing_template + external_epg: extEPG2 + check_mode: yes + ignore_errors: yes + register: cm_non_existing_template + +- name: Non-existing template for selector (normal_mode) + mso_schema_site_external_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: non_existing_template + external_epg: extEPG2 + ignore_errors: yes + register: nm_non_existing_template + +- name: Verify non_existing_template + assert: + that: + - cm_non_existing_template is not changed + - nm_non_existing_template is not changed + - cm_non_existing_template == nm_non_existing_template + - cm_non_existing_template.msg == nm_non_existing_template.msg == "Provided template 'non_existing_template' does not exist. Existing templates{{':'}} Template1, Template2" + +# USE A NON-EXISTING SITE +- name: Non-existing site for static port (check_mode) + mso_schema_site_external_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'azure_{{ mso_site | default("ansible_test") }}' + template: Template 2 + external_epg: extEPG3 + check_mode: yes + ignore_errors: yes + register: cm_non_existing_site + +- name: Non-existing site for static port (normal_mode) + mso_schema_site_external_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'azure_{{ mso_site | default("ansible_test") }}' + template: Template 2 + external_epg: extEPG3 + ignore_errors: yes + register: nm_non_existing_site + +- name: Verify non_existing_site + assert: + that: + - cm_non_existing_site is not changed + - nm_non_existing_site is not changed + - cm_non_existing_site == nm_non_existing_site + - cm_non_existing_site.msg is match("Provided site/siteId/template 'azure_ansible_test/[0-9a-zA-Z]*/Template2' does not exist. Existing siteIds/templates{{':'}} [0-9a-zA-Z]*/Template1") + - nm_non_existing_site.msg is match("Provided site/siteId/template 'azure_ansible_test/[0-9a-zA-Z]*/Template2' does not exist. Existing siteIds/templates{{':'}} [0-9a-zA-Z]*/Template1") + +# USE A TEMPLATE WITHOUT ANY SITE +- name: Add site external EPG selector to Schema 2 Template 3 without any site associated (check mode) + mso_schema_site_external_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + site: 'azure_{{ mso_site | default("ansible_test") }}' + template: Template 3 + external_epg: extEPG3 + ignore_errors: yes + check_mode: yes + register: cm_no_site_associated + +- name: Add site external EPG selector to Template 3 without any site associated (normal mode) + mso_schema_site_external_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + site: 'azure_{{ mso_site | default("ansible_test") }}' + template: Template 3 + external_epg: extEPG3 + ignore_errors: yes + register: nm_no_site_associated + +- name: Verify cm_no_site_associated and nm_no_site_associated + assert: + that: + - cm_no_site_associated is not changed + - nm_no_site_associated is not changed + - cm_no_site_associated.msg == nm_no_site_associated.msg == "No site associated with template 'Template3'. Associate the site with the template using mso_schema_site."
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_l3out/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_l3out/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_l3out/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_l3out/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_l3out/tasks/main.yml new file mode 100644 index 00000000..8903b2d0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_l3out/tasks/main.yml @@ -0,0 +1,614 @@ +# Test code for the MSO modules +# Copyright: (c) 2021, Anvitha Jain (@anvitha-jain) <anvjain@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 + ansible.builtin.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 + ansible.builtin.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") }}' + l3outs: [ "L3out1", "L3out2"] + +- name: Query MSO version + cisco.mso.mso_version: + <<: *mso_info + state: query + register: version + +- name: Ensure site exists + cisco.mso.mso_site: + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + apic_username: '{{ apic_username }}' + apic_password: '{{ apic_password }}' + apic_site_id: '{{ apic_site_id | default(101) }}' + urls: + - https://{{ apic_hostname }} + state: present + ignore_errors: yes + +- name: Remove schemas + cisco.mso.mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Ensure sites removed from tenant ansible_test + cisco.mso.mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: '{{ item }}' + state: absent + loop: + - '{{ mso_site | default("ansible_test") }}' + - 'aws_{{ mso_site | default("ansible_test") }}' + - 'azure_{{ mso_site | default("ansible_test") }}' + +- name: Ensure tenant ansible_test exists + cisco.mso.mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + sites: + - '{{ mso_site | default("ansible_test") }}' + state: present + +- name: Ensure schema 1 with Template1, and Template2 exist + cisco.mso.mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: '{{item.template}}' + state: present + loop: + - { template: Template1} + - { template: Template2} + +- name: Ensure schema 2 with Template3 exist + cisco.mso.mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template3 + state: present + +- name: Ensure VRF1 exists + cisco.mso.mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + vrf: VRF1 + state: present + +- name: Add new L3Out + cisco.mso.mso_schema_template_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + l3out: '{{ item }}' + vrf: + name: VRF1 + state: present + register: add_l3out + loop: '{{ l3outs }}' + +- name: Verify add l3out (template level) + ansible.builtin.assert: + that: + - add_l3out is changed + +- name: Add physical site to a schema + cisco.mso.mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + state: present + +# Add L3out to Site when MSO version >= 3.0 +- name: Execute tasks only for MSO version >= 3.0 + when: version.current.version is version('3.0', '>=') + block: + # Add l3out to site + - name: Add site L3Out (check_mode) + cisco.mso.mso_schema_site_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + l3out: L3out1 + vrf: + name: VRF1 + template: Template1 + schema: '{{ mso_schema | default("ansible_test") }}' + state: present + check_mode: yes + register: cm_add_site_l3out + + - name: Verify cm_add_site_l3out + ansible.builtin.assert: + that: + - cm_add_site_l3out.current.vrfRef.vrfName == "VRF1" + - cm_add_site_l3out.current.vrfRef.templateName == "Template1" + + - name: Verify cm_add_site_l3out + ansible.builtin.assert: + that: + - cm_add_site_l3out is changed + - cm_add_site_l3out.previous == {} + when: version.current.version is version('4.0', '<') # no change in NDO4.0 because site will already be present when template is defined + + - name: Add site L3Out (normal_mode) + cisco.mso.mso_schema_site_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + l3out: L3out1 + vrf: + name: VRF1 + template: Template1 + schema: '{{ mso_schema | default("ansible_test") }}' + state: present + register: nm_add_site_l3out + + - name: Verify nm_add_site_l3out + ansible.builtin.assert: + that: + - nm_add_site_l3out.current.vrfRef.vrfName == "VRF1" + - nm_add_site_l3out.current.vrfRef.templateName == "Template1" + - cm_add_site_l3out.current.vrfRef.schemaId == nm_add_site_l3out.current.vrfRef.schemaId + + - name: Verify nm_add_site_l3out + ansible.builtin.assert: + that: + - nm_add_site_l3out is changed + - nm_add_site_l3out.previous == {} + when: version.current.version is version('4.0', '<') # no change in NDO4.0 because site will already be present when template is defined + + - name: Add site L3Out 2 (normal_mode) + cisco.mso.mso_schema_site_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + l3out: L3out2 + vrf: + name: VRF1 + template: Template1 + schema: '{{ mso_schema | default("ansible_test") }}' + state: present + + - name: Add site L3Out again (normal_mode) + cisco.mso.mso_schema_site_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + l3out: L3out2 + vrf: + name: VRF1 + template: Template1 + schema: '{{ mso_schema | default("ansible_test") }}' + state: present + register: nm_add_site_l3out_again + + - name: Verify cm_add_site_l3out_again and nm_add_site_l3out_again + ansible.builtin.assert: + that: + - nm_add_site_l3out_again is not changed + - nm_add_site_l3out_again.current.vrfRef.vrfName == "VRF1" + + # No options to do changes in site level yet + + - name: Query all L3Outs (check_mode) + cisco.mso.mso_schema_site_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + state: query + check_mode: yes + register: cm_query_all_l3out + + - name: Query all L3Outs (normal_mode) + cisco.mso.mso_schema_site_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + state: query + register: nm_query_all_l3out + + - name: Verify cm_query_all_l3out and cm_query_all_l3out + ansible.builtin.assert: + that: + - cm_query_all_l3out is not changed + - nm_query_all_l3out is not changed + - cm_query_all_l3out.current | length == 2 + - nm_query_all_l3out.current | length == 2 + - "'{{cm_query_all_l3out.current[0].l3outRef.l3outName}}' in l3outs" + - "'{{cm_query_all_l3out.current[1].l3outRef.l3outName}}' in l3outs" + - "'{{nm_query_all_l3out.current[0].l3outRef.l3outName}}' in l3outs" + - "'{{nm_query_all_l3out.current[1].l3outRef.l3outName}}' in l3outs" + - cm_query_all_l3out.current[0].l3outRef.schemaId == nm_query_all_l3out.current[0].l3outRef.schemaId + - cm_query_all_l3out.current[0].l3outRef.templateName == nm_query_all_l3out.current[0].l3outRef.templateName == "Template1" + + - name: Query a specific L3Out (check_mode) + cisco.mso.mso_schema_site_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + l3out: L3out1 + vrf: + name: VRF1 + template: Template1 + schema: '{{ mso_schema | default("ansible_test") }}' + state: query + check_mode: yes + register: cm_query_l3out + + - name: Query a specific L3Out (normal_mode) + cisco.mso.mso_schema_site_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + l3out: L3out1 + state: query + register: nm_query_l3out + + - name: Verify cm_query_l3out and nm_query_l3out + ansible.builtin.assert: + that: + - cm_query_l3out is not changed + - nm_query_l3out is not changed + + - name: Remove L3Out (check_mode) + cisco.mso.mso_schema_site_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + l3out: L3out1 + state: absent + check_mode: yes + register: cm_remove_site_l3out + + - name: Remove L3Out (normal_mode) + cisco.mso.mso_schema_site_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + l3out: L3out1 + state: absent + register: nm_remove_site_l3out + + - name: Verify cm_remove_site_l3out and nm_remove_site_l3out + ansible.builtin.assert: + that: + - cm_remove_site_l3out is changed + - nm_remove_site_l3out is changed + - cm_remove_site_l3out.current == nm_remove_site_l3out.current == {} + when: version.current.version is version('4.0', '<') # no change in NDO4.0 because site will already be present when template is defined + + - name: Remove L3Out again(normal_mode) + cisco.mso.mso_schema_site_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + l3out: L3out1 + state: absent + register: nm_remove_site_l3out_again + + - name: Verify nm_remove_site_l3out_again + ansible.builtin.assert: + that: + - nm_remove_site_l3out_again is not changed + - nm_remove_site_l3out_again.previous == nm_remove_site_l3out_again.current == {} + when: version.current.version is version('4.0', '<') # no change in NDO4.0 because site will already be present when template is defined + + + # QUERY NON-EXISTING L3Out + - name: Query non-existing L3Out (check_mode) + cisco.mso.mso_schema_site_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + l3out: non_existing_l3out + state: query + check_mode: yes + ignore_errors: yes + register: cm_query_non_l3out + + - name: Query non-existing L3Out (normal_mode) + cisco.mso.mso_schema_site_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + l3out: non_existing_l3out + state: query + ignore_errors: yes + register: nm_query_non_l3out + + - name: Verify cm_query_non_l3out and nm_query_non_l3out + ansible.builtin.assert: + that: + - cm_query_non_l3out is not changed + - nm_query_non_l3out is not changed + - cm_query_non_l3out.msg == nm_query_non_l3out.msg == "L3Out 'non_existing_l3out' not found" + + # USE NON-EXISTING STATE + - name: non_existing_state state (check_mode) + cisco.mso.mso_schema_site_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + l3out: L3out1 + vrf: + name: VRF1 + template: Template1 + schema: '{{ mso_schema | default("ansible_test") }}' + state: non_existing_state + ignore_errors: yes + register: cm_non_existing_state + + - name: non_existing_state state (normal_mode) + cisco.mso.mso_schema_site_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + l3out: L3out1 + vrf: + name: VRF1 + template: Template1 + schema: '{{ mso_schema | default("ansible_test") }}' + state: non_existing_state + ignore_errors: yes + register: nm_non_existing_state + + - name: Verify cm_non_existing_state and nm_non_existing_state + ansible.builtin.assert: + that: + - cm_non_existing_state is not changed + - nm_non_existing_state is not changed + - cm_non_existing_state.msg == nm_non_existing_state.msg == "value of state must be one of{{':'}} absent, present, query, got{{':'}} non_existing_state" + + # USE A NON_EXISTING_TEMPLATE + - name: non_existing_template (check_mode) + cisco.mso.mso_schema_site_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: non_existing_template + l3out: L3out1 + vrf: + name: VRF1 + template: Template1 + schema: '{{ mso_schema | default("ansible_test") }}' + state: query + check_mode: yes + ignore_errors: yes + register: cm_non_existing_template + + - name: non_existing_template (normal_mode) + cisco.mso.mso_schema_site_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: non_existing_template + l3out: L3out1 + vrf: + name: VRF1 + template: Template1 + schema: '{{ mso_schema | default("ansible_test") }}' + state: query + ignore_errors: yes + register: nm_non_existing_template + + - name: Verify cm_non_existing_template and nm_non_existing_template + ansible.builtin.assert: + that: + - cm_non_existing_template is not changed + - nm_non_existing_template is not changed + - cm_non_existing_template.msg == nm_non_existing_template.msg == "Provided template 'non_existing_template' does not exist. Existing templates{{':'}} Template1, Template2" + + # USE A NON_EXISTING_SCHEMA + - name: non_existing_schema (check_mode) + cisco.mso.mso_schema_site_l3out: + <<: *mso_info + schema: non_existing_schema + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + l3out: L3out1 + vrf: + name: VRF1 + template: Template1 + schema: '{{ mso_schema | default("ansible_test") }}' + state: query + check_mode: yes + ignore_errors: yes + register: cm_non_existing_schema + + - name: non_existing_schema (normal_mode) + cisco.mso.mso_schema_site_l3out: + <<: *mso_info + schema: non_existing_schema + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + l3out: L3out1 + vrf: + name: VRF1 + template: Template1 + schema: '{{ mso_schema | default("ansible_test") }}' + state: query + ignore_errors: yes + register: nm_non_existing_schema + + - name: Verify cm_non_existing_schema and nm_non_existing_schema + ansible.builtin.assert: + that: + - cm_non_existing_schema is not changed + - nm_non_existing_schema is not changed + - cm_non_existing_schema.msg == nm_non_existing_schema.msg == "Provided schema 'non_existing_schema' does not exist." + + # USE A NON_EXISTING_SITE + - name: non_existing_site (check_mode) + cisco.mso.mso_schema_site_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: non_existing_site + template: Template1 + l3out: L3out1 + vrf: + name: VRF1 + template: Template1 + schema: '{{ mso_schema | default("ansible_test") }}' + state: query + check_mode: yes + ignore_errors: yes + register: cm_non_existing_site + + - name: non_existing_site (normal_mode) + cisco.mso.mso_schema_site_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: non_existing_site + template: Template1 + l3out: L3out1 + vrf: + name: VRF1 + template: Template1 + schema: '{{ mso_schema | default("ansible_test") }}' + state: query + ignore_errors: yes + register: nm_non_existing_site + + - name: Verify cm_non_existing_site and nm_non_existing_site + ansible.builtin.assert: + that: + - cm_non_existing_site is not changed + - nm_non_existing_site is not changed + - cm_non_existing_site.msg == nm_non_existing_site.msg == "Site 'non_existing_site' is not a valid site name." + + # USE A NON_EXISTING_SITE_TEMPLATE + - name: non_existing_site_template (check_mode) + cisco.mso.mso_schema_site_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template5 + l3out: L3out1 + vrf: + name: VRF1 + template: Template1 + schema: '{{ mso_schema | default("ansible_test") }}' + state: query + check_mode: yes + ignore_errors: yes + register: cm_non_existing_site_template + + - name: non_existing_site_template (normal_mode) + cisco.mso.mso_schema_site_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template5 + l3out: L3out1 + vrf: + name: VRF1 + template: Template1 + schema: '{{ mso_schema | default("ansible_test") }}' + state: query + ignore_errors: yes + register: nm_non_existing_site_template + + - name: Verify cm_non_existing_site_template and nm_non_existing_site_template + ansible.builtin.assert: + that: + - cm_non_existing_site_template is not changed + - nm_non_existing_site_template is not changed + - cm_non_existing_site_template.msg == nm_non_existing_site_template.msg == "Provided template 'Template5' does not exist. Existing templates{{':'}} Template1, Template2" + + - name: nm_non_existing_template_site (normal_mode) + cisco.mso.mso_schema_site_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template2 + l3out: L3out1 + vrf: + name: VRF1 + template: Template1 + schema: '{{ mso_schema | default("ansible_test") }}' + state: query + ignore_errors: yes + register: nm_non_existing_template_site + + - name: Verify nm_non_existing_template_site + ansible.builtin.assert: + that: + - nm_non_existing_template_site is not changed + - nm_non_existing_template_site.msg == "Provided template 'Template2' is not associated to site" + + # USE A TEMPLATE WITHOUT ANY SITE + - name: Add site L3Out to Schema Template3 without any site associated (check mode) + cisco.mso.mso_schema_site_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + site: '{{ mso_site | default("ansible_test") }}' + template: Template3 + l3out: L3out1 + vrf: + name: VRF1 + template: Template1 + schema: '{{ mso_schema | default("ansible_test") }}' + state: present + check_mode: yes + ignore_errors: yes + register: cm_no_site_associated + + - name: Add site L3Out to Template3 without any site associated (normal mode) + cisco.mso.mso_schema_site_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + site: '{{ mso_site | default("ansible_test") }}' + template: Template3 + l3out: L3out1 + vrf: + name: VRF1 + template: Template1 + schema: '{{ mso_schema | default("ansible_test") }}' + state: present + ignore_errors: yes + register: nm_no_site_associated + + - name: Verify cm_no_site_associated and nm_no_site_associated + ansible.builtin.assert: + that: + - cm_no_site_associated is not changed + - nm_no_site_associated is not changed + - cm_no_site_associated.msg == nm_no_site_associated.msg == "No site associated with template 'Template3'. Associate the site with the template using mso_schema_site."
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_service_graph/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_service_graph/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_service_graph/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_service_graph/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_service_graph/tasks/main.yml new file mode 100644 index 00000000..8c4a6553 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_service_graph/tasks/main.yml @@ -0,0 +1,795 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Shreyas Srish (@shrsr) <ssrish@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(false) }}' + output_level: '{{ mso_output_level | default("info") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +# Service Graph at Site Level is blocked by validations in MSO/NDO before v3.3. +# It is supported after v3.3 by using validate=false. +- name: Execute tasks only for MSO version >= 3.3 + when: version.current.version is version('3.3', '>=') + block: + - name: Ensure site exists + cisco.mso.mso_site: + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + apic_username: '{{ apic_username }}' + apic_password: '{{ apic_password }}' + apic_site_id: '{{ apic_site_id | default(101) }}' + urls: + - https://{{ apic_hostname }} + state: present + ignore_errors: yes + + - name: Remove schemas + cisco.mso.mso_schema: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + state: absent + + - name: Ensure sites removed from tenant ansible_test + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: '{{ item }}' + state: absent + loop: + - '{{ mso_site | default("ansible_test") }}' + - 'aws_{{ mso_site | default("ansible_test") }}' + - 'azure_{{ mso_site | default("ansible_test") }}' + + - name: Ensure tenant ansible_test exist + cisco.mso.mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + state: present + + - name: Associate site with ansible_test + cisco.mso.mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: '{{ mso_site | default("ansible_test") }}' + state: present + + - name: Add a tenant on APIC + cisco.aci.aci_tenant: + host: '{{ apic_hostname }}' + username: '{{ apic_username }}' + password: '{{ apic_password }}' + validate_certs: no + name: "ansible_test" + + - name: Add devices to APIC + cisco.aci.aci_rest: + host: '{{ apic_hostname }}' + username: '{{ apic_username }}' + password: '{{ apic_password }}' + validate_certs: no + path: /api/node/mo/uni/tn-ansible_test.json + method: post + content: + vnsLDevVip: + attributes: + svcType: '{{ item.type }}' + managed: 'false' + name: '{{ item.name }}' + children: + - vnsCDev: + attributes: + name: '{{ item.name }}' + loop: + - { type: FW, name: ansible_test_firewall1 } + - { type: FW, name: ansible_test_firewall2 } + - { type: ADC, name: ansible_test_adc } + - { type: OTHERS, name: ansible_test_other } + + - name: Ensure schema 1 with Template1 and 2 exist + cisco.mso.mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: '{{ item }}' + state: present + loop: + - 'Template1' + - 'Template2' + + - name: Ensure schema 2 with Template1 exists + cisco.mso.mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template1 + state: present + + - name: Add Node1 + cisco.mso.mso_service_node_type: + <<: *mso_info + name: ansible_test_other1 + display_name: ansible_test_other1 + state: present + + - name: Add Node2 + cisco.mso.mso_service_node_type: + <<: *mso_info + name: ansible_test_other2 + display_name: ansible_test_other2 + state: present + + - name: Create a service graph 1 at Template level + cisco.mso.mso_schema_template_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG1 + display_name: sg1 + service_nodes: + - type: firewall + filter_after_first_node: allow_all + state: present + + - name: Create service graph 2 at Template level + cisco.mso.mso_schema_template_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG2 + display_name: sg2 + service_nodes: + - type: firewall + - type: load-balancer + filter_after_first_node: allow_all + state: present + register: sg1_again + + - name: Create service graph 3 at Template level + cisco.mso.mso_schema_template_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG3 + display_name: sg3 + service_nodes: + - type: firewall + - type: load-balancer + - type: other + filter_after_first_node: allow_all + state: present + register: sg1_again + + - name: Create a service graph 4 at Template level + cisco.mso.mso_schema_template_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG4 + display_name: sg4 + service_nodes: + - type: other + - type: load-balancer + - type: firewall + filter_after_first_node: filters_from_contract + state: present + + - name: Create a service graph 5 at Template level + cisco.mso.mso_schema_template_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG5 + display_name: sg5 + service_nodes: + - type: other + - type: firewall + - type: firewall + filter_after_first_node: filters_from_contract + state: present + + - name: Create a service graph 6 at Template level + cisco.mso.mso_schema_template_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG6 + display_name: sg6 + service_nodes: + - type: other + - type: other + - type: other + filter_after_first_node: filters_from_contract + state: present + + - name: Create a service graph 7 at Template level + cisco.mso.mso_schema_template_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG7 + display_name: sg7 + service_nodes: + - type: load-balancer + - type: load-balancer + filter_after_first_node: filters_from_contract + state: present + + - name: Add physical site to a schema + cisco.mso.mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + state: present + + - name: Add a new Graph at site level (check mode) + cisco.mso.mso_schema_site_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG1 + site: '{{ mso_site | default("ansible_test") }}' + tenant: ansible_test + devices: + - name: ansible_test_firewall1 + state: present + register: cm_sg1 + check_mode: yes + + - name: Verify cm_sg1 + assert: + that: + - cm_sg1 is changed + - cm_sg1.current.serviceGraphRef.serviceGraphName == "SG1" + - cm_sg1.current.serviceGraphRef.templateName == "Template1" + - cm_sg1.current.serviceNodes | length == 1 + - cm_sg1.current.serviceNodes.0.device.dn == "uni/tn-ansible_test/lDevVip-ansible_test_firewall1" + + - name: Add a new Graph SG1 at site level (normal mode) + cisco.mso.mso_schema_site_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG1 + site: '{{ mso_site | default("ansible_test") }}' + tenant: ansible_test + devices: + - name: ansible_test_firewall1 + state: present + register: nm_sg1 + + - name: Verify change_sg1 + assert: + that: + - nm_sg1 is changed + - nm_sg1.current.serviceGraphRef.serviceGraphName == "SG1" + - nm_sg1.current.serviceGraphRef.templateName == "Template1" + - nm_sg1.current.serviceNodes | length == 1 + - nm_sg1.current.serviceNodes.0.device.dn == "uni/tn-ansible_test/lDevVip-ansible_test_firewall1" + + - name: Add Graph SG1 at site level again + cisco.mso.mso_schema_site_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG1 + site: '{{ mso_site | default("ansible_test") }}' + tenant: ansible_test + devices: + - name: ansible_test_firewall1 + state: present + register: nm_sg1_again + + - name: Verify change_sg1 + assert: + that: + - nm_sg1_again is not changed + - nm_sg1_again.current.serviceGraphRef.serviceGraphName == "SG1" + - nm_sg1_again.current.serviceGraphRef.templateName == "Template1" + - nm_sg1_again.current.serviceNodes | length == 1 + - nm_sg1_again.current.serviceNodes.0.device.dn == "uni/tn-ansible_test/lDevVip-ansible_test_firewall1" + + - name: Change service graph SG1 at site level + cisco.mso.mso_schema_site_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG1 + site: '{{ mso_site | default("ansible_test") }}' + tenant: ansible_test + devices: + - name: ansible_test_firewall2 + state: present + register: change_sg1 + + - name: Verify change_sg1 + assert: + that: + - change_sg1 is changed + - change_sg1.current.serviceGraphRef.serviceGraphName == "SG1" + - change_sg1.current.serviceGraphRef.templateName == "Template1" + - change_sg1.current.serviceNodes | length == 1 + - change_sg1.current.serviceNodes.0.device.dn == "uni/tn-ansible_test/lDevVip-ansible_test_firewall2" + + - name: Add a new Graph SG2 at site level + cisco.mso.mso_schema_site_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG2 + site: '{{ mso_site | default("ansible_test") }}' + tenant: ansible_test + devices: + - name: ansible_test_firewall1 + - name: ansible_test_adc + state: present + register: sg2 + + - name: Verify sg2 + assert: + that: + - sg2 is changed + - sg2.current.serviceGraphRef.serviceGraphName == "SG2" + - sg2.current.serviceGraphRef.templateName == "Template1" + - sg2.current.serviceNodes | length == 2 + - sg2.current.serviceNodes.0.device.dn == "uni/tn-ansible_test/lDevVip-ansible_test_firewall1" + - sg2.current.serviceNodes.1.device.dn == "uni/tn-ansible_test/lDevVip-ansible_test_adc" + + - name: Add a new Graph SG3 at site level + cisco.mso.mso_schema_site_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG3 + site: '{{ mso_site | default("ansible_test") }}' + tenant: ansible_test + devices: + - name: ansible_test_firewall1 + - name: ansible_test_adc + - name: ansible_test_other + state: present + register: sg3 + + - name: Verify sg3 + assert: + that: + - sg3 is changed + - sg3.current.serviceGraphRef.serviceGraphName == "SG3" + - sg3.current.serviceGraphRef.templateName == "Template1" + - sg3.current.serviceNodes | length == 3 + - sg3.current.serviceNodes.0.device.dn == "uni/tn-ansible_test/lDevVip-ansible_test_firewall1" + - sg3.current.serviceNodes.1.device.dn == "uni/tn-ansible_test/lDevVip-ansible_test_adc" + - sg3.current.serviceNodes.2.device.dn == "uni/tn-ansible_test/lDevVip-ansible_test_other" + + - name: Add a new Graph SG4 at site level + cisco.mso.mso_schema_site_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG4 + site: '{{ mso_site | default("ansible_test") }}' + tenant: ansible_test + devices: + - name: ansible_test_other + - name: ansible_test_adc + - name: ansible_test_firewall1 + state: present + register: sg4 + + - name: Verify sg4 + assert: + that: + - sg4 is changed + - sg4.current.serviceGraphRef.serviceGraphName == "SG4" + - sg4.current.serviceGraphRef.templateName == "Template1" + - sg4.current.serviceNodes | length == 3 + - sg4.current.serviceNodes.0.device.dn == "uni/tn-ansible_test/lDevVip-ansible_test_other" + - sg4.current.serviceNodes.1.device.dn == "uni/tn-ansible_test/lDevVip-ansible_test_adc" + - sg4.current.serviceNodes.2.device.dn == "uni/tn-ansible_test/lDevVip-ansible_test_firewall1" + + - name: Change Graph SG4 at site level + cisco.mso.mso_schema_site_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG4 + site: '{{ mso_site | default("ansible_test") }}' + tenant: ansible_test + devices: + - name: ansible_test_other + - name: ansible_test_adc + - name: ansible_test_firewall2 + state: present + register: change1_sg4 + + - name: Verify change1_sg4 + assert: + that: + - change1_sg4 is changed + - change1_sg4.current.serviceGraphRef.serviceGraphName == "SG4" + - change1_sg4.current.serviceGraphRef.templateName == "Template1" + - change1_sg4.current.serviceNodes | length == 3 + - change1_sg4.current.serviceNodes.0.device.dn == "uni/tn-ansible_test/lDevVip-ansible_test_other" + - change1_sg4.current.serviceNodes.1.device.dn == "uni/tn-ansible_test/lDevVip-ansible_test_adc" + - change1_sg4.current.serviceNodes.2.device.dn == "uni/tn-ansible_test/lDevVip-ansible_test_firewall2" + + - name: Change Graph SG4 at site level + cisco.mso.mso_schema_site_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG4 + site: '{{ mso_site | default("ansible_test") }}' + tenant: ansible_test + devices: + - name: ansible_test_other + state: present + ignore_errors: yes + register: change2_sg4 + + - name: Verify change2_sg4 + assert: + that: + - change2_sg4 is not changed + - change2_sg4.msg == "Service Graph 'SG4' has '3' service node type(s) but '1' service node(s) were given for the service graph" + + - name: Change Graph SG4 at site level + cisco.mso.mso_schema_site_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG4 + site: '{{ mso_site | default("ansible_test") }}' + tenant: ansible_test + devices: + - name: ansible_test_adc + state: present + ignore_errors: yes + register: change3_sg4 + + - name: Verify change3_sg4 + assert: + that: + - change3_sg4 is not changed + - change3_sg4.msg == "Service Graph 'SG4' has '3' service node type(s) but '1' service node(s) were given for the service graph" + + - name: Change Graph SG4 at site level + cisco.mso.mso_schema_site_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG4 + site: '{{ mso_site | default("ansible_test") }}' + tenant: ansible_test + devices: + - name: ansible_test_firewall1 + state: present + ignore_errors: yes + register: change4_sg4 + + - name: Verify change4_sg4 + assert: + that: + - change4_sg4 is not changed + - change4_sg4.msg == "Service Graph 'SG4' has '3' service node type(s) but '1' service node(s) were given for the service graph" + + - name: Change Graph SG4 at site level + cisco.mso.mso_schema_site_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG4 + site: '{{ mso_site | default("ansible_test") }}' + tenant: ansible_test + devices: + - name: ansible_test_other + - name: ansible_test_adc + state: present + ignore_errors: yes + register: change5_sg4 + + - name: Verify change5_sg4 + assert: + that: + - change5_sg4 is not changed + - change5_sg4.msg == "Service Graph 'SG4' has '3' service node type(s) but '2' service node(s) were given for the service graph" + + - name: Change Graph SG4 at site level + cisco.mso.mso_schema_site_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG4 + site: '{{ mso_site | default("ansible_test") }}' + tenant: ansible_test + devices: + - name: ansible_test_other + - name: ansible_test_other + - name: ansible_test_adc + state: present + ignore_errors: yes + register: change6_sg4 + + - name: Verify change6_sg4 + assert: + that: + - change6_sg4 is not changed + - change6_sg4.msg == "Provided device 'ansible_test_other' of type 'ADC' does not exist." + + - name: Add Graph SG5 at site level + cisco.mso.mso_schema_site_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG5 + site: '{{ mso_site | default("ansible_test") }}' + tenant: ansible_test + devices: + - name: ansible_test_other + - name: ansible_test_firewall1 + - name: ansible_test_firewall1 + state: present + register: sg5 + + - name: Verify sg5 + assert: + that: + - sg5 is changed + - sg5.current.serviceGraphRef.serviceGraphName == "SG5" + - sg5.current.serviceGraphRef.templateName == "Template1" + - sg5.current.serviceNodes | length == 3 + - sg5.current.serviceNodes.0.device.dn == "uni/tn-ansible_test/lDevVip-ansible_test_other" + - sg5.current.serviceNodes.1.device.dn == "uni/tn-ansible_test/lDevVip-ansible_test_firewall1" + - sg5.current.serviceNodes.2.device.dn == "uni/tn-ansible_test/lDevVip-ansible_test_firewall1" + + - name: Add Graph SG6 at site level + cisco.mso.mso_schema_site_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG6 + site: '{{ mso_site | default("ansible_test") }}' + tenant: ansible_test + devices: + - name: ansible_test_other + - name: ansible_test_other + - name: ansible_test_other + state: present + register: sg6 + + - name: Verify sg6 + assert: + that: + - sg6 is changed + - sg6.current.serviceGraphRef.serviceGraphName == "SG6" + - sg6.current.serviceGraphRef.templateName == "Template1" + - sg6.current.serviceNodes | length == 3 + - sg6.current.serviceNodes.0.device.dn == "uni/tn-ansible_test/lDevVip-ansible_test_other" + - sg6.current.serviceNodes.1.device.dn == "uni/tn-ansible_test/lDevVip-ansible_test_other" + - sg6.current.serviceNodes.2.device.dn == "uni/tn-ansible_test/lDevVip-ansible_test_other" + + - name: Add Graph SG7 at site level + cisco.mso.mso_schema_site_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG7 + site: '{{ mso_site | default("ansible_test") }}' + tenant: ansible_test + devices: + - name: ansible_test_adc + - name: ansible_test_adc + state: present + register: sg7 + + - name: Verify sg7 + assert: + that: + - sg7 is changed + - sg7.current.serviceGraphRef.serviceGraphName == "SG7" + - sg7.current.serviceGraphRef.templateName == "Template1" + - sg7.current.serviceNodes | length == 2 + - sg7.current.serviceNodes.0.device.dn == "uni/tn-ansible_test/lDevVip-ansible_test_adc" + - sg7.current.serviceNodes.1.device.dn == "uni/tn-ansible_test/lDevVip-ansible_test_adc" + + - name: Query service graph SG at site level + cisco.mso.mso_schema_site_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG1 + site: '{{ mso_site | default("ansible_test") }}' + tenant: ansible_test + state: query + register: query_sg + + - name: Verify query_sg + assert: + that: + - query_sg is not changed + - query_sg.current.serviceGraphRef is match("/schemas/[0-9a-zA-Z]*/templates/Template1/serviceGraphs/SG1") + + - name: Query all service graphs at site level + cisco.mso.mso_schema_site_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + site: '{{ mso_site | default("ansible_test") }}' + tenant: ansible_test + state: query + register: query_all + + - name: Verify query_all + assert: + that: + - query_all is not changed + - query_all.current | length == 7 + + - name: Query non_existing service graph at site level + cisco.mso.mso_schema_site_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + site: '{{ mso_site | default("ansible_test") }}' + service_graph: non_existent + tenant: ansible_test + state: query + ignore_errors: yes + register: query_non_existing_sg + + - name: Verify query_non_existing_sg + assert: + that: + - query_non_existing_sg.msg == "Service Graph 'non_existent' not found" + + - name: Use non_existing schema + cisco.mso.mso_schema_site_service_graph: + <<: *mso_info + schema: non_existing_schema + template: Template1 + service_graph: SG + tenant: ansible_test + site: '{{ mso_site | default("ansible_test") }}' + state: query + ignore_errors: yes + register: query_non_existing_schema + + - name: Verify non_existing_schema + assert: + that: + - query_non_existing_schema is not changed + - query_non_existing_schema.msg == "Provided schema 'non_existing_schema' does not exist." + + - name: Use non_existing template + cisco.mso.mso_schema_site_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: non_existing_template + service_graph: SG + tenant: ansible_test + site: '{{ mso_site | default("ansible_test") }}' + state: query + ignore_errors: yes + register: query_non_existing_template + + - name: Verify query_non_existing_template + assert: + that: + - query_non_existing_template.msg == "Provided template 'non_existing_template' does not exist. Existing templates{{':'}} Template1, Template2" + + - name: Use non_existing_site_template + cisco.mso.mso_schema_site_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + service_graph: SG + template: Template2 + tenant: ansible_test + state: query + ignore_errors: yes + register: nm_non_existing_site_template + + - name: Verify cm_non_existing_site_template and nm_non_existing_site_template + assert: + that: + - nm_non_existing_site_template is not changed + - nm_non_existing_site_template.msg == "Provided site-template association 'ansible_test-Template2' does not exist." + + - name: Add site Service Graph to Template2 without any site association + cisco.mso.mso_schema_site_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + site: '{{ mso_site | default("ansible_test") }}' + template: Template1 + service_graph: SG1 + tenant: ansible_test + devices: + - name: ansible_test_firewall2 + state: present + ignore_errors: yes + register: nm_no_site_associated + + - name: Verify nm_no_site_associated + assert: + that: + - nm_no_site_associated is not changed + - nm_no_site_associated.msg == "No site associated with template 'Template1'. Associate the site with the template using mso_schema_site." + + - name: Remove service graph from site level(check mode) + cisco.mso.mso_schema_site_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG1 + site: '{{ mso_site | default("ansible_test") }}' + tenant: ansible_test + state: absent + register: rm_sg_cm + check_mode: yes + + - name: Verify rm_sg_cm + assert: + that: + - rm_sg_cm is changed + - rm_sg_cm.current == {} + - rm_sg_cm.previous.serviceGraphRef is match("/schemas/[0-9a-zA-Z]*/templates/Template1/serviceGraphs/SG1") + + - name: Remove service graph from site level (normal mode) + cisco.mso.mso_schema_site_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG1 + tenant: ansible_test + site: '{{ mso_site | default("ansible_test") }}' + state: absent + register: rm_sg + + - name: Verify rm_sg + assert: + that: + - rm_sg is changed + - rm_sg.current == {} + - rm_sg.previous.serviceGraphRef is match("/schemas/[0-9a-zA-Z]*/templates/Template1/serviceGraphs/SG1") + + - name: Remove service graph again + cisco.mso.mso_schema_site_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG1 + tenant: ansible_test + site: '{{ mso_site | default("ansible_test") }}' + state: absent + register: rm_sg_again + + - name: Verify rm_sg_again + assert: + that: + - rm_sg_again is not changed + - rm_sg_again.current == {} + - rm_sg_again.previous == {} + when: version.current.version is version('4.0', '<') # no change in NDO4.0 because site will already be present when template is defined diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_vrf_region/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_vrf_region/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_vrf_region/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_vrf_region/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_vrf_region/tasks/main.yml new file mode 100644 index 00000000..0ad3dba8 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_vrf_region/tasks/main.yml @@ -0,0 +1,588 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Cindy Zhao (@cizhao) <cizhao@cisco.com> +# Copyright: (c) 2021, Anvitha Jain (@anvitha-jain) <anvjain@cisco.com> +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +# 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") }}' + sites: "['aws_{{ mso_site | default(\"ansible_test\") }}', + 'azure_{{ mso_site | default(\"ansible_test\") }}', + '{{ mso_site | default(\"ansible_test\") }}']" + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Ensure aws site exists + mso_site: + <<: *mso_info + site: 'aws_{{ mso_site | default("ansible_test") }}' + apic_username: '{{ aws_apic_username }}' + apic_password: '{{ aws_apic_password }}' + apic_site_id: '{{ aws_site_id | default(102) }}' + urls: + - https://{{ aws_apic_hostname }} + state: present + +- name: Ensure azure site exists + mso_site: + <<: *mso_info + site: 'azure_{{ mso_site | default("ansible_test") }}' + apic_username: '{{ azure_apic_username }}' + apic_password: '{{ azure_apic_password }}' + apic_site_id: '{{ azure_site_id | default(103) }}' + urls: + - https://{{ azure_apic_hostname }} + state: present + +- name: Remove Schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Ensure sites removed from tenant ansible_test + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: '{{ item }}' + state: absent + loop: + - '{{ mso_site | default("ansible_test") }}' + - 'aws_{{ mso_site | default("ansible_test") }}' + - 'azure_{{ mso_site | default("ansible_test") }}' + +- name: Ensure tenant ansible_test exist + mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + state: present + +- name: Ensure AWS site is present under tenant ansible_test + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'aws_{{ mso_site | default("ansible_test") }}' + cloud_account: '000000000000' + aws_access_key: 1 + secret_key: 0 + state: present + +- name: Ensure Azure site is present under tenant ansible_test + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'azure_{{ mso_site | default("ansible_test") }}' + cloud_account: uni/tn-ansible_test/act-[9]-vendor-azure + state: present + +- name: Ensure schema 1 with Template 1 and 2 exists + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: '{{ item }}' + state: present + loop: + - Template 1 + - Template 2 + +- name: Ensure schema 2 with Template 3 exists + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template 3 + state: present + +- name: Ensure VRF1 exists + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF1 + state: present + +- name: Add region and cidr in VRF1 at AWS site level + mso_schema_site_vrf_region_cidr: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + cidr: 10.0.0.0/16 + primary: true + state: present + register: aws_add_region_cidr + +- name: Add region and cidr in VRF1 at Azure site level + mso_schema_site_vrf_region_cidr: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'azure_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + cidr: 10.0.0.0/16 + primary: true + state: present + register: azure_add_region_cidr + +- name: Add another region and cidr in VRF1 at AWS site level + mso_schema_site_vrf_region_cidr: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-east-1 + cidr: 10.10.0.0/16 + primary: true + state: present + register: aws_add_another_region_cidr + +- name: Add another region and cidr in VRF1 at Azure site level + mso_schema_site_vrf_region_cidr: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'azure_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-east-1 + cidr: 10.10.0.0/16 + primary: true + state: present + register: azure_add_another_region_cidr + +# Execute context underlay parameters only when when MSO version >= 3.3 +- name: Execute tasks only for MSO version >= 3.3 + when: version.current.version is version('3.3', '>=') + block: + - name: Ensure VRF2 exists + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF2 + state: present + + - name: Add region and cidr in VRF2 at Azure site level + mso_schema_site_vrf_region_cidr: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'azure_{{ mso_site | default("ansible_test") }}' + vrf: VRF2 + region: westus + cidr: 10.10.0.0/16 + primary: true + state: present + register: azure_add_another_region_cidr + + - name: Add region and cidr in VRF2 at AWS site level + mso_schema_site_vrf_region_cidr: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF2 + region: westus + cidr: 10.10.0.0/16 + primary: true + state: present + register: azure_add_another_region_cidr + + - name: Add context underlay parameters in VRF1 at Azure site level + mso_schema_site_vrf_region: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'azure_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + container_overlay: true + underlay_context_profile: + vrf: VRF2 + region: westus + state: present + register: azure_add_context_underlay + + - name: Add context underlay parameters in VRF1 at AWS site level + mso_schema_site_vrf_region: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-east-1 + container_overlay: true + underlay_context_profile: + vrf: VRF2 + region: westus + state: present + register: aws_add_context_underlay + + - name: Verify add_context_underlay + assert: + that: + - azure_add_context_underlay is changed + - azure_add_context_underlay.current.contextProfileType == "container-overlay" + - aws_add_context_underlay is changed + - aws_add_context_underlay.current.contextProfileType == "container-overlay" + + - name: Get Validation status + mso_schema_validate: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + state: query + register: query_validate + + - name: Verify query_validate + assert: + that: + - query_validate is not changed + + - name: Verify query_validate result < 4.0 + assert: + that: + - query_validate.current.result == "true" + when: version.current.version is version('4.0', '<') + + - name: Verify query_validate result => 4.0 + assert: + that: + - query_validate.current.result == true + when: version.current.version is version('4.0', '>=') + +- name: Query all aws regions + mso_schema_site_vrf_region: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + state: query + register: aws_query_all + +- name: Query all azure regions + mso_schema_site_vrf_region: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'azure_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + state: query + register: azure_query_all + +- name: Query specific aws region + mso_schema_site_vrf_region: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + state: query + register: aws_query_region + +- name: Query specific azure region + mso_schema_site_vrf_region: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'azure_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + state: query + register: azure_query_region + +- name: Verify query + assert: + that: + - aws_query_all is not changed + - azure_query_all is not changed + - aws_query_region is not changed + - azure_query_region is not changed + - aws_query_all.current | length == 2 + - azure_query_all.current | length == 2 + - aws_query_region.current.name == "us-west-1" + - aws_query_region.current.cidrs.0.ip == "10.0.0.0/16" + - aws_query_region.current.cidrs.0.primary == true + - aws_query_region.current.cidrs.0.subnets == [] + - azure_query_region.current.name == "us-west-1" + - azure_query_region.current.cidrs.0.ip == "10.0.0.0/16" + - azure_query_region.current.cidrs.0.primary == true + - azure_query_region.current.cidrs.0.subnets == [] + +- name: Remove aws VRF region (check mode) + mso_schema_site_vrf_region: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-east-1 + state: absent + check_mode: yes + register: cm_rm_aws_region + +- name: Remove aws VRF region (normal mode) + mso_schema_site_vrf_region: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-east-1 + state: absent + register: nm_rm_aws_region + +- name: Remove azure VRF region (check mode) + mso_schema_site_vrf_region: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'azure_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + state: absent + check_mode: yes + register: cm_rm_azure_region + +- name: Remove azure VRF region (normal mode) + mso_schema_site_vrf_region: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'azure_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + state: absent + register: nm_rm_azure_region + +- name: Verify deletion + assert: + that: + - cm_rm_aws_region is changed + - nm_rm_aws_region is changed + - cm_rm_azure_region is changed + - nm_rm_azure_region is changed + - cm_rm_aws_region.previous == nm_rm_aws_region.previous + - cm_rm_azure_region.previous == nm_rm_azure_region.previous + - cm_rm_aws_region.current == nm_rm_aws_region.current == {} + - cm_rm_azure_region.current == nm_rm_azure_region.current == {} + - cm_rm_aws_region.previous.name == nm_rm_aws_region.previous.name == "us-east-1" + - cm_rm_azure_region.previous.name == nm_rm_azure_region.previous.name == "us-west-1" + +- name: Add VPN Gateway Router to Region for AWS + cisco.mso.mso_schema_site_vrf_region: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + vpn_gateway_router: true + state: present + when: version.current.version is version('3.0.0a', '>=') + register: add_vpn_gateway_router_aws + +- name: Add VPN Gateway Router to Region for Azure + cisco.mso.mso_schema_site_vrf_region: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'azure_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-east-1 + vpn_gateway_router: true + state: present + when: version.current.version is version('3.0.0a', '>=') + register: add_vpn_gateway_router_azure + +- name: Verify adding VPN Gateway Router + assert: + that: + - add_vpn_gateway_router_aws.current.isVpnGatewayRouter == add_vpn_gateway_router_azure.current.isVpnGatewayRouter == true + when: version.current.version is version('3.0.0a', '>=') + +- name: Remove VPN Gateway Router at Region for AWS (check mode) + cisco.mso.mso_schema_site_vrf_region: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + vpn_gateway_router: false + state: present + check_mode: yes + when: version.current.version is version('3.0.0a', '>=') + register: cm_rm_vpn_gateway_router_aws + +- name: Remove VPN Gateway Router at Region for AWS (normal mode) + cisco.mso.mso_schema_site_vrf_region: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + vpn_gateway_router: false + state: present + when: version.current.version is version('3.0.0a', '>=') + register: nm_rm_vpn_gateway_router_aws + +- name: Remove VPN Gateway Router at Region for Azure (check mode) + cisco.mso.mso_schema_site_vrf_region: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'azure_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-east-1 + vpn_gateway_router: false + state: present + check_mode: yes + when: version.current.version is version('3.0.0a', '>=') + register: cm_rm_vpn_gateway_router_azure + +- name: Remove VPN Gateway Router at Region for Azure (normal mode) + cisco.mso.mso_schema_site_vrf_region: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'azure_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-east-1 + vpn_gateway_router: false + state: present + when: version.current.version is version('3.0.0a', '>=') + register: nm_rm_vpn_gateway_router_azure + +- name: Verify removing VPN Gateway Router + assert: + that: + - cm_rm_vpn_gateway_router_aws is changed + - nm_rm_vpn_gateway_router_aws is changed + - cm_rm_vpn_gateway_router_azure is changed + - nm_rm_vpn_gateway_router_azure is changed + - cm_rm_vpn_gateway_router_aws.previous.isVpnGatewayRouter == nm_rm_vpn_gateway_router_aws.previous.isVpnGatewayRouter == true + - cm_rm_vpn_gateway_router_azure.previous.isVpnGatewayRouter == nm_rm_vpn_gateway_router_azure.previous.isVpnGatewayRouter == true + - cm_rm_vpn_gateway_router_aws.current.isVpnGatewayRouter == nm_rm_vpn_gateway_router_aws.current.isVpnGatewayRouter == false + - cm_rm_vpn_gateway_router_azure.current.isVpnGatewayRouter == nm_rm_vpn_gateway_router_azure.current.isVpnGatewayRouter == false + when: version.current.version is version('3.0.0a', '>=') + +- name: Use non_existing schema + mso_schema_site_vrf_region: + <<: *mso_info + schema: non_existing + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + state: query + register: non_existing_schema + ignore_errors: yes + +- name: Use non_existing site + mso_schema_site_vrf_region: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: non_existing + vrf: VRF1 + region: us-west-1 + state: query + register: non_existing_site + ignore_errors: yes + +- name: Use non_existing site/template association + mso_schema_site_vrf_region: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + state: query + register: non_existing_site_template + ignore_errors: yes + +- name: Use non_existing VRF + mso_schema_site_vrf_region: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: non_existing + region: us-west-1 + state: query + register: non_existing_vrf + ignore_errors: yes + +- name: Use non_existing region + mso_schema_site_vrf_region: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: non_existing + state: query + register: non_existing_region + ignore_errors: yes + +- name: Verify non_existing + assert: + that: + - non_existing_schema.msg == "Provided schema 'non_existing' does not exist." + - non_existing_site.msg == "Site 'non_existing' is not a valid site name." + - non_existing_site_template.msg == "Provided site-template association 'aws_ansible_test-Template2' does not exist." + - non_existing_region.msg == "Region 'non_existing' not found" + +- name: Verify non_existing (version < 3.3) + assert: + that: + - non_existing_vrf.msg == "Provided vrf 'non_existing' does not exist. Existing vrfs{{':'}} VRF1" + when: version.current.version is version('3.3', '<') + +- name: Verify non_existing (version >= 3.3) + assert: + that: + - non_existing_vrf.msg == "Provided vrf 'non_existing' does not exist. Existing vrfs{{':'}} VRF1, VRF2" + when: version.current.version is version('3.3', '>=') + +- name: Delete non_existing region + mso_schema_site_vrf_region: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: non_existing + state: absent + register: rm_non_existing_region + +- name: Verify rm_non_existing_region + assert: + that: + - rm_non_existing_region is not changed + - rm_non_existing_region.previous == rm_non_existing_region.current == {}
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_vrf_region_cidr/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_vrf_region_cidr/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_vrf_region_cidr/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_vrf_region_cidr/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_vrf_region_cidr/tasks/main.yml new file mode 100644 index 00000000..b0dd863c --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_vrf_region_cidr/tasks/main.yml @@ -0,0 +1,721 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Lionel Hercot (@lhercot) <lhercot@cisco.com> +# Copyright: (c) 2020, Shreyas Srish (@shrsr) <ssrish@cisco.com> (based on mso_schema_anp_epg_domain) +# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> (based on mso_site test case) + + +# 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") }}' + sites: "['aws_{{ mso_site | default(\"ansible_test\") }}', + 'azure_{{ mso_site | default(\"ansible_test\") }}', + '{{ mso_site | default(\"ansible_test\") }}']" + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Ensure site exists + mso_site: + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + apic_username: '{{ apic_username }}' + apic_password: '{{ apic_password }}' + apic_site_id: '{{ apic_site_id | default(101) }}' + urls: + - https://{{ apic_hostname }} + state: present + +- name: Ensure site exists + mso_site: + <<: *mso_info + site: 'aws_{{ mso_site | default("ansible_test") }}' + apic_username: '{{ aws_apic_username }}' + apic_password: '{{ aws_apic_password }}' + apic_site_id: '{{ aws_site_id | default(102) }}' + urls: + - https://{{ aws_apic_hostname }} + state: present + +- name: Ensure site exists + mso_site: + <<: *mso_info + site: 'azure_{{ mso_site | default("ansible_test") }}' + apic_username: '{{ azure_apic_username }}' + apic_password: '{{ azure_apic_password }}' + apic_site_id: '{{ azure_site_id | default(103) }}' + urls: + - https://{{ azure_apic_hostname }} + state: present + +- name: Remove Schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Ensure sites removed from tenant ansible_test + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: '{{ item }}' + state: absent + loop: + - '{{ mso_site | default("ansible_test") }}' + - 'aws_{{ mso_site | default("ansible_test") }}' + - 'azure_{{ mso_site | default("ansible_test") }}' + +- name: Ensure tenant ansible_test exist + mso_tenant: + <<: *mso_info + tenant: ansible_test + sites: + - '{{ mso_site | default("ansible_test") }}' + users: + - '{{ mso_username }}' + state: present + +- name: Ensure AWS site is present under tenant ansible_test + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'aws_{{ mso_site | default("ansible_test") }}' + cloud_account: '000000000000' + aws_access_key: 1 + secret_key: 0 + state: present + +- name: Ensure Azure site is present under tenant ansible_test + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'azure_{{ mso_site | default("ansible_test") }}' + cloud_account: uni/tn-ansible_test/act-[9]-vendor-azure + state: present + +- name: Ensure schema 1 with Template 1 and 2 exists + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: '{{ item }}' + state: present + loop: + - Template 1 + - Template 2 + +- name: Ensure schema 2 with Template 3 exists + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template 3 + state: present + +- name: Add physical site to Template 1 + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + state: present + +- name: Ensure VRF1 exists + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ item.schema }}' + template: '{{ item.template }}' + vrf: VRF1 + state: present + loop: + - { schema: '{{ mso_schema | default("ansible_test") }}', template: 'Template 1' } + - { schema: '{{ mso_schema | default("ansible_test") }}', template: 'Template 2' } + - { schema: '{{ mso_schema | default("ansible_test") }}_2', template: 'Template 3' } + +- name: Ensure VRF2 exists + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF2 + state: present + when: version.current.version is version('3', '<') + +- name: Ensure VRF1 exists at Site level for the physical site + mso_schema_site_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: '{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + state: present + +# ADD SUBNET +- name: Add a new CIDR in VRF1 at AWS site level (check mode) + mso_schema_site_vrf_region_cidr: &mso_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + cidr: 10.0.0.0/16 + primary: true + state: present + check_mode: yes + register: cm_add_cidr + +- name: Verify cm_add_cidr + assert: + that: + - cm_add_cidr is changed + - cm_add_cidr.previous == {} + - cm_add_cidr.current.ip == '10.0.0.0/16' + - cm_add_cidr.current.primary == true + +- name: Add a new CIDR in VRF1 at AWS site level (normal mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_present + register: nm_add_cidr + +- name: Verify nm_add_cidr + assert: + that: + - nm_add_cidr is changed + - nm_add_cidr.previous == {} + - nm_add_cidr.current.ip == '10.0.0.0/16' + - nm_add_cidr.current.primary == true + +- name: Add same CIDR in VRF1 at AWS site level (check mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_present + register: cm_add_cidr_again + +- name: Verify cm_add_cidr_again + assert: + that: + - cm_add_cidr_again is not changed + - cm_add_cidr_again.current.ip == cm_add_cidr_again.previous.ip == '10.0.0.0/16' + - cm_add_cidr_again.current.primary == cm_add_cidr_again.previous.primary == true + +- name: Add same CIDR in VRF1 at AWS site level (normal mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_present + register: nm_add_cidr_again + +- name: Verify nm_add_cidr_again + assert: + that: + - nm_add_cidr_again is not changed + - nm_add_cidr_again.current.ip == nm_add_cidr_again.previous.ip == '10.0.0.0/16' + - nm_add_cidr_again.current.primary == nm_add_cidr_again.previous.primary == true + +- name: Add a CIDR in VRF1 at Azure site level (check mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_present + site: 'azure_{{ mso_site | default("ansible_test") }}' + region: westus + cidr: 10.1.0.0/16 + primary: true + check_mode: yes + register: cm_add_cidr_2 + +- name: Verify cm_add_cidr_2 + assert: + that: + - cm_add_cidr_2 is changed + - cm_add_cidr_2.previous == {} + - cm_add_cidr_2.current.ip == '10.1.0.0/16' + - cm_add_cidr_2.current.primary == true + +- name: Add a CIDR in VRF1 at Azure site level (normal mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_present + site: 'azure_{{ mso_site | default("ansible_test") }}' + region: westus + cidr: 10.1.0.0/16 + primary: true + register: nm_add_cidr_2 + +- name: Verify nm_add_cidr_2 + assert: + that: + - nm_add_cidr_2 is changed + - nm_add_cidr_2.previous == {} + - nm_add_cidr_2.current.ip == '10.1.0.0/16' + - nm_add_cidr_2.current.primary == true + +- name: Add a second CIDR in VRF1 at AWS site level (check mode) + mso_schema_site_vrf_region_cidr: &mso_present_2 + <<: *mso_present + site: 'aws_{{ mso_site | default("ansible_test") }}' + region: us-west-1 + cidr: 10.2.0.0/16 + primary: false + check_mode: yes + register: cm_add_cidr_3 + +- name: Verify cm_add_cidr_3 + assert: + that: + - cm_add_cidr_3 is changed + - cm_add_cidr_3.previous == {} + - cm_add_cidr_3.current.ip == '10.2.0.0/16' + - cm_add_cidr_3.current.primary == false + +- name: Add a second CIDR in VRF1 at AWS site level (normal mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_present_2 + register: nm_add_cidr_3 + +- name: Verify nm_add_cidr_3 + assert: + that: + - nm_add_cidr_3 is changed + - nm_add_cidr_3.previous == {} + - nm_add_cidr_3.current.ip == '10.2.0.0/16' + - nm_add_cidr_3.current.primary == false + +- name: Add a second CIDR in VRF1 at Azure site level (check mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_present + site: 'azure_{{ mso_site | default("ansible_test") }}' + region: westus + cidr: 10.3.0.0/16 + primary: false + check_mode: yes + register: cm_add_cidr_4 + +- name: Verify cm_add_cidr_4 + assert: + that: + - cm_add_cidr_4 is changed + - cm_add_cidr_4.previous == {} + - cm_add_cidr_4.current.ip == '10.3.0.0/16' + - cm_add_cidr_4.current.primary == false + +- name: Add a second CIDR in VRF1 at Azure site level (normal mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_present + site: 'azure_{{ mso_site | default("ansible_test") }}' + region: westus + cidr: 10.3.0.0/16 + primary: false + register: nm_add_cidr_4 + +- name: Verify nm_add_cidr_4 + assert: + that: + - nm_add_cidr_4 is changed + - nm_add_cidr_4.previous == {} + - nm_add_cidr_4.current.ip == '10.3.0.0/16' + - nm_add_cidr_4.current.primary == false + +# QUERY CIDR +- name: Query CIDR in VRF1 at AWS site level (check mode) + mso_schema_site_vrf_region_cidr: &mso_query + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + cidr: 10.0.0.0/16 + state: query + check_mode: yes + register: cm_query_cidr + +- name: Verify cm_query_cidr + assert: + that: + - cm_query_cidr is not changed + - cm_query_cidr.current.ip == '10.0.0.0/16' + - cm_query_cidr.current.primary == true + +- name: Query CIDR in VRF1 at AWS site level (normal mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_query + register: nm_query_cidr + +- name: Query CIDR in VRF1 at Azure site level (check mode) + mso_schema_site_vrf_region_cidr: &mso_query_2 + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'azure_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: westus + cidr: 10.1.0.0/16 + state: query + check_mode: yes + register: cm_query_cidr_2 + +- name: Verify cm_query_cidr_2 + assert: + that: + - cm_query_cidr_2 is not changed + - cm_query_cidr_2.current.ip == '10.1.0.0/16' + - cm_query_cidr_2.current.primary == true + +- name: Query CIDR in VRF1 at Azure site level (normal mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_query_2 + register: nm_query_cidr_2 + +- name: Verify nm_query_cidr_2 + assert: + that: + - nm_query_cidr_2 is not changed + - nm_query_cidr_2.current.ip == '10.1.0.0/16' + - nm_query_cidr_2.current.primary == true + +# QUERY ALL CIDR +- name: Query all CIDR in VRF1 at AWS site level (check mode) + mso_schema_site_vrf_region_cidr: &mso_query_all + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + state: query + check_mode: yes + register: cm_query_cidr_all_aws + +- name: Query CIDR in VRF1 at Azure site level (check mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_query_all + site: 'azure_{{ mso_site | default("ansible_test") }}' + region: westus + state: query + check_mode: yes + register: cm_query_cidr_all_azure + +- name: Verify cm_query_cidr_all_aws and cm_query_cidr_all_azure + assert: + that: + - cm_query_cidr_all_aws is not changed + - cm_query_cidr_all_aws.current[0].ip == '10.0.0.0/16' + - cm_query_cidr_all_aws.current[0].primary == true + - cm_query_cidr_all_aws.current[1].ip == '10.2.0.0/16' + - cm_query_cidr_all_aws.current[1].primary == false + - cm_query_cidr_all_azure is not changed + - cm_query_cidr_all_azure.current[0].ip == '10.1.0.0/16' + - cm_query_cidr_all_azure.current[0].primary == true + - cm_query_cidr_all_azure.current[1].ip == '10.3.0.0/16' + - cm_query_cidr_all_azure.current[1].primary == false + +- name: Query CIDR in VRF1 at AWS site level (normal mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_query_all + register: nm_query_cidr_all_aws + +- name: Query CIDR in VRF1 at Azure site level (normal mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_query_all + site: 'azure_{{ mso_site | default("ansible_test") }}' + region: westus + register: nm_query_cidr_all_azure + +- name: Verify nm_query_cidr_all_aws and nm_query_cidr_all_azure + assert: + that: + - nm_query_cidr_all_aws is not changed + - nm_query_cidr_all_aws.current[0].ip == '10.0.0.0/16' + - nm_query_cidr_all_aws.current[0].primary == true + - nm_query_cidr_all_aws.current[1].ip == '10.2.0.0/16' + - nm_query_cidr_all_aws.current[1].primary == false + - nm_query_cidr_all_azure is not changed + - nm_query_cidr_all_azure.current[0].ip == '10.1.0.0/16' + - nm_query_cidr_all_azure.current[0].primary == true + - nm_query_cidr_all_azure.current[1].ip == '10.3.0.0/16' + - nm_query_cidr_all_azure.current[1].primary == false + +- name: Query CIDR in VRF2 (not present a Site level) for AWS Site (normal mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_query_all + vrf: VRF2 + ignore_errors: yes + register: nm_query_cidr_all_aws_2 + +- name: Query CIDR in VRF1 (with VRF present a Site level) for Physical Site (normal mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_query_all + site: '{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + ignore_errors: yes + register: nm_query_cidr_all_aws_3 + +- name: Verify nm_query_cidr_all_aws_2 and nm_query_cidr_all_aws_3 + assert: + that: + - nm_query_cidr_all_aws_2.msg == "Provided vrf 'VRF2' does not exist at site level." + - nm_query_cidr_all_aws_3.msg == "Provided region 'us-west-1' does not exist. Existing regions{{':'}} " + when: version.current.version is version('3', '<') + +# REMOVE CIDR +- name: Remove CIDR (check_mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_present_2 + state: absent + check_mode: yes + register: cm_remove_cidr + +- name: Verify cm_remove_cidr + assert: + that: + - cm_remove_cidr is changed + - cm_remove_cidr.current == {} + +- name: Remove CIDR (normal mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_present_2 + state: absent + register: nm_remove_cidr + +- name: Verify nm_remove_cidr + assert: + that: + - nm_remove_cidr is changed + - nm_remove_cidr.current == {} + +- name: Remove CIDR again (check_mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_present_2 + state: absent + check_mode: yes + register: cm_remove_cidr_again + +- name: Verify cm_remove_cidr_again + assert: + that: + - cm_remove_cidr_again is not changed + - cm_remove_cidr_again.current == {} + +- name: Remove CIDR again (normal mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_present_2 + state: absent + register: nm_remove_cidr_again + +- name: Verify nm_remove_cidr_again + assert: + that: + - nm_remove_cidr_again is not changed + - nm_remove_cidr_again.current == {} + +# QUERY NON-EXISTING CIDR +- name: Query non-existing CIDR (check_mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_query + cidr: non_existing_cidr + check_mode: yes + ignore_errors: yes + register: cm_query_non_cidr + +- name: Query non-existing CIDR (normal mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_query + cidr: non_existing_cidr + ignore_errors: yes + register: nm_query_non_cidr + +- name: Verify query_non_cidr + assert: + that: + - cm_query_non_cidr is not changed + - nm_query_non_cidr is not changed + - cm_query_non_cidr == nm_query_non_cidr + - cm_query_non_cidr.msg == nm_query_non_cidr.msg == "CIDR IP 'non_existing_cidr' not found" + +# QUERY NON-EXISTING region +- name: Query non-existing region (check_mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_query + region: non_existing_region + check_mode: yes + ignore_errors: yes + register: cm_query_non_region + +- name: Query non-existing region (normal mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_query + region: non_existing_region + ignore_errors: yes + register: nm_query_non_region + +- name: Verify query_non_region + assert: + that: + - cm_query_non_region is not changed + - nm_query_non_region is not changed + - cm_query_non_region == nm_query_non_region + - cm_query_non_region.msg == nm_query_non_region.msg == "Provided region 'non_existing_region' does not exist. Existing regions{{':'}} us-west-1" + +# QUERY NON-EXISTING VRF +- name: Query non-existing VRF (check_mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_query + vrf: non_existing_vrf + check_mode: yes + ignore_errors: yes + register: cm_query_non_vrf + +- name: Query non-existing VRF (normal mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_query + vrf: non_existing_vrf + ignore_errors: yes + register: nm_query_non_vrf + +- name: Verify query_non_vrf + assert: + that: + - cm_query_non_vrf is not changed + - nm_query_non_vrf is not changed + - cm_query_non_vrf == nm_query_non_vrf + +- name: Verify query_non_vrf (version < 3.0) + assert: + that: + - cm_query_non_vrf.msg == nm_query_non_vrf.msg == "Provided vrf 'non_existing_vrf' does not exist. Existing vrfs{{':'}} VRF1, VRF2" + when: version.current.version is version('3', '<') + +# USE A NON-EXISTING STATE +- name: Non-existing state for site cidr (check_mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_query + state: non-existing-state + check_mode: yes + ignore_errors: yes + register: cm_non_existing_state + +- name: Non-existing state for site cidr (normal_mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_query + state: non-existing-state + ignore_errors: yes + register: nm_non_existing_state + +- name: Verify non_existing_state + assert: + that: + - cm_non_existing_state is not changed + - nm_non_existing_state is not changed + - cm_non_existing_state == nm_non_existing_state + - cm_non_existing_state.msg == nm_non_existing_state.msg == "value of state must be one of{{':'}} absent, present, query, got{{':'}} non-existing-state" + +# USE A NON-EXISTING SCHEMA +- name: Non-existing schema for site cidr (check_mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_query + schema: non-existing-schema + check_mode: yes + ignore_errors: yes + register: cm_non_existing_schema + +- name: Non-existing schema for site cidr (normal_mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_query + schema: non-existing-schema + ignore_errors: yes + register: nm_non_existing_schema + +- name: Verify non_existing_schema + assert: + that: + - cm_non_existing_schema is not changed + - nm_non_existing_schema is not changed + - cm_non_existing_schema == nm_non_existing_schema + - cm_non_existing_schema.msg == nm_non_existing_schema.msg == "Provided schema 'non-existing-schema' does not exist." + +# USE A NON-EXISTING TEMPLATE +- name: Non-existing template for site cidr (check_mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_query + template: non-existing-template + check_mode: yes + ignore_errors: yes + register: cm_non_existing_template + +- name: Non-existing template for site cidr (normal_mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_query + template: non-existing-template + ignore_errors: yes + register: nm_non_existing_template + +- name: Verify non_existing_template + assert: + that: + - cm_non_existing_template is not changed + - nm_non_existing_template is not changed + - cm_non_existing_template == nm_non_existing_template + - cm_non_existing_template.msg == nm_non_existing_template.msg == "Provided template 'non-existing-template' does not exist. Existing templates{{':'}} Template1, Template2" + +# USE A NON-ASSOCIATED TEMPLATE +- name: Non-associated template for site cidr (check_mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_query + template: Template 2 + check_mode: yes + ignore_errors: yes + register: cm_non_associated_template + +- name: Non-associated template for site cidr (normal_mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_query + template: Template 2 + ignore_errors: yes + register: nm_non_associated_template + +- name: Verify non_associated_template + assert: + that: + - cm_non_associated_template is not changed + - nm_non_associated_template is not changed + - cm_non_associated_template == nm_non_associated_template + - cm_non_associated_template.msg == "Provided site-template association 'aws_{{ mso_site | default("ansible_test") }}-Template2' does not exist." + - nm_non_associated_template.msg == "Provided site-template association 'aws_{{ mso_site | default("ansible_test") }}-Template2' does not exist." + +# USE A TEMPLATE WITHOUT ANY SITE +- name: Add site VRF region cidr to Schema 2 Template 3 without any site associated (check mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_present + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + check_mode: yes + register: cm_no_site_associated + +- name: Add site VRF region cidr to Template 3 without any site associated (normal mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_present + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + register: nm_no_site_associated + +- name: Verify cm_no_site_associated and nm_no_site_associated + assert: + that: + - cm_no_site_associated is changed + - nm_no_site_associated is changed
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_vrf_region_cidr_subnet/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_vrf_region_cidr_subnet/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_vrf_region_cidr_subnet/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_vrf_region_cidr_subnet/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_vrf_region_cidr_subnet/tasks/main.yml new file mode 100644 index 00000000..4cc498bf --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_vrf_region_cidr_subnet/tasks/main.yml @@ -0,0 +1,886 @@ +# Test code for the MSO modules +# Copyright: (c) 2021, Anvitha Jain (@anvitha-jain) <anvjain@cisco.com> +# Copyright: (c) 2020, Lionel Hercot (@lhercot) <lhercot@cisco.com> +# Copyright: (c) 2020, Shreyas Srish (@shrsr) <ssrish@cisco.com> (based on mso_schema_anp_epg_domain) +# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> (based on mso_site test case) + + +# 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") }}' + sites: "[ { 'site': 'aws_{{ mso_site | default(\"ansible_test\") }}', 'region': 'us-west-1', 'cidr': '10.0.0.0/16'}, + { 'site': 'azure_{{ mso_site | default(\"ansible_test\") }}', 'region': 'westus', 'cidr': '10.1.0.0/16'}]" + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Ensure site exists + mso_site: + <<: *mso_info + site: 'aws_{{ mso_site | default("ansible_test") }}' + apic_username: '{{ aws_apic_username }}' + apic_password: '{{ aws_apic_password }}' + apic_site_id: '{{ aws_site_id | default(102) }}' + urls: + - https://{{ aws_apic_hostname }} + state: present + +- name: Ensure site exists + mso_site: + <<: *mso_info + site: 'azure_{{ mso_site | default("ansible_test") }}' + apic_username: '{{ azure_apic_username }}' + apic_password: '{{ azure_apic_password }}' + apic_site_id: '{{ azure_site_id | default(103) }}' + urls: + - https://{{ azure_apic_hostname }} + state: present + +- name: Remove Schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Ensure sites removed from tenant ansible_test + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: '{{ item }}' + state: absent + loop: + - '{{ mso_site | default("ansible_test") }}' + - 'aws_{{ mso_site | default("ansible_test") }}' + - 'azure_{{ mso_site | default("ansible_test") }}' + +- name: Ensure tenant ansible_test exist + mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + state: present + +- name: Ensure AWS site is present under tenant ansible_test + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'aws_{{ mso_site | default("ansible_test") }}' + cloud_account: '000000000000' + aws_access_key: 1 + secret_key: 0 + state: present + +- name: Ensure Azure site is present under tenant ansible_test + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'azure_{{ mso_site | default("ansible_test") }}' + cloud_account: uni/tn-ansible_test/act-[9]-vendor-azure + state: present + +- name: Ensure schema 1 with Template 1 and 2 exists + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: '{{ item }}' + state: present + loop: + - Template 1 + - Template 2 + +- name: Ensure schema 2 with Template 3 exists + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template 3 + state: present + +- name: Add a new sites to a Template 1 + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ item.site }}' + template: Template 1 + state: present + loop: '{{ sites }}' + when: version.current.version is version('3', '<') + +- name: Ensure VRF1 exists + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF1 + state: present + +- name: Ensure region for VRF1 at site level exists + mso_schema_site_vrf_region_cidr: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: '{{ item.site }}' + vrf: VRF1 + region: '{{ item.region }}' + cidr: '{{ item.cidr }}' + state: present + loop: '{{ sites }}' + + +# ADD SUBNET +- name: Add a new subnet to AWS CIDR in VRF1 at site level (check mode) + mso_schema_site_vrf_region_cidr_subnet: &mso_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + cidr: 10.0.0.0/16 + subnet: 10.0.0.0/24 + zone: us-west-1a + state: present + check_mode: yes + register: cm_add_subnet + +- name: Verify cm_add_subnet + assert: + that: + - cm_add_subnet is changed + - cm_add_subnet.previous == {} + - cm_add_subnet.current.ip == '10.0.0.0/24' + - cm_add_subnet.current.zone == 'us-west-1a' + +- name: Add a new subnet to AWS CIDR in VRF1 at site level (normal mode) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_present + register: nm_add_subnet + +- name: Verify nm_add_subnet + assert: + that: + - nm_add_subnet is changed + - nm_add_subnet.previous == {} + - nm_add_subnet.current.ip == '10.0.0.0/24' + - nm_add_subnet.current.zone == 'us-west-1a' + +- name: Add same subnet again to AWS CIDR in VRF1 at site level (check mode) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_present + register: cm_add_subnet_again + +- name: Verify cm_add_subnet_again + assert: + that: + - cm_add_subnet_again is not changed + - cm_add_subnet_again.current.ip == cm_add_subnet_again.previous.ip == '10.0.0.0/24' + - cm_add_subnet_again.current.zone == cm_add_subnet_again.previous.zone == 'us-west-1a' + +- name: Add same subnet again to AWS CIDR in VRF1 at site level (normal mode) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_present + register: nm_add_subnet_again + +- name: Verify nm_add_subnet_again + assert: + that: + - nm_add_subnet_again is not changed + - nm_add_subnet_again.current.ip == nm_add_subnet_again.previous.ip == '10.0.0.0/24' + - nm_add_subnet_again.current.zone == nm_add_subnet_again.previous.zone == 'us-west-1a' + +- name: Add a new subnet to Azure CIDR in VRF1 at site level (check mode) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_present + site: 'azure_{{ mso_site | default("ansible_test") }}' + region: westus + cidr: 10.1.0.0/16 + subnet: 10.1.0.0/24 + zone: null + check_mode: yes + register: cm_add_subnet_2 + +- name: Verify cm_add_subnet_2 + assert: + that: + - cm_add_subnet_2 is changed + - cm_add_subnet_2.previous == {} + - cm_add_subnet_2.current.ip == '10.1.0.0/24' + - cm_add_subnet_2.current.zone == '' + +- name: Add a new subnet to Azure CIDR in VRF1 at site level (normal mode) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_present + site: 'azure_{{ mso_site | default("ansible_test") }}' + region: westus + cidr: 10.1.0.0/16 + subnet: 10.1.0.0/24 + zone: null + register: nm_add_subnet_2 + +- name: Verify nm_add_subnet_2 + assert: + that: + - nm_add_subnet_2 is changed + - nm_add_subnet_2.previous == {} + - nm_add_subnet_2.current.ip == '10.1.0.0/24' + - nm_add_subnet_2.current.zone == '' + +- name: Add a second subnet to Azure CIDR in VRF1 at site level for VGW (check mode) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_present + site: 'azure_{{ mso_site | default("ansible_test") }}' + region: westus + cidr: 10.1.0.0/16 + subnet: 10.1.1.0/24 + zone: null + vgw: true + check_mode: yes + register: cm_add_subnet_3 + +- name: Verify cm_add_subnet_3 + assert: + that: + - cm_add_subnet_3 is changed + - cm_add_subnet_3.previous == {} + - cm_add_subnet_3.current.ip == '10.1.1.0/24' + - cm_add_subnet_3.current.zone == '' + - cm_add_subnet_3.current.usage == 'gateway' + +# VGW +- name: Add a second subnet to Azure CIDR in VRF1 at site level for VGW (normal mode) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_present + site: 'azure_{{ mso_site | default("ansible_test") }}' + region: westus + cidr: 10.1.0.0/16 + subnet: 10.1.1.0/24 + zone: null + vgw: true + register: nm_add_subnet_3 + +- name: Verify nm_add_subnet_3 + assert: + that: + - nm_add_subnet_3 is changed + - nm_add_subnet_3.previous == {} + - nm_add_subnet_3.current.ip == '10.1.1.0/24' + - nm_add_subnet_3.current.zone == '' + - nm_add_subnet_3.current.usage == 'gateway' + +# Private Link Label +- name: Add a new subnet to Azure CIDR in VRF1 at site level for Private Link Label (MSO >3.3) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_present + site: 'azure_{{ mso_site | default("ansible_test") }}' + region: westus + cidr: 10.1.0.0/16 + subnet: 10.1.0.0/24 + private_link_label: 'New_Private_Link_Label' + zone: null + register: nm_add_subnet_4 + when: version.current.version is version('3.3', '>=') + +- name: Verify nm_add_subnet_4 + assert: + that: + - nm_add_subnet_4 is changed + - nm_add_subnet_4.current.ip == '10.1.0.0/24' + - nm_add_subnet_4.current.privateLinkLabel.name == 'New_Private_Link_Label' + when: version.current.version is version('3.3', '>=') + +# QUERY SUBNETS +- name: Query subnet to AWS CIDR in VRF1 at site level (check mode) + mso_schema_site_vrf_region_cidr_subnet: &mso_query + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + cidr: 10.0.0.0/16 + subnet: 10.0.0.0/24 + state: query + check_mode: yes + register: cm_query_subnet + +- name: Verify cm_query_subnet + assert: + that: + - cm_query_subnet is not changed + - cm_query_subnet.current.ip == '10.0.0.0/24' + - cm_query_subnet.current.zone == 'us-west-1a' + +- name: Query subnet to AWS CIDR in VRF1 at site level (normal mode) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_query + register: nm_query_subnet + +- name: Verify nm_query_subnet + assert: + that: + - nm_query_subnet is not changed + +# QUERY ALL SUBNETS +- name: Query all subnets to AWS CIDR in VRF1 at site level (check mode) + mso_schema_site_vrf_region_cidr_subnet: &mso_query_all + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + cidr: 10.0.0.0/16 + state: query + check_mode: yes + register: cm_query_subnet_all_aws + +- name: Query all subnets to Azure CIDR in VRF1 at site level (check mode) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_query_all + site: 'azure_{{ mso_site | default("ansible_test") }}' + region: westus + cidr: 10.1.0.0/16 + state: query + check_mode: yes + register: cm_query_subnet_all_azure + +- name: Verify cm_query_subnet_all_aws and cm_query_subnet_all_azure + assert: + that: + - cm_query_subnet_all_aws is not changed + - cm_query_subnet_all_aws.current[0].ip == '10.0.0.0/24' + - cm_query_subnet_all_aws.current[0].zone == 'us-west-1a' + - cm_query_subnet_all_azure is not changed + - cm_query_subnet_all_azure.current[0].ip == '10.1.0.0/24' + - cm_query_subnet_all_azure.current[1].ip == '10.1.1.0/24' + +- name: Verify cm_query_subnet_all_aws and cm_query_subnet_all_azure zone + assert: + that: + - cm_query_subnet_all_azure.current[0].zone == '' + - cm_query_subnet_all_azure.current[1].zone == '' + when: version.current.version is version('4.0', '<') + + +- name: Verify cm_query_subnet_all_aws and cm_query_subnet_all_azure zone + assert: + that: + - cm_query_subnet_all_azure.current[0].zone == 'default' + - cm_query_subnet_all_azure.current[1].zone == 'default' + when: version.current.version is version('4.0', '>=') + +- name: Query subnet to AWS CIDR in VRF1 at site level (normal mode) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_query_all + register: nm_query_subnet_all_aws + +- name: Query subnet to AWS CIDR in VRF1 at site level (normal mode) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_query_all + site: 'azure_{{ mso_site | default("ansible_test") }}' + region: westus + cidr: 10.1.0.0/16 + state: query + register: nm_query_subnet_all_azure + +- name: Verify nm_query_subnet_all_aws and nm_query_subnet_all_azure + assert: + that: + - nm_query_subnet_all_aws is not changed + - nm_query_subnet_all_aws.current[0].ip == '10.0.0.0/24' + - nm_query_subnet_all_aws.current[0].zone == 'us-west-1a' + - nm_query_subnet_all_azure is not changed + - nm_query_subnet_all_azure.current[0].ip == '10.1.0.0/24' + - nm_query_subnet_all_azure.current[1].ip == '10.1.1.0/24' + +- name: Verify cm_query_subnet_all_aws and cm_query_subnet_all_azure zone + assert: + that: + - nm_query_subnet_all_azure.current[0].zone == '' + - nm_query_subnet_all_azure.current[1].zone == '' + when: version.current.version is version('4.0', '<') + + +- name: Verify cm_query_subnet_all_aws and cm_query_subnet_all_azure zone + assert: + that: + - nm_query_subnet_all_azure.current[0].zone == 'default' + - nm_query_subnet_all_azure.current[1].zone == 'default' + when: version.current.version is version('4.0', '>=') + +# Execute Hosted VRF parameters only when when MSO version >= 3.3 +- name: Execute tasks only for MSO version >= 3.3 + when: version.current.version is version('3.3', '>=') + block: + - name: Ensure VRF2 exists + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF2 + state: present + + - name: Add a secondary CIDR in VRF1 at AWS site level + mso_schema_site_vrf_region_cidr: &secondary_cidr + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + cidr: 10.2.0.0/16 + primary: false + register: nm_add_cidr_3 + + - name: Verify nm_add_cidr_3 + assert: + that: + - nm_add_cidr_3 is changed + - nm_add_cidr_3.previous == {} + - nm_add_cidr_3.current.ip == '10.2.0.0/16' + - nm_add_cidr_3.current.primary == false + + - name: Add a secondary CIDR in VRF1 at Azure site level + mso_schema_site_vrf_region_cidr: + <<: *secondary_cidr + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'azure_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: westus + cidr: 10.3.0.0/16 + primary: false + register: nm_add_cidr_4 + + - name: Verify nm_add_cidr_4 + assert: + that: + - nm_add_cidr_4 is changed + - nm_add_cidr_4.previous == {} + - nm_add_cidr_4.current.ip == '10.3.0.0/16' + - nm_add_cidr_4.current.primary == false + + - name: Add hosted vrf parameters in VRF1 at Azure site level + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'azure_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: westus + cidr: 10.3.0.0/16 + subnet: 10.3.0.0/24 + zone: westus + hosted_vrf: VRF2 + vgw: true + state: present + register: azure_add_hosted_vrf + + - name: Verify azure_add_hosted_vrf + assert: + that: + - azure_add_hosted_vrf is changed + - azure_add_hosted_vrf.previous == {} + - azure_add_hosted_vrf.current.ip == '10.3.0.0/24' + - azure_add_hosted_vrf.current.vrfRef.vrfName == 'VRF2' + + - name: Add hosted vrf parameters in VRF1 at AWS site level + mso_schema_site_vrf_region_cidr_subnet: &aws_cidr + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + cidr: 10.2.0.0/16 + subnet: 10.2.0.0/24 + zone: us-west-1a + hosted_vrf: VRF2 + vgw: true + state: present + register: aws_add_hosted_vrf + + - name: Verify aws_add_hosted_vrf + assert: + that: + - aws_add_hosted_vrf is changed + - aws_add_hosted_vrf.previous == {} + - aws_add_hosted_vrf.current.ip == '10.2.0.0/24' + - aws_add_hosted_vrf.current.vrfRef.vrfName == 'VRF2' + + - name: Get Validation status + mso_schema_validate: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + state: query + register: query_validate + + - name: Verify query_validate + assert: + that: + - query_validate is not changed + + - name: Verify query_validate result < 4.0 + assert: + that: + - query_validate.current.result == "true" + when: version.current.version is version('4.0', '<') + + - name: Verify query_validate result => 4.0 + assert: + that: + - query_validate.current.result == true + when: version.current.version is version('4.0', '>=') + +# REMOVE SUBNETS +- name: Remove Subnet from CIDR (check_mode) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_present + state: absent + check_mode: yes + register: cm_remove_subnet + +- name: Verify cm_remove_subnet + assert: + that: + - cm_remove_subnet is changed + - cm_remove_subnet.current == {} + +- name: Remove Subnet from CIDR (normal mode) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_present + state: absent + register: nm_remove_subnet + +- name: Verify nm_remove_subnet + assert: + that: + - nm_remove_subnet is changed + - nm_remove_subnet.current == {} + +- name: Remove Subnet from CIDR again (check_mode) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_present + state: absent + check_mode: yes + register: cm_remove_subnet_again + +- name: Verify cm_remove_subnet_again + assert: + that: + - cm_remove_subnet_again is not changed + - cm_remove_subnet_again.current == {} + +- name: Remove Subnet from CIDR again (normal mode) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_present + state: absent + register: nm_remove_subnet_again + +- name: Verify nm_remove_subnet_again + assert: + that: + - nm_remove_subnet_again is not changed + - nm_remove_subnet_again.current == {} + +- name: Remove Subnet from CIDR (normal mode) + mso_schema_site_vrf_region_cidr_subnet: + <<: *aws_cidr + state: absent + register: remove_subnet + when: version.current.version is version('3.3', '>=') + +- name: Verify nm_remove_subnet + assert: + that: + - remove_subnet is changed + - remove_subnet.current == {} + when: version.current.version is version('3.3', '>=') + +# QUERY NON-EXISTING subnet in CIDR +- name: Query non-existing subnet (check_mode) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_query + subnet: non_existing_subnet + check_mode: yes + ignore_errors: yes + register: cm_query_non_subnet + +- name: Query non-existing subnet (normal mode) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_query + subnet: non_existing_subnet + ignore_errors: yes + register: nm_query_non_subnet + +- name: Verify query_non_subnet + assert: + that: + - cm_query_non_subnet is not changed + - nm_query_non_subnet is not changed + - cm_query_non_subnet == nm_query_non_subnet + - cm_query_non_subnet.msg is match("Subnet IP 'non_existing_subnet' not found") + - nm_query_non_subnet.msg is match("Subnet IP 'non_existing_subnet' not found") + +# QUERY NON-EXISTING CIDR +- name: Query non-existing CIDR (check_mode) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_query + cidr: non_existing_cidr + check_mode: yes + ignore_errors: yes + register: cm_query_non_cidr + +- name: Query non-existing CIDR (normal mode) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_query + cidr: non_existing_cidr + ignore_errors: yes + register: nm_query_non_cidr + +- name: Verify query_non_cidr + assert: + that: + - cm_query_non_cidr is not changed + - nm_query_non_cidr is not changed + - cm_query_non_cidr == nm_query_non_cidr + +- name: Verify query_non_cidr value (version < 3.3) + assert: + that: + - cm_query_non_cidr.msg == nm_query_non_cidr.msg == "Provided CIDR IP 'non_existing_cidr' does not exist. Existing CIDR IPs{{':'}} 10.0.0.0/16. Use mso_schema_site_vrf_region_cidr to create it." + when: version.current.version is version('3.3', '<') + +- name: Verify query_non_cidr value (version >= 3.3) + assert: + that: + - cm_query_non_cidr.msg == nm_query_non_cidr.msg == "Provided CIDR IP 'non_existing_cidr' does not exist. Existing CIDR IPs{{':'}} 10.0.0.0/16, 10.2.0.0/16. Use mso_schema_site_vrf_region_cidr to create it." + when: version.current.version is version('3.3', '>=') + +# QUERY NON-EXISTING region +- name: Query non-existing region (check_mode) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_query + region: non_existing_region + check_mode: yes + ignore_errors: yes + register: cm_query_non_region + +- name: Query non-existing region (normal mode) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_query + region: non_existing_region + ignore_errors: yes + register: nm_query_non_region + +- name: Verify query_non_region + assert: + that: + - cm_query_non_region is not changed + - nm_query_non_region is not changed + - cm_query_non_region == nm_query_non_region + - cm_query_non_region.msg == nm_query_non_region.msg == "Provided region 'non_existing_region' does not exist. Existing regions{{':'}} us-west-1. Use mso_schema_site_vrf_region_cidr to create it." + +# QUERY NON-EXISTING VRF +- name: Query non-existing VRF (check_mode) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_query + vrf: non_existing_vrf + check_mode: yes + ignore_errors: yes + register: cm_query_non_vrf + +- name: Query non-existing VRF (normal mode) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_query + vrf: non_existing_vrf + ignore_errors: yes + register: nm_query_non_vrf + +- name: Verify query_non_vrf + assert: + that: + - cm_query_non_vrf is not changed + - nm_query_non_vrf is not changed + - cm_query_non_vrf == nm_query_non_vrf + - cm_query_non_vrf.msg == nm_query_non_vrf.msg == "Provided vrf 'non_existing_vrf' does not exist at site level. Use mso_schema_site_vrf_region_cidr to create it." + +# USE A NON-EXISTING STATE +- name: Non-existing state for site cidr subnet (check_mode) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_query + state: non-existing-state + check_mode: yes + ignore_errors: yes + register: cm_non_existing_state + +- name: Non-existing state for site cidr subnet (normal_mode) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_query + state: non-existing-state + ignore_errors: yes + register: nm_non_existing_state + +- name: Verify non_existing_state + assert: + that: + - cm_non_existing_state is not changed + - nm_non_existing_state is not changed + - cm_non_existing_state == nm_non_existing_state + - cm_non_existing_state.msg == nm_non_existing_state.msg == "value of state must be one of{{':'}} absent, present, query, got{{':'}} non-existing-state" + +# USE A NON-EXISTING SCHEMA +- name: Non-existing schema for site cidr subnet (check_mode) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_query + schema: non-existing-schema + check_mode: yes + ignore_errors: yes + register: cm_non_existing_schema + +- name: Non-existing schema for site cidr subnet (normal_mode) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_query + schema: non-existing-schema + ignore_errors: yes + register: nm_non_existing_schema + +- name: Verify non_existing_schema + assert: + that: + - cm_non_existing_schema is not changed + - nm_non_existing_schema is not changed + - cm_non_existing_schema == nm_non_existing_schema + - cm_non_existing_schema.msg == nm_non_existing_schema.msg == "Provided schema 'non-existing-schema' does not exist." + +# USE A NON-EXISTING TEMPLATE +- name: Non-existing template for site cidr subnet (check_mode) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_query + template: non-existing-template + check_mode: yes + ignore_errors: yes + register: cm_non_existing_template + +- name: Non-existing template for site cidr subnet (normal_mode) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_query + template: non-existing-template + ignore_errors: yes + register: nm_non_existing_template + +- name: Verify non_existing_template + assert: + that: + - cm_non_existing_template is not changed + - nm_non_existing_template is not changed + - cm_non_existing_template == nm_non_existing_template + - cm_non_existing_template.msg == nm_non_existing_template.msg == "Provided template 'non-existing-template' does not exist. Existing templates{{':'}} Template1, Template2" + +# USE A NON-ASSOCIATED TEMPLATE +- name: Non-associated template for site cidr subnet (check_mode) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_query + template: Template 2 + check_mode: yes + ignore_errors: yes + register: cm_non_associated_template + +- name: Non-associated template for site cidr subnet (normal_mode) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_query + template: Template 2 + ignore_errors: yes + register: nm_non_associated_template + +- name: Verify non_associated_template + assert: + that: + - cm_non_associated_template is not changed + - nm_non_associated_template is not changed + - cm_non_associated_template == nm_non_associated_template + - cm_non_associated_template.msg is match("Provided site/siteId/template 'aws_ansible_test/[0-9a-zA-Z]*/Template2' does not exist. Existing siteIds/templates{{':'}} [0-9a-zA-Z]*/Template1") + - nm_non_associated_template.msg is match("Provided site/siteId/template 'aws_ansible_test/[0-9a-zA-Z]*/Template2' does not exist. Existing siteIds/templates{{':'}} [0-9a-zA-Z]*/Template1") + +# USE A TEMPLATE WITHOUT ANY SITE +- name: Add site cidr subnet to Schema 2 Template 3 without any site associated (check mode) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_query + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + check_mode: yes + ignore_errors: yes + register: cm_no_site_associated + +- name: Add site cidr subnet to Template 3 without any site associated (normal mode) + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_query + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + ignore_errors: yes + register: nm_no_site_associated + +- name: Verify cm_no_site_associated and nm_no_site_associated + assert: + that: + - cm_no_site_associated is not changed + - nm_no_site_associated is not changed + - cm_no_site_associated.msg == nm_no_site_associated.msg == "No site associated with template 'Template3'. Associate the site with the template using mso_schema_site." + +# Checking if issue when adding subnet to Hub Network (#126) +- name: Add hub network in VRF1 region us-west-1 at AWS site level + mso_schema_site_vrf_region_hub_network: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + hub_network: + name: hub-test + tenant: infra + state: present + +- name: Add a new subnet to AWS CIDR in VRF1 at site level + mso_schema_site_vrf_region_cidr_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + cidr: 10.0.0.0/16 + subnet: 10.0.0.0/24 + zone: us-west-1a + hub_network: true + state: present + register: nm_add_subnet_hub_network + +- name: Verify nm_add_subnet_hub_network + assert: + that: + - nm_add_subnet_hub_network is changed + - nm_add_subnet_hub_network.current.usage == 'gateway'
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_vrf_region_hub_network/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_vrf_region_hub_network/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_vrf_region_hub_network/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_vrf_region_hub_network/tasks/hub_network.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_vrf_region_hub_network/tasks/hub_network.yml new file mode 100644 index 00000000..9d223399 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_vrf_region_hub_network/tasks/hub_network.yml @@ -0,0 +1,719 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Lionel Hercot (@lhercot) <lhercot@cisco.com> +# Copyright: (c) 2020, Cindy Zhao (@cizhao) <cizhao@cisco.com> + +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +# 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") }}' + sites: "['aws_{{ mso_site | default(\"ansible_test\") }}', + 'azure_{{ mso_site | default(\"ansible_test\") }}', + '{{ mso_site | default(\"ansible_test\") }}']" + +- name: Ensure site exists + mso_site: + <<: *mso_info + site: 'aws_{{ mso_site | default("ansible_test") }}' + apic_username: '{{ aws_apic_username }}' + apic_password: '{{ aws_apic_password }}' + apic_site_id: '{{ aws_site_id | default(102) }}' + urls: + - https://{{ aws_apic_hostname }} + state: present + +- name: Ensure site exists + mso_site: + <<: *mso_info + site: 'azure_{{ mso_site | default("ansible_test") }}' + apic_username: '{{ azure_apic_username }}' + apic_password: '{{ azure_apic_password }}' + apic_site_id: '{{ azure_site_id | default(103) }}' + urls: + - https://{{ azure_apic_hostname }} + state: present + +- name: Remove Schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Ensure sites removed from tenant ansible_test + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: '{{ item }}' + state: absent + loop: + - '{{ mso_site | default("ansible_test") }}' + - 'aws_{{ mso_site | default("ansible_test") }}' + - 'azure_{{ mso_site | default("ansible_test") }}' + +- name: Ensure tenant ansible_test exist + mso_tenant: + <<: *mso_info + tenant: ansible_test + # sites: + # - '{{ mso_site | default("ansible_test") }}' + users: + - '{{ mso_username }}' + state: present + +- name: Ensure AWS site is present under tenant ansible_test + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'aws_{{ mso_site | default("ansible_test") }}' + cloud_account: '000000000000' + aws_access_key: 1 + secret_key: 0 + state: present + +- name: Ensure Azure site is present under tenant ansible_test + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'azure_{{ mso_site | default("ansible_test") }}' + cloud_account: uni/tn-ansible_test/act-[9]-vendor-azure + state: present + +- name: Ensure schema 1 with Template 1 and 2 exists + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: '{{ item }}' + state: present + loop: + - Template 1 + - Template 2 + +- name: Ensure schema 2 with Template 3 exists + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template 3 + state: present + +- name: Ensure VRF1 exists + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF1 + state: present + +- name: Add a new CIDR in VRF1 at AWS site level (check mode) + mso_schema_site_vrf_region_cidr: &mso_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + cidr: 10.0.0.0/16 + primary: true + state: present + check_mode: yes + register: cm_add_cidr + +- name: Verify cm_add_cidr + assert: + that: + - cm_add_cidr is changed + - cm_add_cidr.previous == {} + - cm_add_cidr.current.ip == '10.0.0.0/16' + - cm_add_cidr.current.primary == true + +- name: Add a new CIDR in VRF1 at AWS site level (normal mode) + mso_schema_site_vrf_region_cidr: + <<: *mso_present + register: nm_add_cidr + +- name: Verify nm_add_cidr + assert: + that: + - nm_add_cidr is changed + - nm_add_cidr.previous == {} + - nm_add_cidr.current.ip == '10.0.0.0/16' + - nm_add_cidr.current.primary == true + +# ADD Hub Network +- name: Add hub network in VRF1 region us-west-1 at AWS site level (check mode) + mso_schema_site_vrf_region_hub_network: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + hub_network: + name: hub-test + tenant: infra + state: present + check_mode: yes + register: cm_add_hub_network + +- name: Add hub network in VRF1 region us-west-1 at AWS site level (normal mode) + mso_schema_site_vrf_region_hub_network: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + hub_network: + name: hub-test + tenant: infra + state: present + register: nm_add_hub_network + +- name: Verify cm_add_hub_network and nm_add_hub_network + assert: + that: + - cm_add_hub_network is changed + - nm_add_hub_network is changed + - cm_add_hub_network.previous == {} + - nm_add_hub_network.previous == {} + - cm_add_hub_network.current.name == "hub-test" + - cm_add_hub_network.current.tenantName == "infra" + - nm_add_hub_network.current.name == "hub-test" + - nm_add_hub_network.current.tenantName == "infra" + +# Add hub network again +- name: Add hub network again in VRF1 region us-west-1 at AWS site level (normal mode) + mso_schema_site_vrf_region_hub_network: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + hub_network: + name: hub-test + tenant: infra + state: present + register: nm_add_hub_network_again + +- name: Verify nm_add_hub_network_again + assert: + that: + - nm_add_hub_network_again is not changed + - nm_add_hub_network_again.previous.name == nm_add_hub_network_again.current.name == "hub-test" + - nm_add_hub_network_again.previous.tenantName == nm_add_hub_network_again.current.tenantName == "infra" + +# Update hub network +- name: Update hub network in VRF1 region us-west-1 at AWS site level (check_mode) + mso_schema_site_vrf_region_hub_network: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + hub_network: + name: hub-default + tenant: infra + state: present + check_mode: yes + register: cm_update_hub_network + +- name: Update hub network in VRF1 region us-west-1 at AWS site level (normal_mode) + mso_schema_site_vrf_region_hub_network: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + hub_network: + name: hub-default + tenant: infra + state: present + register: nm_update_hub_network + +- name: Verify cm_update_hub_network and nm_update_hub_network + assert: + that: + - cm_update_hub_network is changed + - nm_update_hub_network is changed + - cm_update_hub_network.previous.name == "hub-test" + - cm_update_hub_network.previous.tenantName == "infra" + - cm_update_hub_network.current.name == "hub-default" + - cm_update_hub_network.current.tenantName == "infra" + - nm_update_hub_network.previous.name == "hub-test" + - nm_update_hub_network.previous.tenantName == "infra" + - nm_update_hub_network.current.name == "hub-default" + - nm_update_hub_network.current.tenantName == "infra" + +# Query Hub Network +- name: Query hub network in VRF1 region us-west-1 at AWS site level + mso_schema_site_vrf_region_hub_network: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + state: query + check_mode: yes + register: cm_query_hub_network + +- name: Verify cm_query_hub_network + assert: + that: + - cm_query_hub_network is not changed + - cm_query_hub_network.current.name == "hub-default" + - cm_query_hub_network.current.tenantName == "infra" + +# Remove Hub Network +- name: Remove hub network in VRF1 region us-west-1 at AWS site level (check_mode) + mso_schema_site_vrf_region_hub_network: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + state: absent + check_mode: yes + register: cm_remove_hub_network + +- name: Remove hub network in VRF1 region us-west-1 at AWS site level (normal mode) + mso_schema_site_vrf_region_hub_network: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + state: absent + register: nm_remove_hub_network + +- name: Verify cm_remove_hub_network and nm_remove_hub_network + assert: + that: + - cm_remove_hub_network is changed + - cm_remove_hub_network.current == {} + - cm_remove_hub_network.previous.name == "hub-default" + - cm_remove_hub_network.previous.tenantName == "infra" + - nm_remove_hub_network is changed + - nm_remove_hub_network.current == {} + - nm_remove_hub_network.previous.name == "hub-default" + - nm_remove_hub_network.previous.tenantName == "infra" + +# Remove Hub Network again +- name: Remove again hub network in VRF1 region us-west-1 at AWS site level (check_mode) + mso_schema_site_vrf_region_hub_network: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + state: absent + check_mode: yes + register: cm_remove_hub_network_again + +- name: Remove again hub network in VRF1 region us-west-1 at AWS site level (normal_mode) + mso_schema_site_vrf_region_hub_network: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + state: absent + register: nm_remove_hub_network_again + +- name: Verify cm_remove_hub_network_again and nm_remove_hub_network_again + assert: + that: + - cm_remove_hub_network_again is not changed + - nm_remove_hub_network_again is not changed + - cm_remove_hub_network_again.previous == cm_remove_hub_network_again.current == {} + - nm_remove_hub_network_again.previous == nm_remove_hub_network_again.current == {} + +# query when hub network does not exist +- name: Query non_existing_hub_network + mso_schema_site_vrf_region_hub_network: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + state: query + ignore_errors: yes + register: query_non_existing_hub_network + +- name: Verify query_non_existing_hub_network + assert: + that: + - query_non_existing_hub_network.msg == "Hub network not found" + +# Re-Add hub network +- name: Re-Add hub network in VRF1 region us-west-1 at AWS site level (normal mode) + mso_schema_site_vrf_region_hub_network: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + hub_network: + name: hub-test + tenant: infra + state: present + register: re_add_hub_network + +- name: Verify re_add_hub_network + assert: + that: + - re_add_hub_network is changed + - re_add_hub_network.previous == {} + - re_add_hub_network.current.name == "hub-test" + - re_add_hub_network.current.tenantName == "infra" + +# QUERY NON-EXISTING region +- name: Query non-existing region (check_mode) + mso_schema_site_vrf_region_hub_network: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: non_existing_region + state: query + ignore_errors: yes + check_mode: yes + register: cm_query_non_region + +- name: Query non-existing region (normal mode) + mso_schema_site_vrf_region_hub_network: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: non_existing_region + state: query + ignore_errors: yes + register: nm_query_non_region + +- name: Verify query_non_region + assert: + that: + - cm_query_non_region is not changed + - nm_query_non_region is not changed + - cm_query_non_region == nm_query_non_region + - cm_query_non_region.msg == nm_query_non_region.msg == "Provided region 'non_existing_region' does not exist. Existing regions{{':'}} us-west-1" + +# QUERY NON-EXISTING VRF +- name: Query non-existing VRF (check_mode) + mso_schema_site_vrf_region_hub_network: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: non_existing_vrf + region: us-west-1 + state: query + check_mode: yes + ignore_errors: yes + register: cm_query_non_vrf + +- name: Query non-existing VRF (normal mode) + mso_schema_site_vrf_region_hub_network: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: non_existing_vrf + region: us-west-1 + state: query + ignore_errors: yes + register: nm_query_non_vrf + +- name: Verify query_non_vrf + assert: + that: + - cm_query_non_vrf is not changed + - nm_query_non_vrf is not changed + - cm_query_non_vrf == nm_query_non_vrf + - cm_query_non_vrf.msg == nm_query_non_vrf.msg == "Provided vrf 'non_existing_vrf' does not exist. Existing vrfs{{':'}} VRF1" + +# USE A NON-EXISTING STATE +- name: Non-existing state for site hub network (check_mode) + mso_schema_site_vrf_region_hub_network: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + state: non-existing-state + check_mode: yes + ignore_errors: yes + register: cm_non_existing_state + +- name: Non-existing state for hub network (normal_mode) + mso_schema_site_vrf_region_hub_network: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + state: non-existing-state + ignore_errors: yes + register: nm_non_existing_state + +- name: Verify non_existing_state + assert: + that: + - cm_non_existing_state is not changed + - nm_non_existing_state is not changed + - cm_non_existing_state == nm_non_existing_state + - cm_non_existing_state.msg == nm_non_existing_state.msg == "value of state must be one of{{':'}} absent, present, query, got{{':'}} non-existing-state" + +# USE A NON-EXISTING SCHEMA +- name: Non-existing schema for site hub network (check_mode) + mso_schema_site_vrf_region_hub_network: + <<: *mso_info + schema: non-existing-schema + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + state: query + check_mode: yes + ignore_errors: yes + register: cm_non_existing_schema + +- name: Non-existing schema for site hub network (normal_mode) + mso_schema_site_vrf_region_hub_network: + <<: *mso_info + schema: non-existing-schema + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + state: query + ignore_errors: yes + register: nm_non_existing_schema + +- name: Verify non_existing_schema + assert: + that: + - cm_non_existing_schema is not changed + - nm_non_existing_schema is not changed + - cm_non_existing_schema == nm_non_existing_schema + - cm_non_existing_schema.msg == nm_non_existing_schema.msg == "Provided schema 'non-existing-schema' does not exist." + +# USE A NON-EXISTING TEMPLATE +- name: Non-existing template for site hub network (check_mode) + mso_schema_site_vrf_region_hub_network: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: non-existing-template + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + state: query + check_mode: yes + ignore_errors: yes + register: cm_non_existing_template + +- name: Non-existing template for site hub network (normal_mode) + mso_schema_site_vrf_region_hub_network: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: non-existing-template + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + state: query + ignore_errors: yes + register: nm_non_existing_template + +- name: Verify non_existing_template + assert: + that: + - cm_non_existing_template is not changed + - nm_non_existing_template is not changed + - cm_non_existing_template == nm_non_existing_template + - cm_non_existing_template.msg == nm_non_existing_template.msg == "Provided template 'non-existing-template' does not exist. Existing templates{{':'}} Template1, Template2" + +# USE A NON_EXISTING_SITE_TEMPLATE +- name: non_existing_site_template (check_mode) + mso_schema_site_vrf_region_hub_network: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + state: query + check_mode: yes + ignore_errors: yes + register: cm_non_existing_site_template + +- name: non_existing_site_template (normal_mode) + mso_schema_site_vrf_region_hub_network: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + state: query + ignore_errors: yes + register: nm_non_existing_site_template + +- name: Verify cm_non_existing_site_template and nm_non_existing_site_template + assert: + that: + - cm_non_existing_site_template is not changed + - nm_non_existing_site_template is not changed + - cm_non_existing_site_template.msg == nm_non_existing_site_template.msg == "Provided site-template association 'aws_ansible_test-Template2' does not exist." + +# USE A NON_EXISTING_SITE +- name: non_existing_site (check_mode) + mso_schema_site_vrf_region_hub_network: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: non_existing_site + vrf: VRF1 + region: us-west-1 + state: query + check_mode: yes + ignore_errors: yes + register: cm_non_existing_site + +- name: non_existing_site (normal_mode) + mso_schema_site_vrf_region_hub_network: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: non_existing_site + vrf: VRF1 + region: us-west-1 + state: query + ignore_errors: yes + register: nm_non_existing_site + +- name: Verify cm_non_existing_site and nm_non_existing_site + assert: + that: + - cm_non_existing_site is not changed + - nm_non_existing_site is not changed + - cm_non_existing_site.msg == nm_non_existing_site.msg == "Site 'non_existing_site' is not a valid site name." + +# use mso_schema_site_vrf_region_cidr_subnet module to update region +- name: Add a new CIDR in VRF1 at AWS site level (check mode) + mso_schema_site_vrf_region_cidr: &cidr_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + cidr: 10.1.0.0/16 + primary: false + state: present + check_mode: yes + register: cm_add_cidr + +- name: Verify cm_add_cidr + assert: + that: + - cm_add_cidr is changed + - cm_add_cidr.previous == {} + - cm_add_cidr.current.ip == '10.1.0.0/16' + - cm_add_cidr.current.primary == false + +- name: Add a new CIDR in VRF1 at AWS site level (normal mode) + mso_schema_site_vrf_region_cidr: + <<: *cidr_present + register: nm_add_cidr + +- name: Verify nm_add_cidr + assert: + that: + - nm_add_cidr is changed + - nm_add_cidr.previous == {} + - nm_add_cidr.current.ip == '10.1.0.0/16' + - nm_add_cidr.current.primary == false + +# query hub network after using mso_schema_site_vrf_region_cidr_subnet module to update region +- name: Query hub_network after region updated + mso_schema_site_vrf_region_hub_network: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + state: query + register: query_after_region_update + +- name: Verify query_after_region_update + assert: + that: + - query_after_region_update is not changed + - query_after_region_update.current.name == "hub-test" + - query_after_region_update.current.tenantName == "infra" + +# USE A TEMPLATE WITHOUT ANY SITE +- name: Add site VRF region hub network to Schema 2 Template 3 without any site associated (check mode) + mso_schema_site_vrf_region_hub_network: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + hub_network: + name: hub-test + tenant: infra + state: present + ignore_errors: yes + check_mode: yes + register: cm_no_site_associated + +- name: Add site VRF region hub network to Template 3 without any site associated (normal mode) + mso_schema_site_vrf_region_hub_network: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + site: 'aws_{{ mso_site | default("ansible_test") }}' + vrf: VRF1 + region: us-west-1 + hub_network: + name: hub-test + tenant: infra + state: present + ignore_errors: yes + register: nm_no_site_associated + +- name: Verify cm_no_site_associated and nm_no_site_associated + assert: + that: + - cm_no_site_associated is not changed + - nm_no_site_associated is not changed + - cm_no_site_associated.msg == nm_no_site_associated.msg == "No site associated with template 'Template3'. Associate the site with the template using mso_schema_site."
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_vrf_region_hub_network/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_vrf_region_hub_network/tasks/main.yml new file mode 100644 index 00000000..6eb612ad --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_site_vrf_region_hub_network/tasks/main.yml @@ -0,0 +1,32 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Lionel Hercot (@lhercot) <lhercot@cisco.com> +# Copyright: (c) 2020, Cindy Zhao (@cizhao) <cizhao@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") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Import hub_network tasks if MSO version is higher than 3.0 + import_tasks: hub_network.yml + when: version.current.version is version('3', '>')
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template/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/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template/tasks/main.yml new file mode 100644 index 00000000..0afc6680 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template/tasks/main.yml @@ -0,0 +1,391 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Shreyas Srish (@shrsr) <ssrish@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") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Ensure site exists + mso_site: + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + apic_username: '{{ apic_username }}' + apic_password: '{{ apic_password }}' + apic_site_id: '{{ apic_site_id | default(101) }}' + urls: + - https://{{ apic_hostname }} + state: present + ignore_errors: yes + +- name: Remove schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_3' + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Ensure tenant ansible_test exists + mso_tenant: + <<: *mso_info + tenant: '{{ item }}' + users: + - '{{ mso_username }}' + sites: + - '{{ mso_site | default("ansible_test") }}' + state: present + loop: + - 'ansible_test' + - 'ansible_test_2' + +- name: Ensure schema 1 with Template 1 exists in check mode + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template 1 + state: present + check_mode: yes + register: add_template1_schema1_cm + +- name: Ensure schema 1 with Template 1 exists + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template 1 + state: present + register: add_template1_schema1 + +- name: Ensure schema 1 with Template 2 exists + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template 2 + state: present + register: add_template2_schema1 + +- name: Ensure schema 2 with Template 3 exists + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template 3 + state: present + register: add_template3_schema2 + +- name: Ensure schema 2 with Template 3 exists again + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template 3 + state: present + register: add_template3_schema2_again + +- name: Ensure schema 3 with Template 1 exists + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_3' + tenant: ansible_test + template: Template 1 + state: present + register: add_template1_schema3 + +- name: Ensure schema 3 with Template 2 exists + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_3' + tenant: ansible_test_2 + template: Template 2 + state: present + register: add_template2_schema3 + +- name: Update display name of Template 3 in schema 2 + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template 3 + display_name: Temp 3 + state: present + register: update_template3_schema2 + +- name: Verify add + assert: + that: + - add_template1_schema1_cm is changed + - add_template1_schema1_cm.current.name == 'Template1' + - add_template1_schema1 is changed + - add_template1_schema1.current.name == 'Template1' + - add_template2_schema1 is changed + - add_template2_schema1.current.name == 'Template2' + - add_template3_schema2 is changed + - add_template3_schema2.current.name == 'Template3' + - update_template3_schema2 is changed + - add_template3_schema2_again is not changed + - add_template1_schema3 is changed + - add_template1_schema3.current.name == 'Template1' + - add_template2_schema3 is changed + - add_template2_schema3.current.name == 'Template2' + - update_template3_schema2.current.displayName == 'Temp 3' + +- name: Query Template 1 in Schema 1 + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template 1 + state: query + register: query_template1_schema1 + +- name: Query all Templates in Schema 1 + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + state: query + register: query_all_templates_schema1 + +- name: Query Template 1 in Schema 3 + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_3' + tenant: ansible_test + template: Template 1 + state: query + register: query_template1_schema3 + +- name: Query Template 2 in Schema 3 + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_3' + tenant: ansible_test_2 + template: Template 2 + state: query + register: query_template2_schema3 + +- name: Verify query + assert: + that: + - query_template1_schema1 is not changed + - query_template1_schema1.current.name == 'Template1' + - query_all_templates_schema1 is not changed + - query_all_templates_schema1.current | length == 2 + - query_template1_schema3 is not changed + - query_template1_schema3.current.name == 'Template1' + - query_template2_schema3 is not changed + - query_template2_schema3.current.name == 'Template2' + +- name: Remove Template 1 of Schema 1 + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template 1 + state: absent + ignore_errors: yes + register: remove_template1_schema1 + +- name: Remove Template 2 of Schema 1 + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template 2 + state: absent + register: remove_template2_schema1 + +- name: Remove non_existing_template + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: non_existing_template + state: absent + ignore_errors: yes + register: remove_template_non_existing_template + +- name: Remove Template 3 in schema 2 in check mode + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template 3 + state: absent + check_mode: yes + register: remove_template3_schema2_cm + +- name: Remove Template 3 in schema 2 in normal mode + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template 3 + state: absent + register: remove_template3_schema2_nm + +- name: Remove Template 3 in schema 2 again + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template 3 + state: absent + register: remove_template3_schema2_nm_again + +- name: Remove Template 1 of Schema 3 + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_3' + tenant: ansible_test + template: Template 1 + state: absent + register: remove_template1_schema3 + +- name: Remove Template 2 of Schema 3 + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_3' + tenant: ansible_test_2 + template: Template 2 + state: absent + register: remove_template2_schema3 + +- name: non_existing_schema + mso_schema_template: + <<: *mso_info + schema: non_schema + tenant: ansible_test + template: Template 4 + state: absent + ignore_errors: yes + register: remove_template_non_existing_schema + +- name: Verify remove + assert: + that: + - remove_template1_schema1.current == {} + - remove_template1_schema1.previous.name == 'Template1' + - remove_template2_schema1.current == {} + - remove_template2_schema1.previous.name == 'Template2' + - remove_template3_schema2_cm.current == {} + - remove_template3_schema2_cm.previous.name == 'Template3' + - remove_template3_schema2_nm.current == {} + - remove_template3_schema2_nm.previous.name == 'Template3' + - remove_template3_schema2_nm_again is not changed + - remove_template_non_existing_schema is not changed + - remove_template_non_existing_template is not changed + - remove_template1_schema3.current == {} + - remove_template2_schema3.current == {} + - remove_template1_schema3.previous.name == 'Template1' + - remove_template2_schema3.previous.name == 'Template2' + +# USE NON-EXISTING STATE +- name: non_existing_state state + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template 2 + state: non_existing_state + ignore_errors: yes + register: non_existing_state + +- name: Verify non_existing_state + assert: + that: + - non_existing_state is not changed + - non_existing_state.msg == "value of state must be one of{{':'}} absent, present, query, got{{':'}} non_existing_state" + +# USE A NON_EXISTING_TEMPLATE +- name: non_existing_template + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: non_existing_template + state: query + ignore_errors: yes + register: non_existing_template + +- name: Verify non_existing_template + assert: + that: + - non_existing_template is not changed + - non_existing_template.msg == "Template 'non_existing_template' not found" + +- name: Template attribute absent in task + mso_schema_template: + <<: *mso_info + schema: non_schema + tenant: ansible_test + state: query + ignore_errors: yes + register: absent_template + +- name: Verify absent_template + assert: + that: + - absent_template is not changed + - absent_template.current == [] + +- name: Update description schema 1 with Template 1 when version is greater than 3.3 + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + schema_description: "this is schema" + tenant: ansible_test + template: Template 1 + template_description: "this is template" + state: present + register: add_description + when: version.current.version is version('3.3', '>=') + +- name: Verify add description + assert: + that: + - add_description is changed + when: version.current.version is version('3.3', '>=') + +# REMOVE Schemas for next CI Run +- name: Remove schemas for next ci test + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_3' + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +# REMOVE Tenant2 specific to this test case +- name: Remove tenant2 + mso_tenant: + <<: *mso_info + tenant: ansible_test_2 + state: absent
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_anp/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_anp/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_anp/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/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_anp/tasks/main.yml new file mode 100644 index 00000000..fd05f9d3 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_anp/tasks/main.yml @@ -0,0 +1,311 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Cindy Zhao (@cizhao) <cizhao@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(false) }}' + output_level: '{{ mso_output_level | default("info") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Remove schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_3' + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Remove tenant2 + mso_tenant: + <<: *mso_info + tenant: ansible_test_2 + state: absent + +- name: Ensure tenant ansible_test exist + mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + state: present + +- name: Ensure schema 1 with Template 1 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template 1 + state: present + +- name: Ensure schema 1 with Template 2 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template 2 + state: present + +- name: Ensure schema 2 with Template 3 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template 3 + state: present + +- name: Ensure ANP exist (check_mode) + mso_schema_template_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + state: present + check_mode: yes + register: cm_create_anp + +- name: Ensure ANP exist (normal_mode) + mso_schema_template_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + state: present + register: nm_create_anp + +- name: Create ANP again (normal_mode) + mso_schema_template_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + state: present + register: nm_create_anp_again + +- name: Verify cm_create_anp, nm_create_anp and nm_create_anp_again + assert: + that: + - cm_create_anp is changed + - nm_create_anp is changed + - nm_create_anp_again is not changed + - cm_create_anp.previous == {} + - cm_create_anp.current.displayName == "ANP" + - cm_create_anp.current.name == "ANP" + - cm_create_anp.current.epgs == [] + - nm_create_anp.previous == {} + - nm_create_anp.current.displayName == "ANP" + - nm_create_anp.current.name == "ANP" + - nm_create_anp.current.epgs == [] + - nm_create_anp_again.previous == nm_create_anp_again.current + - nm_create_anp_again.current.displayName == "ANP" + - nm_create_anp_again.current.name == "ANP" + - nm_create_anp_again.current.epgs == [] + +- name: Create another anp (normal_mode) + mso_schema_template_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP_2 + display_name: another anp + state: present + register: nm_create_another_anp + +- name: Verify nm_create_another_anp + assert: + that: + - nm_create_another_anp is changed + - nm_create_another_anp.previous == {} + - nm_create_another_anp.current.displayName == "another anp" + - nm_create_another_anp.current.name == "ANP_2" + - nm_create_another_anp.current.epgs == [] + + +# Add description for version >= 3.3 +- name: Create another anp with description(normal_mode) + mso_schema_template_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP_3 + display_name: another anp 3 + description: "Description of an ANP_3" + state: present + register: nm_create_another_anp + when: version.current.version is version('3.3', '>=') + +- name: Verify nm_create_another_anp with description + assert: + that: + - nm_create_another_anp is changed + - nm_create_another_anp.previous == {} + - nm_create_another_anp.current.displayName == "another anp 3" + - nm_create_another_anp.current.name == "ANP_3" + - nm_create_another_anp.current.description == "Description of an ANP_3" + - nm_create_another_anp.current.epgs == [] + when: version.current.version is version('3.3', '>=') + +- name: Change anp (normal_mode) + mso_schema_template_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + display_name: displayName for ANP + state: present + register: nm_change_anp + +- name: Verify nm_change_anp + assert: + that: + - nm_change_anp is changed + - nm_change_anp.previous.name == nm_change_anp.current.name == "ANP" + - nm_change_anp.previous.displayName == "ANP" + - nm_change_anp.current.displayName == "displayName for ANP" + - nm_change_anp.previous.epgs == nm_change_anp.current.epgs == [] + +- name: Query anp + mso_schema_template_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + state: query + register: query_anp + +- name: Verify query_anp + assert: + that: + - query_anp is not changed + - query_anp.current.name == "ANP" + - query_anp.current.epgs == [] + - query_anp.current.displayName == "displayName for ANP" + +- name: Query all + mso_schema_template_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + state: query + register: query_all + +- name: Verify query_all + assert: + that: + - query_all is not changed + - query_all.current | length == 2 + when: version.current.version is version('3.3', '<') + +- name: Verify query_all + assert: + that: + - query_all is not changed + - query_all.current | length == 3 + when: version.current.version is version('3.3', '>=') + +- name: Query non_existing anp + mso_schema_template_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: non_existing_anp + state: query + ignore_errors: yes + register: query_non_existing_anp + +- name: Verify query_non_existing_anp + assert: + that: + - query_non_existing_anp.msg == "ANP 'non_existing_anp' not found" + +- name: Use non_existing schema + mso_schema_template_anp: + <<: *mso_info + schema: non_existing_schema + template: Template 1 + anp: ANP + state: query + ignore_errors: yes + register: query_non_existing_schema + +- name: Use non_existing template + mso_schema_template_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: non_existing_template + anp: ANP + state: query + ignore_errors: yes + register: query_non_existing_template + +- name: Verify query_non_existing_schema and query_non_existing_template + assert: + that: + - query_non_existing_schema.msg == "Provided schema 'non_existing_schema' does not exist." + - query_non_existing_template.msg == "Provided template 'non_existing_template' does not exist. Existing templates{{':'}} Template1, Template2" + +- name: Remove anp (check_mode) + mso_schema_template_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + state: absent + check_mode: yes + register: cm_rm_anp + +- name: Remove anp (normal_mode) + mso_schema_template_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + state: absent + register: nm_rm_anp + +- name: Verify cm_rm_anp and nm_rm_anp + assert: + that: + - cm_rm_anp is changed + - nm_rm_anp is changed + - nm_rm_anp.previous == cm_rm_anp.previous + - nm_rm_anp.current == cm_rm_anp.current == {} + - nm_rm_anp.previous.name == cm_rm_anp.previous.name == "ANP" + - nm_rm_anp.previous.displayName == cm_rm_anp.previous.displayName == "displayName for ANP" + - nm_rm_anp.previous.epgs == cm_rm_anp.previous.epgs == [] + +- name: Remove anp again + mso_schema_template_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + state: absent + register: nm_rm_anp_again + +- name: Verify nm_rm_anp_again + assert: + that: + - nm_rm_anp_again is not changed + - nm_rm_anp_again.previous == nm_rm_anp_again.current == {} diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_anp_epg/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_anp_epg/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_anp_epg/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/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_anp_epg/tasks/main.yml new file mode 100644 index 00000000..78f7c834 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_anp_epg/tasks/main.yml @@ -0,0 +1,1263 @@ +# Test code for the MSO modules +# Copyright: (c) 2021, Anvitha Jain (@anvitha-jain) <anvjain@cisco.com> +# Copyright: (c) 2020, Lionel Hercot (@lhercot) <lhercot@cisco.com> +# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> (based on mso_site test case) +# + +# 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(false) }}' + output_level: '{{ mso_output_level | default("info") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Remove schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Ensure tenant ansible_test exist + mso_tenant: &tenant_present + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + state: present + +- name: Ensure schema 1 with Template 1 exist + mso_schema_template: &schema_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template 1 + state: present + +- name: Ensure schema 1 with Template 2 exist + mso_schema_template: + <<: *schema_present + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template 2 + state: present + +- name: Ensure schema 2 with Template 3 exist + mso_schema_template: + <<: *schema_present + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template 3 + state: present + +- name: Ensure VRF exist + mso_schema_template_vrf: &vrf_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF + layer3_multicast: true + state: present + +- name: Ensure VRF2 exist + mso_schema_template_vrf: + <<: *vrf_present + vrf: VRF2 + state: present + +- name: Ensure VRF3 exist + mso_schema_template_vrf: + <<: *vrf_present + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + vrf: VRF3 + state: present + +- name: Ensure VRF4 exist + mso_schema_template_vrf: + <<: *vrf_present + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + vrf: VRF4 + state: present + +- name: Ensure ANP exist + mso_schema_template_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + state: present + +- name: Ensure ANP2 exist + mso_schema_template_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + anp: ANP2 + state: present + +- name: Ensure ANP3 exist + mso_schema_template_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + anp: ANP3 + state: present + +- name: Ensure Filter 1 exist + mso_schema_template_filter_entry: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + filter: Filter1 + entry: Filter1-Entry + state: present + +- name: Ensure Contract1 exist + mso_schema_template_contract_filter: &contract_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract1 + filter: Filter1 + filter_schema: '{{ mso_schema | default("ansible_test") }}' + filter_template: Template 1 + state: present + +- name: Ensure Filter 2 exist + mso_schema_template_filter_entry: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + filter: Filter2 + entry: Filter2-Entry + state: present + +- name: Ensure Contract2 exist + mso_schema_template_contract_filter: &contract2_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + contract: Contract2 + filter: Filter2 + filter_schema: '{{ mso_schema | default("ansible_test") }}' + filter_template: Template 2 + state: present + +- name: Ensure ansible_test_1 BD exist + mso_schema_template_bd: + <<: *vrf_present + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + bd: ansible_test_1 + vrf: + name: VRF + layer3_multicast: true + state: present + +- name: Ensure ansible_test_2 BD exist + mso_schema_template_bd: + <<: *vrf_present + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + bd: ansible_test_2 + vrf: + name: VRF2 + template: Template 1 + layer3_multicast: true + state: present + +- name: Ensure ansible_test_3 BD exist + mso_schema_template_bd: + <<: *vrf_present + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + bd: ansible_test_3 + vrf: + name: VRF3 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + layer3_multicast: true + state: present + +- name: Ensure ansible_test_4 BD exist + mso_schema_template_bd: + <<: *vrf_present + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + bd: ansible_test_4 + vrf: + name: VRF4 + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + layer3_multicast: true + state: present + +# ADD EPG +- name: Add EPG (check_mode) + mso_schema_template_anp_epg: &epg_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + bd: + name: ansible_test_1 + vrf: + name: VRF + state: present + check_mode: yes + register: cm_add_epg + +- name: Verify cm_add_epg + assert: + that: + - cm_add_epg is changed + - cm_add_epg.previous == {} + - cm_add_epg.current.name == "ansible_test_1" + - cm_add_epg.current.vrfRef.templateName == "Template1" + - cm_add_epg.current.vrfRef.vrfName == "VRF" + - cm_add_epg.current.bdRef.templateName == "Template1" + - cm_add_epg.current.bdRef.bdName == "ansible_test_1" + +- name: Add EPG (normal mode) + mso_schema_template_anp_epg: + <<: *epg_present + register: nm_add_epg + +- name: Verify nm_add_epg + assert: + that: + - nm_add_epg is changed + - nm_add_epg.previous == {} + - nm_add_epg.current.name == "ansible_test_1" + - nm_add_epg.current.vrfRef.templateName == "Template1" + - nm_add_epg.current.vrfRef.vrfName == "VRF" + - nm_add_epg.current.bdRef.templateName == "Template1" + - nm_add_epg.current.bdRef.bdName == "ansible_test_1" + - cm_add_epg.current.vrfRef.schemaId == nm_add_epg.current.vrfRef.schemaId + - cm_add_epg.current.bdRef.schemaId == nm_add_epg.current.bdRef.schemaId + +- name: Add EPG again (check_mode) + mso_schema_template_anp_epg: + <<: *epg_present + check_mode: yes + register: cm_add_epg_again + +- name: Verify cm_add_epg_again + assert: + that: + - cm_add_epg_again is not changed + - cm_add_epg_again.current.name == cm_add_epg_again.previous.name == "ansible_test_1" + - cm_add_epg_again.current.vrfRef.templateName == cm_add_epg_again.previous.vrfRef.templateName == "Template1" + - cm_add_epg_again.current.vrfRef.vrfName == cm_add_epg_again.previous.vrfRef.vrfName == "VRF" + - cm_add_epg_again.current.bdRef.templateName == cm_add_epg_again.previous.bdRef.templateName == "Template1" + - cm_add_epg_again.current.bdRef.bdName == cm_add_epg_again.previous.bdRef.bdName == "ansible_test_1" + - cm_add_epg_again.previous.vrfRef.schemaId == cm_add_epg_again.current.vrfRef.schemaId + - cm_add_epg_again.previous.bdRef.schemaId == cm_add_epg_again.current.bdRef.schemaId + + +- name: Add EPG again (normal mode) + mso_schema_template_anp_epg: + <<: *epg_present + register: nm_add_epg_again + +- name: Verify nm_add_epg_again + assert: + that: + - nm_add_epg_again is not changed + - nm_add_epg_again.current.name == nm_add_epg_again.previous.name == "ansible_test_1" + - nm_add_epg_again.current.vrfRef.templateName == nm_add_epg_again.previous.vrfRef.templateName == "Template1" + - nm_add_epg_again.current.vrfRef.vrfName == nm_add_epg_again.previous.vrfRef.vrfName == "VRF" + - nm_add_epg_again.current.bdRef.templateName == nm_add_epg_again.previous.bdRef.templateName == "Template1" + - nm_add_epg_again.current.bdRef.bdName == nm_add_epg_again.previous.bdRef.bdName == "ansible_test_1" + - nm_add_epg_again.previous.vrfRef.schemaId == nm_add_epg_again.current.vrfRef.schemaId + - nm_add_epg_again.previous.bdRef.schemaId == nm_add_epg_again.current.bdRef.schemaId + +- name: Add EPG 2 (normal mode) + mso_schema_template_anp_epg: + <<: *epg_present + schema: '{{ mso_schema | default("ansible_test") }}' + epg: ansible_test_2 + +- name: Add EPG 3 in template of schema 1(normal mode) + mso_schema_template_anp_epg: &epg_schema_1_template_2 + <<: *epg_present + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + anp: ANP2 + epg: ansible_test_3 + bd: + name: ansible_test_3 + template: Template 2 + vrf: + name: VRF3 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + useg_epg: true + intra_epg_isolation: enforced + intersite_multicast_source: true + proxy_arp: true + preferred_group: true + subnets: + - subnet: 10.0.0.128/24 + - subnet: 10.0.1.254/24 + description: 1234567890 + - subnet: 172.16.0.1/24 + description: "My description for a subnet" + scope: public + shared: true + no_default_gateway: false + - ip: 192.168.0.254/24 + description: "My description for a subnet" + scope: private + shared: false + no_default_gateway: true + register: nm_add_epg_3 + +- name: Add EPG 4 in template3 of schema 2(normal mode) + mso_schema_template_anp_epg: &epg_schema_2_template_3 + <<: *epg_present + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + anp: ANP3 + epg: ansible_test_4 + bd: + name: ansible_test_4 + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + vrf: + name: VRF4 + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + register: nm_add_epg_4 + +- name: Verify nm_add_epg_3 and nm_add_epg_4 + assert: + that: + - nm_add_epg_3 is changed + - nm_add_epg_4 is changed + - nm_add_epg_3.current.name == "ansible_test_3" + - nm_add_epg_4.current.name == "ansible_test_4" + - nm_add_epg_3.current.vrfRef.templateName == "Template2" + - nm_add_epg_4.current.vrfRef.templateName == "Template3" + - nm_add_epg_3.current.vrfRef.vrfName == "VRF3" + - nm_add_epg_4.current.vrfRef.vrfName == "VRF4" + - nm_add_epg_3.current.bdRef.templateName == "Template2" + - nm_add_epg_4.current.bdRef.templateName == "Template3" + - nm_add_epg_3.current.bdRef.bdName == "ansible_test_3" + - nm_add_epg_4.current.bdRef.bdName == "ansible_test_4" + - nm_add_epg_3.current.uSegEpg == true + - nm_add_epg_3.current.intraEpg == 'enforced' + - nm_add_epg_3.current.mCastSource == true + - nm_add_epg_3.current.proxyArp == true + - nm_add_epg_3.current.preferredGroup == true + - nm_add_epg_3.current.subnets[0].description == "10.0.0.128/24" + - nm_add_epg_3.current.subnets[0].ip == "10.0.0.128/24" + - nm_add_epg_3.current.subnets[0].noDefaultGateway == false + - nm_add_epg_3.current.subnets[0].scope == "private" + - nm_add_epg_3.current.subnets[0].shared == false + - nm_add_epg_3.current.subnets[1].description == "1234567890" + - nm_add_epg_3.current.subnets[1].ip == "10.0.1.254/24" + - nm_add_epg_3.current.subnets[1].noDefaultGateway == false + - nm_add_epg_3.current.subnets[1].scope == "private" + - nm_add_epg_3.current.subnets[1].shared == false + - nm_add_epg_3.current.subnets[2].description == "My description for a subnet" + - nm_add_epg_3.current.subnets[2].ip == "172.16.0.1/24" + - nm_add_epg_3.current.subnets[2].noDefaultGateway == false + - nm_add_epg_3.current.subnets[2].scope == "public" + - nm_add_epg_3.current.subnets[2].shared == true + - nm_add_epg_3.current.subnets[3].description == "My description for a subnet" + - nm_add_epg_3.current.subnets[3].ip == "192.168.0.254/24" + - nm_add_epg_3.current.subnets[3].noDefaultGateway == true + - nm_add_epg_3.current.subnets[3].scope == "private" + - nm_add_epg_3.current.subnets[3].shared == false + +# CHANGE EPG +- name: Change EPG (check_mode) + mso_schema_template_anp_epg: + <<: *epg_present + vrf: + name: VRF2 + bd: + name: ansible_test_2 + check_mode: yes + register: cm_change_epg + +- name: Verify cm_change_epg + assert: + that: + - cm_change_epg is changed + - cm_change_epg.current.name == 'ansible_test_1' + - cm_change_epg.current.vrfRef.vrfName == 'VRF2' + - cm_change_epg.current.bdRef.templateName == cm_change_epg.current.vrfRef.templateName == "Template1" + - cm_change_epg.current.vrfRef.schemaId == cm_change_epg.previous.vrfRef.schemaId + - cm_change_epg.current.bdRef.bdName == 'ansible_test_2' + - cm_change_epg.current.bdRef.schemaId == cm_change_epg.previous.bdRef.schemaId + +- name: Change EPG (normal mode) + mso_schema_template_anp_epg: + <<: *epg_present + vrf: + name: VRF2 + bd: + name: ansible_test_2 + output_level: debug + register: nm_change_epg + +- name: Verify nm_change_epg + assert: + that: + - nm_change_epg is changed + - nm_change_epg.current.name == 'ansible_test_1' + - nm_change_epg.current.vrfRef.vrfName == 'VRF2' + - nm_change_epg.current.bdRef.templateName == nm_change_epg.current.vrfRef.templateName == "Template1" + - nm_change_epg.current.vrfRef.schemaId == nm_change_epg.previous.vrfRef.schemaId + - nm_change_epg.current.bdRef.bdName == 'ansible_test_2' + - nm_change_epg.current.bdRef.schemaId == nm_change_epg.previous.bdRef.schemaId + +- name: Change EPG again (check_mode) + mso_schema_template_anp_epg: + <<: *epg_present + vrf: + name: VRF2 + bd: + name: ansible_test_2 + check_mode: yes + register: cm_change_epg_again + +- name: Verify cm_change_epg_again + assert: + that: + - cm_change_epg_again is not changed + - cm_change_epg_again.current.name == 'ansible_test_1' + - cm_change_epg_again.current.vrfRef.vrfName == 'VRF2' + - cm_change_epg_again.current.vrfRef.templateName == cm_change_epg_again.current.bdRef.templateName == "Template1" + - cm_change_epg_again.current.vrfRef.schemaId == cm_change_epg_again.previous.vrfRef.schemaId + - cm_change_epg_again.current.bdRef.bdName == 'ansible_test_2' + - cm_change_epg_again.current.bdRef.schemaId == cm_change_epg_again.previous.bdRef.schemaId + +- name: Change EPG again (normal mode) + mso_schema_template_anp_epg: + <<: *epg_present + vrf: + name: VRF2 + bd: + name: ansible_test_2 + register: nm_change_epg_again + +- name: Verify nm_change_epg_again + assert: + that: + - nm_change_epg_again is not changed + - nm_change_epg_again.current.name == 'ansible_test_1' + - nm_change_epg_again.current.vrfRef.vrfName == 'VRF2' + - nm_change_epg_again.current.vrfRef.templateName == nm_change_epg_again.current.bdRef.templateName == "Template1" + - nm_change_epg_again.current.vrfRef.schemaId == nm_change_epg_again.previous.vrfRef.schemaId + - nm_change_epg_again.current.bdRef.bdName == 'ansible_test_2' + - nm_change_epg_again.current.bdRef.schemaId == nm_change_epg_again.previous.bdRef.schemaId + +- name: Change EPG to VRF in different template (normal mode) + mso_schema_template_anp_epg: + <<: *epg_schema_1_template_2 + vrf: + name: VRF + template: Template 1 + bd: + name: ansible_test_1 + template: Template 1 + register: nm_change_epg_vrf3 + +- name: Change EPG 4 to VRF (normal mode) + mso_schema_template_anp_epg: + <<: *epg_schema_2_template_3 + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + anp: ANP3 + epg: ansible_test_4 + vrf: + name: VRF + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + bd: + name: ansible_test_1 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + register: nm_change_epg_vrf4 + +- name: Verify nm_change_epg_vrf3 and nm_change_epg_vrf4 + assert: + that: + - nm_change_epg_vrf3 is changed + - nm_change_epg_vrf3.current.name == 'ansible_test_3' + - nm_change_epg_vrf4.current.name == 'ansible_test_4' + - nm_change_epg_vrf3.current.vrfRef.vrfName == 'VRF' + - nm_change_epg_vrf3.current.bdRef.bdName == 'ansible_test_1' + - nm_change_epg_vrf3.current.vrfRef.templateName == nm_change_epg_vrf3.current.bdRef.templateName == "Template1" + - nm_change_epg_vrf4.current.vrfRef.vrfName == 'VRF' + - nm_change_epg_vrf4.current.bdRef.bdName == 'ansible_test_1' + - nm_change_epg_vrf4.current.vrfRef.templateName == nm_change_epg_vrf4.current.bdRef.templateName == "Template1" + +- name: Change EPG 1 settings(normal mode) + mso_schema_template_anp_epg: + <<: *epg_present + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + useg_epg: true + intra_epg_isolation: enforced + intersite_multicast_source: true + proxy_arp: true + preferred_group: true + subnets: + - subnet: 10.1.0.128/24 + - subnet: 10.1.1.254/24 + description: 1234567890 + - subnet: 172.17.0.1/24 + description: "My description for a subnet" + scope: public + shared: true + no_default_gateway: false + - ip: 192.168.1.254/24 + description: "My description for a subnet" + scope: private + shared: false + no_default_gateway: true + register: nm_change_epg_1_settings + +- name: Change EPG 1 subnets (normal mode) + mso_schema_template_anp_epg: + <<: *epg_present + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + useg_epg: true + intra_epg_isolation: enforced + intersite_multicast_source: true + proxy_arp: true + preferred_group: true + subnets: + - subnet: 10.1.0.127/24 + - subnet: 172.17.0.1/24 + description: "New description for a subnet" + scope: private + shared: false + no_default_gateway: false + - ip: 192.168.1.254/24 + description: "My description for a subnet" + scope: private + shared: false + no_default_gateway: false + register: nm_change_epg_1_subnets + +- name: Verify nm_change_epg_1_subnets + assert: + that: + - nm_change_epg_1_settings is changed + - nm_change_epg_1_settings.current.name == "ansible_test_1" + - nm_change_epg_1_settings.current.vrfRef.templateName == nm_change_epg_1_settings.current.bdRef.templateName == "Template1" + - nm_change_epg_1_settings.current.vrfRef.vrfName == "VRF" + - nm_change_epg_1_settings.current.bdRef.bdName == "ansible_test_1" + - nm_change_epg_1_settings.current.uSegEpg == true + - nm_change_epg_1_settings.current.intraEpg == 'enforced' + - nm_change_epg_1_settings.current.mCastSource == true + - nm_change_epg_1_settings.current.proxyArp == true + - nm_change_epg_1_settings.current.preferredGroup == true + - nm_change_epg_1_settings.current.subnets[0].description == "10.1.0.128/24" + - nm_change_epg_1_settings.current.subnets[0].ip == "10.1.0.128/24" + - nm_change_epg_1_settings.current.subnets[0].noDefaultGateway == false + - nm_change_epg_1_settings.current.subnets[0].scope == "private" + - nm_change_epg_1_settings.current.subnets[0].shared == false + - nm_change_epg_1_settings.current.subnets[1].description == "1234567890" + - nm_change_epg_1_settings.current.subnets[1].ip == "10.1.1.254/24" + - nm_change_epg_1_settings.current.subnets[1].noDefaultGateway == false + - nm_change_epg_1_settings.current.subnets[1].scope == "private" + - nm_change_epg_1_settings.current.subnets[1].shared == false + - nm_change_epg_1_settings.current.subnets[2].description == "My description for a subnet" + - nm_change_epg_1_settings.current.subnets[2].ip == "172.17.0.1/24" + - nm_change_epg_1_settings.current.subnets[2].noDefaultGateway == false + - nm_change_epg_1_settings.current.subnets[2].scope == "public" + - nm_change_epg_1_settings.current.subnets[2].shared == true + - nm_change_epg_1_settings.current.subnets[3].description == "My description for a subnet" + - nm_change_epg_1_settings.current.subnets[3].ip == "192.168.1.254/24" + - nm_change_epg_1_settings.current.subnets[3].noDefaultGateway == true + - nm_change_epg_1_settings.current.subnets[3].scope == "private" + - nm_change_epg_1_settings.current.subnets[3].shared == false + - nm_change_epg_1_subnets is changed + - nm_change_epg_1_subnets.current.subnets | length == 3 + - nm_change_epg_1_subnets.current.name == "ansible_test_1" + - nm_change_epg_1_subnets.current.vrfRef.templateName == nm_change_epg_1_subnets.current.bdRef.templateName == "Template1" + - nm_change_epg_1_subnets.current.vrfRef.vrfName == "VRF" + - nm_change_epg_1_subnets.current.bdRef.bdName == "ansible_test_1" + - nm_change_epg_1_subnets.current.uSegEpg == true + - nm_change_epg_1_subnets.current.intraEpg == 'enforced' + - nm_change_epg_1_subnets.current.mCastSource == true + - nm_change_epg_1_subnets.current.proxyArp == true + - nm_change_epg_1_subnets.current.preferredGroup == true + - nm_change_epg_1_subnets.current.subnets[0].description == "10.1.0.127/24" + - nm_change_epg_1_subnets.current.subnets[0].ip == "10.1.0.127/24" + - nm_change_epg_1_subnets.current.subnets[0].noDefaultGateway == false + - nm_change_epg_1_subnets.current.subnets[0].scope == "private" + - nm_change_epg_1_subnets.current.subnets[0].shared == false + - nm_change_epg_1_subnets.current.subnets[1].description == "New description for a subnet" + - nm_change_epg_1_subnets.current.subnets[1].ip == "172.17.0.1/24" + - nm_change_epg_1_subnets.current.subnets[1].noDefaultGateway == false + - nm_change_epg_1_subnets.current.subnets[1].scope == "private" + - nm_change_epg_1_subnets.current.subnets[1].shared == false + - nm_change_epg_1_subnets.current.subnets[2].description == "My description for a subnet" + - nm_change_epg_1_subnets.current.subnets[2].ip == "192.168.1.254/24" + - nm_change_epg_1_subnets.current.subnets[2].noDefaultGateway == false + - nm_change_epg_1_subnets.current.subnets[2].scope == "private" + - nm_change_epg_1_subnets.current.subnets[2].shared == false + + +# # QUERY ALL EPGs +- name: Query all EPGs in an ANP (check_mode) + mso_schema_template_anp_epg: &epg_query + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + state: query + check_mode: yes + register: cm_query_all_epgs + +- name: Query all EPGs (normal mode) + mso_schema_template_anp_epg: + <<: *epg_query + register: nm_query_all_epgs + +- name: Verify query_all_epgs + assert: + that: + - cm_query_all_epgs is not changed + - nm_query_all_epgs is not changed + - cm_query_all_epgs.current | length == nm_query_all_epgs.current | length == 2 + + +# QUERY AN EPG +- name: Query EPG 1 (check_mode) + mso_schema_template_anp_epg: + <<: *epg_query + epg: ansible_test_1 + check_mode: yes + register: cm_query_epg_1 + +- name: Query EPG 1 (normal mode) + mso_schema_template_anp_epg: + <<: *epg_query + epg: ansible_test_1 + register: nm_query_epg_1 + +- name: Query EPG 3 (normal mode) + mso_schema_template_anp_epg: + <<: *epg_query + template: Template 2 + anp: ANP2 + epg: ansible_test_3 + register: nm_query_epg_3 + +- name: Query EPG 4 (normal mode) + mso_schema_template_anp_epg: + <<: *epg_query + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + anp: ANP3 + epg: ansible_test_4 + register: nm_query_epg_4 + +- name: Verify query_epg_x + assert: + that: + - cm_query_epg_1 is not changed + - nm_query_epg_1 is not changed + - nm_query_epg_3 is not changed + - nm_query_epg_4 is not changed + - nm_query_epg_1.current.subnets | length == 3 + - nm_query_epg_1.current.name == "ansible_test_1" + - nm_query_epg_1.current.vrfRef.templateName == nm_query_epg_1.current.bdRef.templateName == "Template1" + - nm_query_epg_1.current.vrfRef.vrfName == "VRF" + - nm_query_epg_1.current.bdRef.bdName == "ansible_test_1" + - nm_query_epg_1.current.uSegEpg == true + - nm_query_epg_1.current.intraEpg == 'enforced' + - nm_query_epg_1.current.mCastSource == true + - nm_query_epg_1.current.proxyArp == true + - nm_query_epg_1.current.preferredGroup == true + - nm_query_epg_1.current.subnets[0].description == "10.1.0.127/24" + - nm_query_epg_1.current.subnets[0].ip == "10.1.0.127/24" + - nm_query_epg_1.current.subnets[0].noDefaultGateway == false + - nm_query_epg_1.current.subnets[0].scope == "private" + - nm_query_epg_1.current.subnets[0].shared == false + - nm_query_epg_1.current.subnets[1].description == "New description for a subnet" + - nm_query_epg_1.current.subnets[1].ip == "172.17.0.1/24" + - nm_query_epg_1.current.subnets[1].noDefaultGateway == false + - nm_query_epg_1.current.subnets[1].scope == "private" + - nm_query_epg_1.current.subnets[1].shared == false + - nm_query_epg_1.current.subnets[2].description == "My description for a subnet" + - nm_query_epg_1.current.subnets[2].ip == "192.168.1.254/24" + - nm_query_epg_1.current.subnets[2].noDefaultGateway == false + - nm_query_epg_1.current.subnets[2].scope == "private" + - nm_query_epg_1.current.subnets[2].shared == false + - nm_query_epg_3.current.name == "ansible_test_3" + - nm_query_epg_4.current.name == "ansible_test_4" + - nm_query_epg_3.current.vrfRef.templateName == nm_query_epg_4.current.vrfRef.templateName == "Template1" + - nm_query_epg_3.current.vrfRef.vrfName == nm_query_epg_4.current.vrfRef.vrfName == "VRF" + - nm_query_epg_3.current.bdRef.templateName == nm_query_epg_4.current.bdRef.templateName == "Template1" + - nm_query_epg_3.current.bdRef.bdName == nm_query_epg_4.current.bdRef.bdName == "ansible_test_1" + - nm_query_epg_3.current.uSegEpg == true + - nm_query_epg_3.current.intraEpg == 'enforced' + - nm_query_epg_3.current.mCastSource == true + - nm_query_epg_3.current.proxyArp == true + - nm_query_epg_3.current.preferredGroup == true + - nm_query_epg_3.current.subnets[0].description == "10.0.0.128/24" + - nm_query_epg_3.current.subnets[0].ip == "10.0.0.128/24" + - nm_query_epg_3.current.subnets[0].noDefaultGateway == false + - nm_query_epg_3.current.subnets[0].scope == "private" + - nm_query_epg_3.current.subnets[0].shared == false + - nm_query_epg_3.current.subnets[1].description == "1234567890" + - nm_query_epg_3.current.subnets[1].ip == "10.0.1.254/24" + - nm_query_epg_3.current.subnets[1].noDefaultGateway == false + - nm_query_epg_3.current.subnets[1].scope == "private" + - nm_query_epg_3.current.subnets[1].shared == false + - nm_query_epg_3.current.subnets[2].description == "My description for a subnet" + - nm_query_epg_3.current.subnets[2].ip == "172.16.0.1/24" + - nm_query_epg_3.current.subnets[2].noDefaultGateway == false + - nm_query_epg_3.current.subnets[2].scope == "public" + - nm_query_epg_3.current.subnets[2].shared == true + - nm_query_epg_3.current.subnets[3].description == "My description for a subnet" + - nm_query_epg_3.current.subnets[3].ip == "192.168.0.254/24" + - nm_query_epg_3.current.subnets[3].noDefaultGateway == true + - nm_query_epg_3.current.subnets[3].scope == "private" + - nm_query_epg_3.current.subnets[3].shared == false + +# REMOVE EPG +- name: Remove EPG (check_mode) + mso_schema_template_anp_epg: + <<: *epg_present + state: absent + check_mode: yes + register: cm_remove_epg + +- name: Verify cm_remove_epg + assert: + that: + - cm_remove_epg is changed + - cm_remove_epg.current == {} + +- name: Remove EPG (normal mode) + mso_schema_template_anp_epg: + <<: *epg_present + state: absent + register: nm_remove_epg + +- name: Verify nm_remove_epg + assert: + that: + - nm_remove_epg is changed + - nm_remove_epg.current == {} + +- name: Remove EPG again (check_mode) + mso_schema_template_anp_epg: + <<: *epg_present + state: absent + check_mode: yes + register: cm_remove_epg_again + +- name: Verify cm_remove_epg_again + assert: + that: + - cm_remove_epg_again is not changed + - cm_remove_epg_again.current == {} + +- name: Remove EPG again (normal mode) + mso_schema_template_anp_epg: + <<: *epg_present + state: absent + register: nm_remove_epg_again + +- name: Verify nm_remove_epg_again + assert: + that: + - nm_remove_epg_again is not changed + - nm_remove_epg_again.current == {} + +- name: Remove EPG (normal mode) + mso_schema_template_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + state: absent + ignore_errors: yes + +# Add EPG when MSO version >= 3.3 +- name: Execute tasks only for MSO version >= 3.3 + when: + - version.current.version is version('3.3', '>=') + block: + - name: Add EPG (for version greater than 3.3) + mso_schema_template_anp_epg: &new_epg + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + description: 'Description of ANP EPG' + state: present + register: add_epg_desc + + - name: Verify Add description + assert: + that: + - add_epg_desc is changed + - add_epg_desc.current.description == "Description of ANP EPG" + + - name: Remove EPG (for version greater than 3.3) + mso_schema_template_anp_epg: + <<: *new_epg + state: absent + +- name: Execute tasks only for MSO version >= 4.0 + when: + - version.current.version is version('4.0', '>=') + block: + - name: Add EPG service type parameters (for version greater than 4.0) + mso_schema_template_anp_epg: + <<: *new_epg + epg_type: 'service' + deployment_type: 'third_party' + service_type: 'Azure-Storage' + access_type: 'private' + register: service_type_epg + + - name: Add EPG service type parameters (for version greater than 4.0) with error + mso_schema_template_anp_epg: + <<: *new_epg + epg_type: 'service' + deployment_type: 'third_party' + service_type: 'Azure-Storage' + access_type: 'public_and_private' + ignore_errors: yes + register: service_type_epg_error + + - name: Verify service type error + assert: + that: + - service_type_epg_error.msg == "MSO Error 400{{':'}} EPG{{':'}} ansible_test_1 in Schema{{':'}} ansible_test , Template{{':'}} Template1 DeploymentType{{':'}} saas, AccessType {{':'}}publicAndPrivateType, Combination is not supported" + +# Add EPG when MSO version >= 3.3 and < 4.0 +- name: Execute tasks only for MSO version >= 3.3 and < 4.0 + when: + - version.current.version is version('3.3', '>=') + - version.current.version is version('4.0', '<') + block: + - name: Add EPG service type parameters (for version greater than 3.3 and less than 4.0) + mso_schema_template_anp_epg: + <<: *new_epg + epg_type: 'service' + deployment_type: 'third_party' + service_type: 'Azure-Storage' + access_type: 'public_and_private' + register: add_epg + + - name: Get Validation status for service type parameters + mso_schema_validate: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + state: query + ignore_errors: yes + register: query_validate + + - name: Verify validation + assert: + that: + - query_validate is not changed + - query_validate.msg == "MSO Error 400{{':'}} Bad Request{{':'}} Patch Failed, Received{{':'}} For Deployment type 'Third-party' access type 'PublicAndPrivate' is not supported exception while trying to update schema" + + - name: Add EPG service type parameters (for version greater than 3.3 and less than 4.0) + mso_schema_template_anp_epg: + <<: *new_epg + epg_type: 'service' + deployment_type: 'cloud_native' + service_type: 'Azure-Storage' + access_type: 'public' + register: add_epg + + - name: Get Validation status for service type parameters + mso_schema_validate: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + state: query + ignore_errors: yes + register: query_validate + + - name: Verify validation + assert: + that: + - query_validate is not changed + - query_validate.current.result == "true" + + - name: Add new EPG service type parameters (for version greater than 3.3 and less than 4.0) + mso_schema_template_anp_epg: + <<: *new_epg + epg_type: 'service' + deployment_type: 'third_party' + service_type: 'Azure-Storage' + access_type: 'private' + register: add_epg + + - name: Get Validation status for service type parameters + mso_schema_validate: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + state: query + ignore_errors: yes + register: query_validate + + - name: Verify validation + assert: + that: + - query_validate is not changed + - query_validate.current.result == "true" + +# Add QoS level to EPG +- name: Add EPG (for version greater than 3.1) + mso_schema_template_anp_epg: + <<: *epg_present + name: ansible_test_5 + qos_level: 'level2' + register: add_epg + when: version.current.version is version('3.1', '>=') + +- name: Verify Add contract for version greater than 3.1 + assert: + that: + - add_epg is changed + when: version.current.version is version('3.1', '>=') + +# QUERY NON-EXISTING EPG +- name: Query non-existing EPG (check_mode) + mso_schema_template_anp_epg: + <<: *epg_query + epg: non_existing_epg + check_mode: yes + ignore_errors: yes + register: cm_query_non_epg + +- name: Query non-existing EPG (normal mode) + mso_schema_template_anp_epg: + <<: *epg_query + epg: non_existing_epg + ignore_errors: yes + register: nm_query_non_epg + +- name: Verify query_non_epg + assert: + that: + - cm_query_non_epg is not changed + - nm_query_non_epg is not changed + - cm_query_non_epg == nm_query_non_epg + - cm_query_non_epg.msg == nm_query_non_epg.msg == "EPG 'non_existing_epg' not found" + +# QUERY NON-EXISTING ANP +- name: Query non-existing ANP (check_mode) + mso_schema_template_anp_epg: + <<: *epg_query + anp: non_existing_anp + check_mode: yes + ignore_errors: yes + register: cm_query_non_anp + +- name: Query non-existing ANP (normal mode) + mso_schema_template_anp_epg: + <<: *epg_query + anp: non_existing_anp + ignore_errors: yes + register: nm_query_non_anp + +- name: Verify query_non_anp + assert: + that: + - cm_query_non_anp is not changed + - nm_query_non_anp is not changed + - cm_query_non_anp == nm_query_non_anp + - cm_query_non_anp.msg == nm_query_non_anp.msg == "Provided anp 'non_existing_anp' does not exist. Existing anps{{':'}} ANP" + +# USE A NON-EXISTING STATE +- name: Non-existing state for EPG (check_mode) + mso_schema_template_anp_epg: + <<: *epg_query + epg: ansible_test_2 + state: non-existing-state + check_mode: yes + ignore_errors: yes + register: cm_non_existing_state + +- name: Non-existing state for EPG (normal_mode) + mso_schema_template_anp_epg: + <<: *epg_query + epg: ansible_test_2 + state: non-existing-state + ignore_errors: yes + register: nm_non_existing_state + +- name: Verify non_existing_state + assert: + that: + - cm_non_existing_state is not changed + - nm_non_existing_state is not changed + - cm_non_existing_state == nm_non_existing_state + - cm_non_existing_state.msg == nm_non_existing_state.msg == "value of state must be one of{{':'}} absent, present, query, got{{':'}} non-existing-state" + +# USE A NON-EXISTING SCHEMA +- name: Non-existing schema for EPG (check_mode) + mso_schema_template_anp_epg: + <<: *epg_present + schema: non-existing-schema + epg: ansible_test_2 + check_mode: yes + ignore_errors: yes + register: cm_non_existing_schema + +- name: Non-existing schema for EPG (normal_mode) + mso_schema_template_anp_epg: + <<: *epg_present + schema: non-existing-schema + epg: ansible_test_2 + ignore_errors: yes + register: nm_non_existing_schema + +- name: Verify non_existing_schema + assert: + that: + - cm_non_existing_schema is not changed + - nm_non_existing_schema is not changed + - cm_non_existing_schema == nm_non_existing_schema + - cm_non_existing_schema.msg == nm_non_existing_schema.msg == "Provided schema 'non-existing-schema' does not exist." + +- name: Non-existing BD schema for EPG (check_mode) + mso_schema_template_anp_epg: + <<: *epg_present + epg: ansible_test_2 + bd: + name: ansible_test_1 + schema: non-existing-schema + template: Template 1 + check_mode: yes + ignore_errors: yes + register: cm_non_existing_bd_schema + +- name: Non-existing BD schema for EPG (normal_mode) + mso_schema_template_anp_epg: + <<: *epg_present + epg: ansible_test_2 + bd: + name: ansible_test_1 + schema: non-existing-schema + template: Template 1 + ignore_errors: yes + register: nm_non_existing_bd_schema + +- name: Verify non_existing_bd_schema + assert: + that: + - cm_non_existing_bd_schema is not changed + - nm_non_existing_bd_schema is not changed + - cm_non_existing_bd_schema == nm_non_existing_bd_schema + - cm_non_existing_bd_schema.msg == nm_non_existing_bd_schema.msg == "Referenced schema 'non-existing-schema' in bdref does not exist" + +- name: Non-existing VRF schema for EPG (check_mode) + mso_schema_template_anp_epg: + <<: *epg_present + epg: ansible_test_2 + vrf: + name: VRF + schema: non-existing-schema + template: Template 1 + check_mode: yes + ignore_errors: yes + register: cm_non_existing_vrf_schema + +- name: Non-existing VRF schema for EPG (normal_mode) + mso_schema_template_anp_epg: + <<: *epg_present + epg: ansible_test_2 + vrf: + name: VRF + schema: non-existing-schema + template: Template 1 + ignore_errors: yes + register: nm_non_existing_vrf_schema + +- name: Verify non_existing_vrf_schema + assert: + that: + - cm_non_existing_vrf_schema is not changed + - nm_non_existing_vrf_schema is not changed + - cm_non_existing_vrf_schema == nm_non_existing_vrf_schema + - cm_non_existing_vrf_schema.msg == nm_non_existing_vrf_schema.msg == "Referenced schema 'non-existing-schema' in vrfref does not exist" + +# USE A NON-EXISTING TEMPLATE +- name: Non-existing template for EPG (check_mode) + mso_schema_template_anp_epg: + <<: *epg_present + template: non-existing-template + epg: ansible_test_2 + check_mode: yes + ignore_errors: yes + register: cm_non_existing_template + +- name: Non-existing template for EPG (normal_mode) + mso_schema_template_anp_epg: + <<: *epg_present + template: non-existing-template + epg: ansible_test_2 + ignore_errors: yes + register: nm_non_existing_template + +- name: Verify non_existing_template + assert: + that: + - cm_non_existing_template is not changed + - nm_non_existing_template is not changed + - cm_non_existing_template == nm_non_existing_template + - cm_non_existing_template.msg == nm_non_existing_template.msg == "Provided template 'non-existing-template' does not exist. Existing templates{{':'}} Template1, Template2" + +# Checking if contract are removed after re-applying an EPG. (#13 | #62137) +- name: Reset EPG 3 in template of schema 1 to avoid cyclic circles (normal mode) + mso_schema_template_anp_epg: + <<: *epg_schema_1_template_2 + register: nm_add_epg_3 + +- name: Add Contracts to EPG 2 + mso_schema_template_anp_epg_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_2 + contract: + name: '{{ item.name }}' + template: '{{ item.template }}' + type: '{{ item.type }}' + state: present + loop: + - { name: Contract1, template: Template 1, type: consumer } + - { name: Contract1, template: Template 1, type: provider } + - { name: Contract2, template: Template 2, type: consumer } + - { name: Contract2, template: Template 2, type: provider } + +- name: Query EPG 2 + mso_schema_template_anp_epg: + <<: *epg_query + epg: ansible_test_2 + register: nm_query_contract_epg + +- name: Verify that 4 contracts are in EPG 2 using nm_query_contract_epg + assert: + that: + - nm_query_contract_epg.current.contractRelationships | length == 4 + +- name: Add EPG 2 again (normal_mode) + mso_schema_template_anp_epg: + <<: *epg_present + epg: ansible_test_2 + register: nm_add_epg_2_again + +- name: Verify that EPG 2 didn't change + assert: + that: + - nm_add_epg_2_again is not changed + +- name: Query EPG 2 + mso_schema_template_anp_epg: + <<: *epg_query + epg: ansible_test_2 + register: nm_query_contract_epg + +- name: Verify that 4 contracts are in EPG 2 using nm_query_contract_epg + assert: + that: + - nm_query_contract_epg.current.contractRelationships | length == 4 + +# Checking if issue when querying EPG and VRF is not defined (#66) +- name: Add new test EPG 3 (normal mode) + mso_schema_template_anp_epg: &epg_present_2 + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_3 + bd: + name: ansible_test_1 + register: nm_add_epg_3 + +- name: Verify nm_add_epg_3 + assert: + that: + - nm_add_epg_3 is changed + - nm_add_epg_3.current.name == 'ansible_test_3' + - "'vrfRef' not in nm_add_epg_3.current" + +- name: Query test EPG 3 + mso_schema_template_anp_epg: + <<: *epg_present_2 + register: nm_query_epg_3 + +- name: Verify nm_query_epg_3 + assert: + that: + - nm_query_epg_3 is not changed + - nm_query_epg_3.current.name == 'ansible_test_3' + - "'vrfRef' not in nm_query_epg_3.current" + +# Checking if modifying an EPG with existing contracts throw an MSO error. (#82) +- name: Change EPG 2 to add VRF (normal_mode) + mso_schema_template_anp_epg: + <<: *epg_present + epg: ansible_test_2 + vrf: + name: VRF2 + bd: + name: ansible_test_2 + register: nm_change_epg_2_vrf + +- name: Verify that EPG 2 did change + assert: + that: + - nm_change_epg_2_vrf is changed + - nm_change_epg_2_vrf.current.vrfRef.templateName == "Template1" + - nm_change_epg_2_vrf.current.vrfRef.vrfName == "VRF2" + - nm_change_epg_2_vrf.current.bdRef.bdName == "ansible_test_2" + +- name: Query EPG 2 + mso_schema_template_anp_epg: + <<: *epg_query + epg: ansible_test_2 + register: nm_query_contract_epg_2 + +- name: Verify that 4 contracts are in EPG 2 using nm_query_contract_epg_2 + assert: + that: + - nm_query_contract_epg_2.current.contractRelationships | length == 4
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_anp_epg_contract/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_anp_epg_contract/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_anp_epg_contract/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_contract/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_anp_epg_contract/tasks/main.yml new file mode 100644 index 00000000..82e6b203 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_anp_epg_contract/tasks/main.yml @@ -0,0 +1,620 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Lionel Hercot (@lhercot) <lhercot@cisco.com> +# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> (based on mso_site test case) +# + +# 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 + +- 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(false) }}' + output_level: '{{ mso_output_level | default("info") }}' + +# CLEAN ENVIRONMENT +# - name: Ensure site exist +# mso_site: &site_present +# 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") }}' +# site: '{{ mso_site | default("ansible_test") }}' +# apic_username: '{{ apic_username }}' +# apic_password: '{{ apic_password }}' +# apic_site_id: '{{ apic_site_id | default(101) }}' +# urls: +# - https://{{ apic_hostname }} +# state: present + +- name: Remove schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Ensure tenant ansible_test exist + mso_tenant: &tenant_present + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + # sites: + # - '{{ mso_site | default("ansible_test") }}' + state: present + +- name: Ensure schema 1 with Template 1 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template 1 + state: present + +- name: Ensure schema 1 with Template 2 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template 2 + state: present + +- name: Ensure schema 2 with Template 3 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template 3 + state: present + +- name: Ensure ANP exist + mso_schema_template_anp: + <<: *mso_info + schema: '{{ item.schema }}' + template: '{{ item.template }}' + anp: ANP + state: present + loop: + - { schema: '{{ mso_schema | default("ansible_test") }}', template: 'Template 1' } + - { schema: '{{ mso_schema | default("ansible_test") }}_2', template: 'Template 3' } + +- name: Ensure Filter 1 exist + mso_schema_template_filter_entry: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + filter: Filter1 + entry: Filter1-Entry + state: present + +- name: Ensure Contract1 exist + mso_schema_template_contract_filter: &contract_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract1 + filter: Filter1 + filter_schema: '{{ mso_schema | default("ansible_test") }}' + filter_template: Template 1 + state: present + +- name: Ensure Filter 2 exist + mso_schema_template_filter_entry: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + filter: Filter2 + entry: Filter2-Entry + state: present + +- name: Ensure Contract2 exist + mso_schema_template_contract_filter: &contract2_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + contract: Contract2 + filter: Filter2 + filter_schema: '{{ mso_schema | default("ansible_test") }}' + filter_template: Template 2 + state: present + +- name: Ensure EPGs exist + mso_schema_template_anp_epg: + <<: *mso_info + schema: '{{ item.schema }}' + template: '{{ item.template }}' + anp: ANP + epg: '{{ item.epg }}' + state: present + loop: + - { schema: '{{ mso_schema | default("ansible_test") }}', template: 'Template 1', epg: 'ansible_test_1' } + - { schema: '{{ mso_schema | default("ansible_test") }}_2', template: 'Template 3', epg: 'ansible_test_3' } + +# ADD Contract to EPG +- name: Add Contract1 to EPG (check_mode) + mso_schema_template_anp_epg_contract: &contract_epg_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + contract: + name: Contract1 + type: consumer + state: present + check_mode: yes + register: cm_add_contract_rel + +- name: Verify cm_add_contract_rel + assert: + that: + - cm_add_contract_rel is changed + - cm_add_contract_rel.previous == {} + - cm_add_contract_rel.current.contractRef.templateName == "Template1" + - cm_add_contract_rel.current.contractRef.contractName == "Contract1" + - cm_add_contract_rel.current.relationshipType == "consumer" + +- name: Add Contract to EPG (normal mode) + mso_schema_template_anp_epg_contract: + <<: *contract_epg_present + register: nm_add_contract_rel + +- name: Verify nm_add_contract_rel + assert: + that: + - nm_add_contract_rel is changed + - nm_add_contract_rel.previous == {} + - nm_add_contract_rel.current.contractRef.templateName == "Template1" + - nm_add_contract_rel.current.contractRef.contractName == "Contract1" + - nm_add_contract_rel.current.relationshipType == "consumer" + - cm_add_contract_rel.current.contractRef.schemaId == nm_add_contract_rel.current.contractRef.schemaId + +- name: Add Contract to EPG again (check_mode) + mso_schema_template_anp_epg_contract: + <<: *contract_epg_present + check_mode: yes + register: cm_add_contract_rel_again + +- name: Verify cm_add_contract_rel_again + assert: + that: + - cm_add_contract_rel_again is not changed + - cm_add_contract_rel_again.previous.contractRef.templateName == "Template1" + - cm_add_contract_rel_again.current.contractRef.templateName == "Template1" + - cm_add_contract_rel_again.previous.contractRef.contractName == "Contract1" + - cm_add_contract_rel_again.current.contractRef.contractName == "Contract1" + - cm_add_contract_rel_again.previous.relationshipType == "consumer" + - cm_add_contract_rel_again.current.relationshipType == "consumer" + - cm_add_contract_rel_again.previous.contractRef.schemaId == cm_add_contract_rel_again.current.contractRef.schemaId + + +- name: Add Contract to EPG again (normal mode) + mso_schema_template_anp_epg_contract: + <<: *contract_epg_present + register: nm_add_contract_rel_again + +- name: Verify nm_add_contract_rel_again + assert: + that: + - nm_add_contract_rel_again is not changed + - nm_add_contract_rel_again.previous.contractRef.templateName == "Template1" + - nm_add_contract_rel_again.current.contractRef.templateName == "Template1" + - nm_add_contract_rel_again.previous.contractRef.contractName == "Contract1" + - nm_add_contract_rel_again.current.contractRef.contractName == "Contract1" + - nm_add_contract_rel_again.previous.relationshipType == "consumer" + - nm_add_contract_rel_again.current.relationshipType == "consumer" + - nm_add_contract_rel_again.previous.contractRef.schemaId == nm_add_contract_rel_again.current.contractRef.schemaId + +- name: Add Contract1 to EPG - provider (normal mode) + mso_schema_template_anp_epg_contract: + <<: *contract_epg_present + contract: + name: Contract1 + type: provider + register: nm_add_contract1_rel_provider + +- name: Add Contract2 to EPG - consumer (normal mode) + mso_schema_template_anp_epg_contract: + <<: *contract_epg_present + contract: + name: Contract2 + template: Template 2 + type: consumer + register: nm_add_contract2_rel_consumer + +- name: Add Contract1 to EPG 3 - provider (normal mode) + mso_schema_template_anp_epg_contract: + <<: *contract_epg_present + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + anp: ANP + epg: ansible_test_3 + contract: + name: Contract1 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + type: provider + register: nm_add_contract3_rel_provider + +- name: Verify nm_add_contract1_rel_provider, nm_add_contract2_rel_consumer and nm_add_contract3_rel_provider + assert: + that: + - nm_add_contract1_rel_provider is changed + - nm_add_contract2_rel_consumer is changed + - nm_add_contract3_rel_provider is changed + - nm_add_contract1_rel_provider.current.contractRef.contractName == nm_add_contract3_rel_provider.current.contractRef.contractName == "Contract1" + - nm_add_contract2_rel_consumer.current.contractRef.contractName == "Contract2" + - nm_add_contract1_rel_provider.current.contractRef.templateName == nm_add_contract3_rel_provider.current.contractRef.templateName == "Template1" + - nm_add_contract2_rel_consumer.current.contractRef.templateName == "Template2" + - nm_add_contract1_rel_provider.current.contractRef.schemaId == nm_add_contract2_rel_consumer.current.contractRef.schemaId == nm_add_contract3_rel_provider.current.contractRef.schemaId + - nm_add_contract2_rel_consumer.current.relationshipType == "consumer" + - nm_add_contract1_rel_provider.current.relationshipType == nm_add_contract3_rel_provider.current.relationshipType == "provider" + +# # QUERY ALL Contract to EPG +- name: Query all contract relationship for EPG (check_mode) + mso_schema_template_anp_epg_contract: &contract_epg_query + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + state: query + check_mode: yes + register: cm_query_all_contract_rels + +- name: Query all contract relationship for EPG (normal mode) + mso_schema_template_anp_epg_contract: + <<: *contract_epg_query + register: nm_query_all_contract_rels + +- name: Verify query_all_contract_rels + assert: + that: + - cm_query_all_contract_rels is not changed + - nm_query_all_contract_rels is not changed + - cm_query_all_contract_rels.current | length == nm_query_all_contract_rels.current | length == 3 + + +# QUERY A Contract to EPG +- name: Query Contract1 relationship for EPG - consumer (check_mode) + mso_schema_template_anp_epg_contract: + <<: *contract_epg_query + contract: + name: Contract1 + type: consumer + check_mode: yes + register: cm_query_contract1_consumer_rel + +- name: Query Contract1 relationship for EPG - consumer (normal mode) + mso_schema_template_anp_epg_contract: + <<: *contract_epg_query + contract: + name: Contract1 + type: consumer + register: nm_query_contract1_consumer_rel + +- name: Query Contract1 relationship for EPG - provider (normal mode) + mso_schema_template_anp_epg_contract: + <<: *contract_epg_query + contract: + name: Contract1 + type: provider + register: nm_query_contract1_provider_rel + +- name: Query Contract1 relationship for EPG - consumer (normal mode) + mso_schema_template_anp_epg_contract: + <<: *contract_epg_query + contract: + name: Contract2 + template: Template 2 + type: consumer + register: nm_query_contract2_consumer_rel + +- name: Query Contract1 relationship for EPG - provider (normal mode) + mso_schema_template_anp_epg_contract: + <<: *contract_epg_query + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + anp: ANP + epg: ansible_test_3 + contract: + name: Contract1 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + type: provider + register: nm_query_contract3_provider_rel + +- name: Verify query_contractX_YYYYY_rel + assert: + that: + - cm_query_contract1_consumer_rel is not changed + - nm_query_contract1_consumer_rel is not changed + - nm_query_contract1_provider_rel is not changed + - nm_query_contract2_consumer_rel is not changed + - nm_query_contract3_provider_rel is not changed + - cm_query_contract1_consumer_rel == nm_query_contract1_consumer_rel + - cm_query_contract1_consumer_rel.current.contractRef.contractName == nm_query_contract1_consumer_rel.current.contractRef.contractName == nm_query_contract1_provider_rel.current.contractRef.contractName == nm_query_contract3_provider_rel.current.contractRef.contractName == "Contract1" + - nm_query_contract2_consumer_rel.current.contractRef.contractName == "Contract2" + - cm_query_contract1_consumer_rel.current.contractRef.templateName == nm_query_contract1_consumer_rel.current.contractRef.templateName == nm_query_contract1_provider_rel.current.contractRef.templateName == nm_query_contract3_provider_rel.current.contractRef.templateName == "Template1" + - nm_query_contract2_consumer_rel.current.contractRef.templateName == "Template2" + - cm_query_contract1_consumer_rel.current.contractRef.schemaId == nm_query_contract1_consumer_rel.current.contractRef.schemaId == nm_query_contract1_provider_rel.current.contractRef.schemaId == nm_query_contract2_consumer_rel.current.contractRef.schemaId == nm_query_contract3_provider_rel.current.contractRef.schemaId + - cm_query_contract1_consumer_rel.current.relationshipType == nm_query_contract1_consumer_rel.current.relationshipType == nm_query_contract2_consumer_rel.current.relationshipType == "consumer" + - nm_query_contract1_provider_rel.current.relationshipType == nm_query_contract3_provider_rel.current.relationshipType == "provider" + + +# REMOVE Contract to EPG +- name: Remove Contract to EPG (check_mode) + mso_schema_template_anp_epg_contract: + <<: *contract_epg_present + state: absent + check_mode: yes + register: cm_remove_contract_rel + +- name: Verify cm_remove_contract_rel + assert: + that: + - cm_remove_contract_rel is changed + - cm_remove_contract_rel.current == {} + +- name: Remove Contract to EPG (normal mode) + mso_schema_template_anp_epg_contract: + <<: *contract_epg_present + state: absent + register: nm_remove_contract_rel + +- name: Verify nm_remove_contract_rel + assert: + that: + - nm_remove_contract_rel is changed + - nm_remove_contract_rel.current == {} + +- name: Remove Contract to EPG again (check_mode) + mso_schema_template_anp_epg_contract: + <<: *contract_epg_present + state: absent + check_mode: yes + register: cm_remove_contract_rel_again + +- name: Verify cm_remove_contract_rel_again + assert: + that: + - cm_remove_contract_rel_again is not changed + - cm_remove_contract_rel_again.current == {} + +- name: Remove Contract to EPG again (normal mode) + mso_schema_template_anp_epg_contract: + <<: *contract_epg_present + state: absent + register: nm_remove_contract_rel_again + +- name: Verify nm_remove_contract_rel_again + assert: + that: + - nm_remove_contract_rel_again is not changed + - nm_remove_contract_rel_again.current == {} + + +# QUERY NON-EXISTING Contract to EPG +- name: Query non-existing contract (check_mode) + mso_schema_template_anp_epg_contract: + <<: *contract_epg_query + contract: + name: non_existing_contract + type: provider + check_mode: yes + ignore_errors: yes + register: cm_query_non_contract + +- name: Query non-existing contract (normal mode) + mso_schema_template_anp_epg_contract: + <<: *contract_epg_query + contract: + name: non_existing_contract + type: provider + ignore_errors: yes + register: nm_query_non_contract + +- name: Verify query_non_contract + assert: + that: + - cm_query_non_contract is not changed + - nm_query_non_contract is not changed + - cm_query_non_contract == nm_query_non_contract + - cm_query_non_contract.msg is match("Contract '/schemas/[0-9a-zA-Z]*/templates/Template1/contracts/non_existing_contract' not found") + - nm_query_non_contract.msg is match("Contract '/schemas/[0-9a-zA-Z]*/templates/Template1/contracts/non_existing_contract' not found") + +# QUERY NON-EXISTING EPG +- name: Query non-existing EPG (check_mode) + mso_schema_template_anp_epg_contract: + <<: *contract_epg_query + epg: non_existing_epg + check_mode: yes + ignore_errors: yes + register: cm_query_non_epg + +- name: Query non-existing EPG (normal mode) + mso_schema_template_anp_epg_contract: + <<: *contract_epg_query + epg: non_existing_epg + ignore_errors: yes + register: nm_query_non_epg + +- name: Verify query_non_epg + assert: + that: + - cm_query_non_epg is not changed + - nm_query_non_epg is not changed + - cm_query_non_epg == nm_query_non_epg + - cm_query_non_epg.msg == nm_query_non_epg.msg == "Provided epg 'non_existing_epg' does not exist. Existing epgs{{':'}} ansible_test_1" + +# QUERY NON-EXISTING ANP +- name: Query non-existing ANP (check_mode) + mso_schema_template_anp_epg_contract: + <<: *contract_epg_query + anp: non_existing_anp + check_mode: yes + ignore_errors: yes + register: cm_query_non_anp + +- name: Query non-existing ANP (normal mode) + mso_schema_template_anp_epg_contract: + <<: *contract_epg_query + anp: non_existing_anp + ignore_errors: yes + register: nm_query_non_anp + +- name: Verify query_non_anp + assert: + that: + - cm_query_non_anp is not changed + - nm_query_non_anp is not changed + - cm_query_non_anp == nm_query_non_anp + - cm_query_non_anp.msg == nm_query_non_anp.msg == "Provided anp 'non_existing_anp' does not exist. Existing anps{{':'}} ANP" + +# USE A NON-EXISTING STATE +- name: Non-existing state for contract relationship (check_mode) + mso_schema_template_anp_epg_contract: + <<: *contract_epg_query + state: non-existing-state + check_mode: yes + ignore_errors: yes + register: cm_non_existing_state + +- name: Non-existing state for contract relationship (normal_mode) + mso_schema_template_anp_epg_contract: + <<: *contract_epg_query + state: non-existing-state + ignore_errors: yes + register: nm_non_existing_state + +- name: Verify non_existing_state + assert: + that: + - cm_non_existing_state is not changed + - nm_non_existing_state is not changed + - cm_non_existing_state == nm_non_existing_state + - cm_non_existing_state.msg == nm_non_existing_state.msg == "value of state must be one of{{':'}} absent, present, query, got{{':'}} non-existing-state" + +# USE A NON-EXISTING SCHEMA +- name: Non-existing schema for contract relationship (check_mode) + mso_schema_template_anp_epg_contract: + <<: *contract_epg_query + schema: non-existing-schema + check_mode: yes + ignore_errors: yes + register: cm_non_existing_schema + +- name: Non-existing schema for contract relationship (normal_mode) + mso_schema_template_anp_epg_contract: + <<: *contract_epg_query + schema: non-existing-schema + ignore_errors: yes + register: nm_non_existing_schema + +- name: Verify non_existing_schema + assert: + that: + - cm_non_existing_schema is not changed + - nm_non_existing_schema is not changed + - cm_non_existing_schema == nm_non_existing_schema + - cm_non_existing_schema.msg == nm_non_existing_schema.msg == "Provided schema 'non-existing-schema' does not exist." + +- name: Non-existing contract schema for contract relationship (check_mode) + mso_schema_template_anp_epg_contract: + <<: *contract_epg_query + contract: + name: Contract1 + schema: non-existing-schema + template: Template 1 + type: provider + check_mode: yes + ignore_errors: yes + register: cm_non_existing_contract_schema + +- name: Non-existing contract schema for contract relationship (normal_mode) + mso_schema_template_anp_epg_contract: + <<: *contract_epg_query + contract: + name: Contract1 + schema: non-existing-schema + template: Template 1 + type: provider + ignore_errors: yes + register: nm_non_existing_contract_schema + +- name: Verify non_existing_contract_schema + assert: + that: + - cm_non_existing_contract_schema is not changed + - nm_non_existing_contract_schema is not changed + - cm_non_existing_contract_schema == nm_non_existing_contract_schema + - cm_non_existing_contract_schema.msg == nm_non_existing_contract_schema.msg == "Provided schema 'non-existing-schema' does not exist." + +# USE A NON-EXISTING TEMPLATE +- name: Non-existing template for contract relationship (check_mode) + mso_schema_template_anp_epg_contract: + <<: *contract_epg_query + template: non-existing-template + check_mode: yes + ignore_errors: yes + register: cm_non_existing_template + +- name: Non-existing template for contract relationship (normal_mode) + mso_schema_template_anp_epg_contract: + <<: *contract_epg_query + template: non-existing-template + ignore_errors: yes + register: nm_non_existing_template + +- name: Verify non_existing_template + assert: + that: + - cm_non_existing_template is not changed + - nm_non_existing_template is not changed + - cm_non_existing_template == nm_non_existing_template + - cm_non_existing_template.msg == nm_non_existing_template.msg == "Provided template 'non-existing-template' does not exist. Existing templates{{':'}} Template1, Template2" + +- name: Non-existing contract template for contract relationship (check_mode) + mso_schema_template_anp_epg_contract: + <<: *contract_epg_query + contract: + name: Contract1 + template: non-existing-template + type: provider + check_mode: yes + ignore_errors: yes + register: cm_non_existing_contract_template + +- name: Non-existing contract template for contract relationship (normal_mode) + mso_schema_template_anp_epg_contract: + <<: *contract_epg_query + contract: + name: Contract1 + template: non-existing-template + type: provider + ignore_errors: yes + register: nm_non_existing_contract_template + +- name: Verify non_existing_contract_template + assert: + that: + - cm_non_existing_contract_template is not changed + - nm_non_existing_contract_template is not changed + - cm_non_existing_contract_template == nm_non_existing_contract_template + - cm_non_existing_contract_template.msg is match("Contract '/schemas/[0-9a-zA-Z]*/templates/non-existing-template/contracts/Contract1' not found") + - nm_non_existing_contract_template.msg is match("Contract '/schemas/[0-9a-zA-Z]*/templates/non-existing-template/contracts/Contract1' not found")
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_anp_epg_selector/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_anp_epg_selector/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_anp_epg_selector/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_selector/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_anp_epg_selector/tasks/main.yml new file mode 100644 index 00000000..8caad6e9 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_anp_epg_selector/tasks/main.yml @@ -0,0 +1,794 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Lionel Hercot (@lhercot) <lhercot@cisco.com> +# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> (based on mso_site test case) +# + +# 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") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +# - name: Ensure site exist +# mso_site: &site_present +# 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") }}' +# site: '{{ mso_site | default("ansible_test") }}' +# apic_username: '{{ apic_username }}' +# apic_password: '{{ apic_password }}' +# apic_site_id: '{{ apic_site_id | default(101) }}' +# urls: +# - https://{{ apic_hostname }} +# state: present + +- name: Remove schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Ensure tenant ansible_test exist + mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + # sites: + # - '{{ mso_site | default("ansible_test") }}' + state: present + +- name: Ensure schema 1 with Template 1 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template 1 + state: present + +- name: Ensure schema 1 with Template 2 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template 2 + state: present + +- name: Ensure schema 2 with Template 3 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template 3 + state: present + +- name: Ensure ANP exist + mso_schema_template_anp: + <<: *mso_info + schema: '{{ item.schema }}' + template: '{{ item.template }}' + anp: ANP + state: present + loop: + - { schema: '{{ mso_schema | default("ansible_test") }}', template: 'Template 1' } + - { schema: '{{ mso_schema | default("ansible_test") }}_2', template: 'Template 3' } + +# ADD EPGs +- name: Ensure EPGs exist + mso_schema_template_anp_epg: + <<: *mso_info + schema: '{{ item.schema }}' + template: '{{ item.template }}' + anp: ANP + epg: '{{ item.epg }}' + state: present + loop: + - { schema: '{{ mso_schema | default("ansible_test") }}', template: 'Template 1', epg: 'ansible_test_1' } + - { schema: '{{ mso_schema | default("ansible_test") }}_2', template: 'Template 3', epg: 'ansible_test_3' } + +# ADD Selector to EPG +- name: Add Selector to EPG (check_mode) + mso_schema_template_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: selector_1 + state: present + check_mode: yes + register: cm_add_selector_1 + +- name: Verify cm_add_selector_1 + assert: + that: + - cm_add_selector_1 is changed + - cm_add_selector_1.previous == {} + - cm_add_selector_1.current.name == "selector_1" + - cm_add_selector_1.current.expressions == [] + +- name: Add Selector 1 to EPG with space in selector name (normal_mode) + mso_schema_template_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: selector 1 + state: present + ignore_errors: yes + register: nm_add_selector1_with_space_in_name + +- name: Verify nm_add_selector1_with_space_in_name + assert: + that: + - nm_add_selector1_with_space_in_name is not changed + - nm_add_selector1_with_space_in_name.msg == "There should not be any space in selector name." + +- name: Add Selector to EPG (normal_mode) + mso_schema_template_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: selector_1 + state: present + register: nm_add_selector_1 + +- name: Verify nm_add_selector_1 + assert: + that: + - nm_add_selector_1 is changed + - nm_add_selector_1.previous == {} + - nm_add_selector_1.current.name == "selector_1" + - nm_add_selector_1.current.expressions == [] + +- name: Add Selector to EPG again (check_mode) + mso_schema_template_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: selector_1 + state: present + check_mode: yes + register: cm_add_selector_1_again + +- name: Verify cm_add_selector_1_again + assert: + that: + - cm_add_selector_1_again is not changed + - cm_add_selector_1_again.previous.name == "selector_1" + - cm_add_selector_1_again.previous.expressions == [] + - cm_add_selector_1_again.current.name == "selector_1" + - cm_add_selector_1_again.current.expressions == [] + +- name: Add Selector to EPG again (normal_mode) + mso_schema_template_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: selector_1 + state: present + register: nm_add_selector_1_again + +- name: Verify nm_add_selector_1_again + assert: + that: + - nm_add_selector_1_again is not changed + - nm_add_selector_1_again.previous.name == "selector_1" + - nm_add_selector_1_again.previous.expressions == [] + - nm_add_selector_1_again.current.name == "selector_1" + - nm_add_selector_1_again.current.expressions == [] + +- name: Add Selector 2 to EPG (check_mode) + mso_schema_template_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: selector_2 + expressions: + - type: expression_1 + operator: in + value: test + state: present + check_mode: yes + register: cm_add_selector_2 + +- name: Verify cm_add_selector_2 + assert: + that: + - cm_add_selector_2 is changed + - cm_add_selector_2.previous == {} + - cm_add_selector_2.current.name == "selector_2" + - cm_add_selector_2.current.expressions[0].key == "Custom:expression_1" + - cm_add_selector_2.current.expressions[0].operator == "in" + - cm_add_selector_2.current.expressions[0].value == "test" + +- name: Add Selector 2 to EPG (normal_mode) + mso_schema_template_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: selector_2 + expressions: + - type: expression_1 + operator: in + value: test + state: present + register: nm_add_selector_2 + +- name: Verify nm_add_selector_2 + assert: + that: + - nm_add_selector_2 is changed + - nm_add_selector_2.previous == {} + - nm_add_selector_2.current.name == "selector_2" + - nm_add_selector_2.current.expressions[0].key == "Custom:expression_1" + - nm_add_selector_2.current.expressions[0].operator == "in" + - nm_add_selector_2.current.expressions[0].value == "test" + +- name: Add Selector 2 to EPG with space in expression type (normal_mode) + mso_schema_template_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: selector_2 + expressions: + - type: expression 1 + operator: in + value: test + state: present + ignore_errors: yes + register: nm_add_selector2_with_space_in_expression_type + +- name: Verify nm_add_selector2_with_space_in_expression_type + assert: + that: + - nm_add_selector2_with_space_in_expression_type is not changed + - nm_add_selector2_with_space_in_expression_type.msg == "There should not be any space in 'type' attribute of expression 'expression 1'" + +- name: Change Selector 2 - keyExist(normal_mode) + mso_schema_template_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: selector_2 + expressions: + - type: expression_5 + operator: has_key + value: test + state: present + ignore_errors: yes + register: nm_change_selector_2_key_exist + +- name: Verify nm_change_selector_2_key_exist + assert: + that: + - nm_change_selector_2_key_exist is not changed + - nm_change_selector_2_key_exist.msg == "Attribute 'value' is not supported for operator 'has_key' in expression 'expression_5'" + +- name: Change Selector 2 - keyNotExist (normal_mode) + mso_schema_template_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: selector_2 + expressions: + - type: expression_6 + operator: does_not_have_key + value: test + state: present + ignore_errors: yes + register: nm_change_selector_2_key_not_exist + +- name: Verify nm_change_selector_2_key_not_exist + assert: + that: + - nm_change_selector_2_key_not_exist is not changed + - nm_change_selector_2_key_not_exist.msg == "Attribute 'value' is not supported for operator 'does_not_have_key' in expression 'expression_6'" + +- name: Change Selector 2 - equals (normal_mode) + mso_schema_template_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: selector_2 + expressions: + - type: expression_6 + operator: equals + state: present + ignore_errors: yes + register: nm_change_selector_2_equals + +- name: Verify nm_change_selector_2_equals + assert: + that: + - nm_change_selector_2_equals is not changed + - nm_change_selector_2_equals.msg == "Attribute 'value' needed for operator 'equals' in expression 'expression_6'" + +- name: Change Selector 2 expressions (normal_mode) + mso_schema_template_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: selector_2 + expressions: + - type: expression_1 + operator: in + value: test + - type: expression_2 + operator: not_in + value: test + - type: expression_3 + operator: equals + value: test + - type: expression_4 + operator: not_equals + value: test + - type: expression_5 + operator: has_key + value: + - type: expression_6 + operator: does_not_have_key + state: present + register: nm_change_selector_2 + +- name: Verify nm_change_selector_2 + assert: + that: + - nm_change_selector_2 is changed + - nm_change_selector_2.current.name == "selector_2" + - nm_change_selector_2.current.expressions | length == 6 + +- name: Change Selector 2 expressions again (normal_mode) + mso_schema_template_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: selector_2 + expressions: + - type: expression_1 + operator: in + value: test + - type: expression_2 + operator: not_in + value: test + - type: expression_3 + operator: equals + value: test + - type: expression_4 + operator: not_equals + value: test + - type: expression_5 + operator: has_key + value: + - type: expression_6 + operator: does_not_have_key + state: present + register: nm_change_selector_2_again + +- name: Verify nm_change_selector_2_again + assert: + that: + - nm_change_selector_2_again is not changed + - nm_change_selector_2_again.current.name == "selector_2" + - nm_change_selector_2_again.current.expressions | length == 6 + +- name: Query all selectors (check_mode) + mso_schema_template_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + state: query + check_mode: yes + register: cm_query_all_selectors + +- name: Verify cm_query_all_selectors + assert: + that: + - cm_query_all_selectors is not changed + - cm_query_all_selectors.current | length == 2 + - cm_query_all_selectors.current[0].name == "selector_1" + - cm_query_all_selectors.current[1].name == "selector_2" + - cm_query_all_selectors.current[0].expressions == [] + - cm_query_all_selectors.current[1].expressions | length == 6 + +- name: Query all selectors (normal_mode) + mso_schema_template_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + state: query + register: nm_query_all_selectors + +- name: Verify nm_query_all_selectors + assert: + that: + - nm_query_all_selectors is not changed + - nm_query_all_selectors.current | length == 2 + - nm_query_all_selectors.current[0].name == "selector_1" + - nm_query_all_selectors.current[1].name == "selector_2" + - nm_query_all_selectors.current[0].expressions == [] + - nm_query_all_selectors.current[1].expressions | length == 6 + +- name: Query specific selector (check_mode) + mso_schema_template_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: selector_1 + state: query + check_mode: yes + register: cm_query_selector1 + +- name: Verify cm_query_selector1 + assert: + that: + - cm_query_selector1 is not changed + - cm_query_selector1.current.name == "selector_1" + - cm_query_selector1.current.expressions == [] + +- name: Query specific selector (normal_mode) + mso_schema_template_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: selector_1 + state: query + register: nm_query_selector1 + +- name: Verify nm_query_selector1 + assert: + that: + - nm_query_selector1 is not changed + - nm_query_selector1.current.name == "selector_1" + - nm_query_selector1.current.expressions == [] + +- name: Query specific selector2 (normal_mode) + mso_schema_template_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: selector_2 + state: query + register: nm_query_selector2 + +- name: Verify nm_query_selector2 + assert: + that: + - nm_query_selector2 is not changed + - nm_query_selector2.current.name == "selector_2" + - nm_query_selector2.current.expressions | length == 6 + - nm_query_selector2.current.expressions[0].key == "Custom:expression_1" + - nm_query_selector2.current.expressions[0].operator == "in" + - nm_query_selector2.current.expressions[0].value == "test" + - nm_query_selector2.current.expressions[1].key == "Custom:expression_2" + - nm_query_selector2.current.expressions[1].operator == "notIn" + - nm_query_selector2.current.expressions[1].value == "test" + - nm_query_selector2.current.expressions[2].key == "Custom:expression_3" + - nm_query_selector2.current.expressions[2].operator == "equals" + - nm_query_selector2.current.expressions[2].value == "test" + - nm_query_selector2.current.expressions[3].key == "Custom:expression_4" + - nm_query_selector2.current.expressions[3].operator == "notEquals" + - nm_query_selector2.current.expressions[3].value == "test" + - nm_query_selector2.current.expressions[4].key == "Custom:expression_5" + - nm_query_selector2.current.expressions[4].operator == "keyExist" + - nm_query_selector2.current.expressions[4].value == "" + - nm_query_selector2.current.expressions[5].key == "Custom:expression_6" + - nm_query_selector2.current.expressions[5].operator == "keyNotExist" + - nm_query_selector2.current.expressions[5].value == "" + +# - name: Remove selector 1 (check_mode) +# mso_schema_template_anp_epg_selector: +# <<: *mso_info +# schema: '{{ mso_schema | default("ansible_test") }}' +# template: Template 1 +# anp: ANP +# epg: ansible_test_1 +# selector: selector 1 +# state: absent +# check_mode: yes +# register: cm_remove_selector_1 + +# - name: Verify cm_remove_selector_1 +# assert: +# that: +# - cm_remove_selector_1 is changed +# - cm_remove_selector_1.current == {} + +# - name: Remove selector 1 (normal_mode) +# mso_schema_template_anp_epg_selector: +# <<: *mso_info +# schema: '{{ mso_schema | default("ansible_test") }}' +# template: Template 1 +# anp: ANP +# epg: ansible_test_1 +# selector: selector 1 +# state: absent +# register: nm_remove_selector_1 + +# - name: Verify nm_remove_selector_1 +# assert: +# that: +# - nm_remove_selector_1 is changed +# - nm_remove_selector_1.current == {} + +- name: Remove selector 2 (normal_mode) + mso_schema_template_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: selector_2 + state: absent + register: nm_remove_selector_2 + +- name: Verify nm_remove_selector_2 + assert: + that: + - nm_remove_selector_2 is changed + - nm_remove_selector_2.current == {} + +# QUERY NON-EXISTING Selector to EPG +- name: Query non-existing selector (check_mode) + mso_schema_template_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: non_existing_selector + state: query + check_mode: yes + ignore_errors: yes + register: cm_query_non_selector + +- name: Query non-existing selector (normal mode) + mso_schema_template_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: non_existing_selector + state: query + ignore_errors: yes + register: nm_query_non_selector + +- name: Verify cm_query_non_selector and nm_query_non_selector + assert: + that: + - cm_query_non_selector is not changed + - nm_query_non_selector is not changed + - cm_query_non_selector == nm_query_non_selector + - cm_query_non_selector.msg == "Selector 'non_existing_selector' not found" + - nm_query_non_selector.msg == "Selector 'non_existing_selector' not found" + +# QUERY NON-EXISTING EPG +- name: Query non-existing EPG (check_mode) + mso_schema_template_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: non_existing_epg + selector: selector_1 + state: query + check_mode: yes + ignore_errors: yes + register: cm_query_non_epg + +- name: Query non-existing EPG (normal mode) + mso_schema_template_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: non_existing_epg + selector: selector_1 + state: query + ignore_errors: yes + register: nm_query_non_epg + +- name: Verify query_non_epg + assert: + that: + - cm_query_non_epg is not changed + - nm_query_non_epg is not changed + - cm_query_non_epg == nm_query_non_epg + - cm_query_non_epg.msg == nm_query_non_epg.msg == "Provided epg 'non_existing_epg' does not exist. Existing epgs{{':'}} ansible_test_1" + +# QUERY NON-EXISTING ANP +- name: Query non-existing ANP (check_mode) + mso_schema_template_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: non_existing_anp + epg: ansible_test_1 + selector: selector_1 + state: query + check_mode: yes + ignore_errors: yes + register: cm_query_non_anp + +- name: Query non-existing ANP (normal mode) + mso_schema_template_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: non_existing_anp + epg: ansible_test_1 + selector: selector_1 + state: query + ignore_errors: yes + register: nm_query_non_anp + +- name: Verify query_non_anp + assert: + that: + - cm_query_non_anp is not changed + - nm_query_non_anp is not changed + - cm_query_non_anp == nm_query_non_anp + - cm_query_non_anp.msg == nm_query_non_anp.msg == "Provided anp 'non_existing_anp' does not exist. Existing anps{{':'}} ANP" + +# USE A NON-EXISTING STATE +- name: Non-existing state (check_mode) + mso_schema_template_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: selector_1 + state: non-existing-state + check_mode: yes + ignore_errors: yes + register: cm_non_existing_state + +- name: Non-existing state (normal_mode) + mso_schema_template_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: selector_1 + state: non-existing-state + ignore_errors: yes + register: nm_non_existing_state + +- name: Verify non_existing_state + assert: + that: + - cm_non_existing_state is not changed + - nm_non_existing_state is not changed + - cm_non_existing_state == nm_non_existing_state + - cm_non_existing_state.msg == nm_non_existing_state.msg == "value of state must be one of{{':'}} absent, present, query, got{{':'}} non-existing-state" + +# USE A NON-EXISTING TEMPLATE +- name: Non-existing template (check_mode) + mso_schema_template_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: non-existing-template + anp: ANP + epg: ansible_test_1 + selector: selector_1 + state: query + check_mode: yes + ignore_errors: yes + register: cm_non_existing_template + +- name: Non-existing template (normal_mode) + mso_schema_template_anp_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: non-existing-template + anp: ANP + epg: ansible_test_1 + selector: selector_1 + state: query + ignore_errors: yes + register: nm_non_existing_template + +- name: Verify non_existing_template + assert: + that: + - cm_non_existing_template is not changed + - nm_non_existing_template is not changed + - cm_non_existing_template == nm_non_existing_template + - cm_non_existing_template.msg == nm_non_existing_template.msg == "Provided template 'non-existing-template' does not exist. Existing templates{{':'}} Template1, Template2" + +# USE A NON-EXISTING SCHEMA +- name: Non-existing schema (check_mode) + mso_schema_template_anp_epg_selector: + <<: *mso_info + schema: non-existing-schema + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: selector_1 + state: query + check_mode: yes + ignore_errors: yes + register: cm_non_existing_schema + +- name: Non-existing schema (normal_mode) + mso_schema_template_anp_epg_selector: + <<: *mso_info + schema: non-existing-schema + template: Template 1 + anp: ANP + epg: ansible_test_1 + selector: selector_1 + state: query + ignore_errors: yes + register: nm_non_existing_schema + +- name: Verify non_existing_schema + assert: + that: + - cm_non_existing_schema is not changed + - nm_non_existing_schema is not changed + - cm_non_existing_schema == nm_non_existing_schema + - cm_non_existing_schema.msg == nm_non_existing_schema.msg == "Provided schema 'non-existing-schema' does not exist."
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_bd/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_bd/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_bd/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_bd/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_bd/tasks/main.yml new file mode 100644 index 00000000..2ddbb2a1 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_bd/tasks/main.yml @@ -0,0 +1,1907 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Lionel Hercot (@lhercot) <lhercot@cisco.com> +# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> (based on mso_site test case) +# + +# 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") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Set version vars + set_fact: + mso_l3mcast: false + when: version.current.version is version('2.2.4', '=') + +- name: Ensure site exist + mso_site: &site_present + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + apic_username: '{{ apic_username }}' + apic_password: '{{ apic_password }}' + apic_site_id: '{{ apic_site_id | default(101) }}' + urls: + - https://{{ apic_hostname }} + state: present + +- name: Remove schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Remove DHCP policies + mso_dhcp_relay_policy: + <<: *mso_info + dhcp_relay_policy: '{{ item }}' + tenant: ansible_test + state: absent + loop: + - 'ansible_test_dhcp_policy1' + - 'ansible_test_dhcp_policy2' + - 'ansible_test_dhcp_policy3' + when: + # TODO dhcp policies api endpoint has changed after 4.0, fix when new module is created + - version.current.version is version('4.0', '<') + +- name: Remove DHCP option policies + mso_dhcp_option_policy: + <<: *mso_info + dhcp_option_policy: '{{ item }}' + tenant: ansible_test + state: absent + loop: + - 'ansible_test_dhcp_policy_option1' + - 'ansible_test_dhcp_policy_option2' + - 'ansible_test_dhcp_policy_option3' + when: + # TODO dhcp policies api endpoint has changed after 4.0, fix when new module is created + - version.current.version is version('4.0', '<') + +- name: Ensure tenant ansible_test exist + mso_tenant: &tenant_present + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + sites: + - '{{ mso_site | default("ansible_test") }}' + state: present + +- name: Ensure schema 1 with Template1 exist + mso_schema_template: &schema_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template1 + state: present + +- name: Ensure schema 1 with Template2 exists + mso_schema_template: + <<: *schema_present + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template2 + +- name: Ensure schema 2 with Template3 exists + mso_schema_template: + <<: *schema_present + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template3 + +- name: Ensure schema 2 with Template5 exists + mso_schema_template: + <<: *schema_present + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template5 + +- name: Ensure VRF exist + mso_schema_template_vrf: &vrf_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + vrf: VRF + layer3_multicast: true + state: present + +- name: Ensure VRF2 exist + mso_schema_template_vrf: + <<: *vrf_present + vrf: VRF2 + +- name: Ensure VRF3 exist + mso_schema_template_vrf: + <<: *vrf_present + template: Template2 + vrf: VRF3 + +- name: Ensure VRF4 exist + mso_schema_template_vrf: + <<: *vrf_present + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template3 + vrf: VRF4 + +- name: Ensure VRF5 exists + mso_schema_template_vrf: + <<: *vrf_present + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template5 + vrf: VRF5 + +- name: Ensure ansible_test_1 BD does not exist + mso_schema_template_bd: + <<: *vrf_present + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + vrf: + name: VRF + state: absent + +- name: Ensure ansible_test_2 BD does not exist + mso_schema_template_bd: + <<: *vrf_present + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template2 + bd: ansible_test_2 + vrf: + name: VRF + state: absent + +- name: Ensure ansible_test_3 BD does not exist + mso_schema_template_bd: + <<: *vrf_present + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template3 + bd: ansible_test_3 + vrf: + name: VRF + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + state: absent + +- name: Ensure ansible_test_4 BD does not exist + mso_schema_template_bd: + <<: *vrf_present + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_4 + vrf: + name: VRF + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + state: absent + +- name: Ensure multiple DHCP policies exist + mso_dhcp_relay_policy: + <<: *mso_info + dhcp_relay_policy: '{{ item }}' + description: "My Test DHCP Policies" + tenant: ansible_test + state: present + loop: + - 'ansible_test_dhcp_policy1' + - 'ansible_test_dhcp_policy2' + - 'ansible_test_dhcp_policy3' + when: + # TODO dhcp policies api endpoint has changed after 4.0, fix when new module is created + - version.current.version is version('4.0', '<') + +- name: Ensure multiple DHCP option policies exist + mso_dhcp_option_policy: + <<: *mso_info + dhcp_option_policy: '{{ item }}' + description: "My Test DHCP Policy Options" + tenant: ansible_test + state: present + loop: + - 'ansible_test_dhcp_policy_option1' + - 'ansible_test_dhcp_policy_option2' + - 'ansible_test_dhcp_policy_option3' + when: + # TODO dhcp policies api endpoint has changed after 4.0, fix when new module is created + - version.current.version is version('4.0', '<') + +# ADD BD +- name: Add bd (check_mode) + mso_schema_template_bd: &bd_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + vrf: + name: VRF + state: present + check_mode: yes + register: cm_add_bd + +- name: Verify cm_add_bd + assert: + that: + - cm_add_bd is changed + - cm_add_bd.previous == {} + - cm_add_bd.current.name == "ansible_test_1" + - cm_add_bd.current.vrfRef.templateName == "Template1" + - cm_add_bd.current.vrfRef.vrfName == "VRF" + +- name: Add bd (normal mode) + mso_schema_template_bd: + <<: *bd_present + register: nm_add_bd + +- name: Verify nm_add_bd + assert: + that: + - nm_add_bd is changed + - nm_add_bd.previous == {} + - nm_add_bd.current.name == "ansible_test_1" + - nm_add_bd.current.vrfRef.templateName == "Template1" + - nm_add_bd.current.vrfRef.vrfName == "VRF" + - cm_add_bd.current.vrfRef.schemaId == nm_add_bd.current.vrfRef.schemaId + +- name: Add bd again (check_mode) + mso_schema_template_bd: + <<: *bd_present + check_mode: yes + register: cm_add_bd_again + +- name: Verify cm_add_bd_again + assert: + that: + - cm_add_bd_again is not changed + - cm_add_bd_again.previous.name == "ansible_test_1" + - cm_add_bd_again.current.name == "ansible_test_1" + - cm_add_bd_again.previous.vrfRef.templateName == "Template1" + - cm_add_bd_again.current.vrfRef.templateName == "Template1" + - cm_add_bd_again.previous.vrfRef.vrfName == "VRF" + - cm_add_bd_again.current.vrfRef.vrfName == "VRF" + - cm_add_bd_again.previous.vrfRef.schemaId == cm_add_bd_again.current.vrfRef.schemaId + +- name: Add bd again (normal mode) + mso_schema_template_bd: + <<: *bd_present + register: nm_add_bd_again + +- name: Verify nm_add_bd_again + assert: + that: + - nm_add_bd_again is not changed + - nm_add_bd_again.previous.name == "ansible_test_1" + - nm_add_bd_again.current.name == "ansible_test_1" + - nm_add_bd_again.previous.vrfRef.templateName == "Template1" + - nm_add_bd_again.current.vrfRef.templateName == "Template1" + - nm_add_bd_again.previous.vrfRef.vrfName == "VRF" + - nm_add_bd_again.current.vrfRef.vrfName == "VRF" + - nm_add_bd_again.previous.vrfRef.schemaId == nm_add_bd_again.current.vrfRef.schemaId + +- name: Add bd 2 (normal mode) + mso_schema_template_bd: + <<: *bd_present + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template2 + bd: ansible_test_2 + intersite_bum_traffic: true + optimize_wan_bandwidth: true + layer2_stretch: true + layer2_unknown_unicast: flood + layer3_multicast: true + subnets: + - subnet: 10.0.0.128/24 + - subnet: 10.0.1.254/24 + description: 1234567890 + - subnet: 172.16.0.1/24 + description: "My description for a subnet" + scope: public + shared: true + no_default_gateway: false + querier: true + - ip: 192.168.0.254/24 + description: "My description for a subnet" + scope: private + shared: false + no_default_gateway: true + vrf: + name: VRF3 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template2 + dhcp_policy: + name: ansible_test + version: 1 + dhcp_option_policy: + name: ansible_test_option + version: 1 + register: nm_add_bd_2 + +- name: Add bd 3 (normal mode) + mso_schema_template_bd: + <<: *bd_present + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template3 + bd: ansible_test_3 + vrf: + name: VRF4 + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template3 + register: nm_add_bd_3 + +- name: Add bd 4 (normal mode) + mso_schema_template_bd: + <<: *bd_present + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_4 + vrf: + name: VRF + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + register: nm_add_bd_4 + +- name: Verify nm_add_bd_2 and nm_add_bd_3 + assert: + that: + - nm_add_bd_2 is changed + - nm_add_bd_3 is changed + - nm_add_bd_2.current.name == "ansible_test_2" + - nm_add_bd_3.current.name == "ansible_test_3" + - nm_add_bd_2.current.vrfRef.templateName == "Template2" + - nm_add_bd_3.current.vrfRef.templateName == "Template3" + - nm_add_bd_2.current.vrfRef.vrfName == "VRF3" + - nm_add_bd_3.current.vrfRef.vrfName == "VRF4" + - nm_add_bd_2.current.vrfRef.schemaId == nm_add_bd.current.vrfRef.schemaId + - nm_add_bd_2.current.intersiteBumTrafficAllow == true + - nm_add_bd_2.current.optimizeWanBandwidth == true + - nm_add_bd_2.current.l2Stretch == true + - nm_add_bd_2.current.l2UnknownUnicast == "flood" + - nm_add_bd_2.current.l3MCast == true + - nm_add_bd_2.current.subnets[0].description == "10.0.0.128/24" + - nm_add_bd_2.current.subnets[0].ip == "10.0.0.128/24" + - nm_add_bd_2.current.subnets[0].noDefaultGateway == false + - nm_add_bd_2.current.subnets[0].scope == "private" + - nm_add_bd_2.current.subnets[0].shared == false + - nm_add_bd_2.current.subnets[0].querier == false + - nm_add_bd_2.current.subnets[1].description == "1234567890" + - nm_add_bd_2.current.subnets[1].ip == "10.0.1.254/24" + - nm_add_bd_2.current.subnets[1].noDefaultGateway == false + - nm_add_bd_2.current.subnets[1].scope == "private" + - nm_add_bd_2.current.subnets[1].shared == false + - nm_add_bd_2.current.subnets[1].querier == false + - nm_add_bd_2.current.subnets[2].description == "My description for a subnet" + - nm_add_bd_2.current.subnets[2].ip == "172.16.0.1/24" + - nm_add_bd_2.current.subnets[2].noDefaultGateway == false + - nm_add_bd_2.current.subnets[2].scope == "public" + - nm_add_bd_2.current.subnets[2].shared == true + - nm_add_bd_2.current.subnets[2].querier == true + - nm_add_bd_2.current.subnets[3].description == "My description for a subnet" + - nm_add_bd_2.current.subnets[3].ip == "192.168.0.254/24" + - nm_add_bd_2.current.subnets[3].noDefaultGateway == true + - nm_add_bd_2.current.subnets[3].scope == "private" + - nm_add_bd_2.current.subnets[3].shared == false + - nm_add_bd_2.current.subnets[3].querier == false + +- name: Add bd 5 (normal mode) + mso_schema_template_bd: + <<: *bd_present + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template5 + bd: ansible_test_5 + intersite_bum_traffic: true + optimize_wan_bandwidth: true + layer2_stretch: true + layer2_unknown_unicast: flood + layer3_multicast: false + unknown_multicast_flooding: flood + multi_destination_flooding: drop + ipv6_unknown_multicast_flooding: flood + arp_flooding: true + virtual_mac_address: 00:00:5E:00:01:3C + vrf: + name: VRF5 + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template5 + dhcp_policy: + name: ansible_test + version: 1 + dhcp_option_policy: + name: ansible_test_option + version: 1 + register: nm_add_bd_5 + +- name: Verify nm_add_bd_5 for a version that's before 3.1 + assert: + that: + - nm_add_bd_5 is changed + - nm_add_bd_5.current.name == "ansible_test_5" + - nm_add_bd_5.current.vrfRef.templateName == "Template5" + - nm_add_bd_5.current.vrfRef.vrfName == "VRF5" + - nm_add_bd_5.current.intersiteBumTrafficAllow == true + - nm_add_bd_5.current.optimizeWanBandwidth == true + - nm_add_bd_5.current.l2Stretch == true + - nm_add_bd_5.current.l2UnknownUnicast == "flood" + - nm_add_bd_5.current.l3MCast == false + when: version.current.version is version('3.1.1g', '<') + +- name: Verify nm_add_bd_5 for a version that's 3.1 + assert: + that: + - nm_add_bd_5 is changed + - nm_add_bd_5.current.name == "ansible_test_5" + - nm_add_bd_5.current.vrfRef.templateName == "Template5" + - nm_add_bd_5.current.vrfRef.vrfName == "VRF5" + - nm_add_bd_5.current.intersiteBumTrafficAllow == true + - nm_add_bd_5.current.optimizeWanBandwidth == true + - nm_add_bd_5.current.l2Stretch == true + - nm_add_bd_5.current.l2UnknownUnicast == "flood" + - nm_add_bd_5.current.l3MCast == false + - nm_add_bd_5.current.unkMcastAct == "flood" + - nm_add_bd_5.current.v6unkMcastAct == "flood" + - nm_add_bd_5.current.vmac == "00:00:5E:00:01:3C" + - nm_add_bd_5.current.multiDstPktAct == "drop" + - nm_add_bd_5.current.arpFlood == true + when: version.current.version is version('3.1.1g', '>=') + +- name: Add bd 5 again (normal mode) + mso_schema_template_bd: + <<: *bd_present + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template5 + bd: ansible_test_5 + intersite_bum_traffic: true + optimize_wan_bandwidth: true + layer2_stretch: true + layer2_unknown_unicast: flood + layer3_multicast: false + unknown_multicast_flooding: flood + multi_destination_flooding: drop + ipv6_unknown_multicast_flooding: flood + arp_flooding: true + virtual_mac_address: 00:00:5E:00:01:3C + vrf: + name: VRF5 + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template5 + dhcp_policy: + name: ansible_test + version: 1 + dhcp_option_policy: + name: ansible_test_option + version: 1 + register: nm_add_again_bd_5 + +- name: Verify nm_add_again_bd_5 for a version that's before 3.1 + assert: + that: + - nm_add_again_bd_5 is not changed + when: version.current.version is version('3.1.1g', '<') + +- name: Verify nm_add_again_bd_5 for a version that's between 3.1 and 4.0 + assert: + that: + - nm_add_again_bd_5 is not changed + when: + - version.current.version is version('3.1.1g', '>=') + +- name: Add bd 5 with different values for new options (normal mode) + mso_schema_template_bd: + <<: *bd_present + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template5 + bd: ansible_test_5 + intersite_bum_traffic: true + optimize_wan_bandwidth: true + layer2_stretch: true + layer2_unknown_unicast: flood + layer3_multicast: false + unknown_multicast_flooding: optimized_flooding + multi_destination_flooding: flood_in_bd + ipv6_unknown_multicast_flooding: optimized_flooding + arp_flooding: true + virtual_mac_address: 00:00:5E:00:02:3C + vrf: + name: VRF5 + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template5 + dhcp_policy: + name: ansible_test + version: 1 + dhcp_option_policy: + name: ansible_test_option + version: 1 + register: nm_bd_5_options + +- name: Verify nm_bd_5_options for a version that's before 3.1 + assert: + that: + - nm_bd_5_options is not changed + when: version.current.version is version('3.1.1g', '<') + +- name: Verify nm_bd_5_options for a version that's 3.1 + assert: + that: + - nm_bd_5_options is changed + - nm_bd_5_options.current.unkMcastAct == "opt-flood" + - nm_bd_5_options.current.v6unkMcastAct == "opt-flood" + - nm_bd_5_options.current.multiDstPktAct == "bd-flood" + - nm_bd_5_options.current.vmac == "00:00:5E:00:02:3C" + when: version.current.version is version('3.1.1g', '>=') + +- name: Change bd 5_1 (normal mode) + mso_schema_template_bd: + <<: *bd_present + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template5 + bd: ansible_test_5 + intersite_bum_traffic: true + optimize_wan_bandwidth: true + layer2_stretch: true + layer2_unknown_unicast: proxy + layer3_multicast: false + unknown_multicast_flooding: flood + multi_destination_flooding: drop + ipv6_unknown_multicast_flooding: flood + arp_flooding: true + virtual_mac_address: 00:00:5E:00:01:3C + vrf: + name: VRF5 + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template5 + dhcp_policy: + name: ansible_test + version: 1 + dhcp_option_policy: + name: ansible_test_option + version: 1 + register: nm_change_bd_5_1 + +- name: Verify nm_change_bd_5_1 for a version that's before 3.1 + assert: + that: + - nm_change_bd_5_1 is changed + when: version.current.version is version('3.1.1g', '<') + +- name: Verify nm_change_bd_5_1 for a version that's 3.1 + assert: + that: + - nm_change_bd_5_1 is changed + - nm_change_bd_5_1.current.arpFlood == true + when: version.current.version is version('3.1.1g', '>=') + +- name: Change bd 5_2 (normal mode) + mso_schema_template_bd: &change_bd5_2 + <<: *bd_present + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template5 + bd: ansible_test_5 + intersite_bum_traffic: true + optimize_wan_bandwidth: true + layer2_stretch: true + layer2_unknown_unicast: flood + layer3_multicast: false + unknown_multicast_flooding: flood + multi_destination_flooding: drop + ipv6_unknown_multicast_flooding: flood + arp_flooding: false + virtual_mac_address: 00:00:5E:00:01:3C + vrf: + name: VRF5 + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template5 + dhcp_policy: + name: ansible_test + version: 1 + dhcp_option_policy: + name: ansible_test_option + version: 1 + ignore_errors: yes + register: nm_change_bd_5_2 + +- name: Verify nm_change_bd_5_2 for a version that's before 3.1 + assert: + that: + - nm_change_bd_5_2 is changed + - nm_change_bd_5_2.current.l2UnknownUnicast == "flood" + when: version.current.version is version('3.1.1g', '<') + +- name: Verify nm_change_bd_5_2 for a version that's after 3.1 + assert: + that: + - nm_change_bd_5_2 is changed + - nm_change_bd_5_2.current.arpFlood == true + when: version.current.version is version('3.1.1g', '>=') + +- name: Change bd 5_3 (normal mode) + mso_schema_template_bd: + <<: *bd_present + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template5 + bd: ansible_test_5 + intersite_bum_traffic: false + optimize_wan_bandwidth: true + layer2_stretch: true + layer2_unknown_unicast: flood + layer3_multicast: false + unknown_multicast_flooding: flood + multi_destination_flooding: drop + ipv6_unknown_multicast_flooding: flood + arp_flooding: false + virtual_mac_address: 00:00:5E:00:01:3C + vrf: + name: VRF5 + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template5 + dhcp_policy: + name: ansible_test + version: 1 + dhcp_option_policy: + name: ansible_test_option + version: 1 + ignore_errors: yes + register: nm_change_bd_5_3 + +- name: Verify nm_change_bd_5_3 for a version that's before 3.1 + assert: + that: + - nm_change_bd_5_3 is changed + - nm_change_bd_5_3.msg is match ("MSO Error 143{{':'}} Invalid Field{{':'}} BD 'ansible_test_5' l2UnknownUnicast cannot be flood when intersiteBumTrafficAllow is off") + when: version.current.version is version('3.1.1g', '<') + +- name: Verify nm_change_bd_5_3 for a version that's after 3.1 and before 3.3 + assert: + that: + - nm_change_bd_5_3 is changed + # Inconsistency shown in returned error messages for v3.1.1 + # Below variants of the message output have occurred randomly, thus commenting out the specific error messages below. + # Would need further investigation in to the cause, but due to old version decided to skip this investigation and do skip the message skip. + # - "'l2UnknownUnicast cannot be flood when intersiteBumTrafficAllow is off exception while trying to update schema' in nm_change_bd_5_3.msg" + # - nm_change_bd_5_3.msg is match ("MSO Error 400{{':'}} Bad Request{{':'}} Patch Failed, Received{{':'}} BD 'ansible_test_5' {{':'}} ARP Flooding has to be disabled if L2 Stretch enabled and BUM traffic disabled exception while trying to update schema") + # - nm_change_bd_5_3.msg is match ("MSO Error 400{{':'}} Bad Request{{':'}} Patch Failed, Received{{':'}} Template 'Template5', BD 'ansible_test_5' {{':'}} ARP Flooding has to be disabled if L2 Stretch enabled and BUM traffic disabled exception while trying to update schema") + when: + - version.current.version is version('3.3', '<') + - version.current.version is version('3.1.1g', '>=') + +- name: Verify nm_change_bd_5_3 for a version that's after 4.0 + assert: + that: + - nm_change_bd_5_3 is changed + - nm_change_bd_5_3.msg is match ("MSO Error 400{{':'}} BD{{':'}} ansible_test_5 in Schema{{':'}} ansible_test_2 , Template{{':'}} Template5 BD ansible_test_5 l2UnknownUnicast cannot be flood when intersiteBumTrafficAllow is off") + when: + - version.current.version is version('4.0', '>=') + +- name: Get Validation status + mso_schema_validate: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + state: query + ignore_errors: yes + register: query_validate + when: + - version.current.version is version('3.3', '>=') + - version.current.version is version('4.0', '<') # mso_schema_validate not needed after 4.0 because validation is done upon request + +- name: Verify query_validate for a version that's after 3.3 + assert: + that: + - query_validate is not changed + - query_validate.msg is match ("MSO Error 400{{':'}} Bad Request{{':'}} Patch Failed, Received{{':'}} Template 'Template5', BD 'ansible_test_5' {{':'}} ARP Flooding has to be disabled if L2 Stretch enabled and BUM traffic disabled exception while trying to update schema") + when: + - version.current.version is version('3.3', '>=') + - version.current.version is version('3.7', '<') + +# Reverting back to bd 5_2 +- name: Change bd 5_3 (normal mode) + mso_schema_template_bd: + <<: *change_bd5_2 + register: nm_change_bd_5_3_again + when: query_validate is failed + +- name: Get Validation status + mso_schema_validate: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + state: query + register: query_validate + when: + - version.current.version is version('3.3', '>=') + - version.current.version is version('4.0', '<') # mso_schema_validate not needed after 4.0 because validation is done upon request + +- name: Change bd 5 for query (normal mode) + mso_schema_template_bd: + <<: *bd_present + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template5 + bd: ansible_test_5 + intersite_bum_traffic: true + optimize_wan_bandwidth: true + layer2_stretch: true + layer2_unknown_unicast: flood + layer3_multicast: false + unknown_multicast_flooding: flood + multi_destination_flooding: drop + ipv6_unknown_multicast_flooding: flood + arp_flooding: true + virtual_mac_address: 00:00:5E:00:01:3C + vrf: + name: VRF5 + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template5 + dhcp_policy: + name: ansible_test + version: 1 + dhcp_option_policy: + name: ansible_test_option + version: 1 + +# CHANGE BD +- name: Change bd (check_mode) + mso_schema_template_bd: + <<: *bd_present + vrf: + name: VRF2 + check_mode: yes + register: cm_change_bd + +- name: Verify cm_change_bd + assert: + that: + - cm_change_bd is changed + - cm_change_bd.current.name == 'ansible_test_1' + - cm_change_bd.current.vrfRef.vrfName == 'VRF2' + - cm_change_bd.current.vrfRef.templateName == "Template1" + - cm_change_bd.current.vrfRef.schemaId == cm_change_bd.previous.vrfRef.schemaId + +- name: Change bd (normal mode) + mso_schema_template_bd: + <<: *bd_present + vrf: + name: VRF2 + output_level: debug + register: nm_change_bd + +- name: Verify nm_change_bd + assert: + that: + - nm_change_bd is changed + - nm_change_bd.current.name == 'ansible_test_1' + - nm_change_bd.current.vrfRef.vrfName == 'VRF2' + - nm_change_bd.current.vrfRef.templateName == "Template1" + - nm_change_bd.current.vrfRef.schemaId == nm_change_bd.previous.vrfRef.schemaId + +- name: Change bd again (check_mode) + mso_schema_template_bd: + <<: *bd_present + vrf: + name: VRF2 + check_mode: yes + register: cm_change_bd_again + +- name: Verify cm_change_bd_again + assert: + that: + - cm_change_bd_again is not changed + - cm_change_bd_again.current.name == 'ansible_test_1' + - cm_change_bd_again.current.vrfRef.vrfName == 'VRF2' + - cm_change_bd_again.current.vrfRef.templateName == "Template1" + - cm_change_bd_again.current.vrfRef.schemaId == cm_change_bd_again.previous.vrfRef.schemaId + +- name: Change bd again (normal mode) + mso_schema_template_bd: + <<: *bd_present + vrf: + name: VRF2 + register: nm_change_bd_again + +- name: Verify nm_change_bd_again + assert: + that: + - nm_change_bd_again is not changed + - nm_change_bd_again.current.name == 'ansible_test_1' + - nm_change_bd_again.current.vrfRef.vrfName == 'VRF2' + - nm_change_bd_again.current.vrfRef.templateName == "Template1" + - nm_change_bd_again.current.vrfRef.schemaId == nm_change_bd_again.previous.vrfRef.schemaId + +- name: Change bd to VRF3 in other template (normal mode) + mso_schema_template_bd: + <<: *bd_present + vrf: + name: VRF3 + template: Template2 + register: nm_change_bd_vrf3 + +- name: Change bd to VRF4 in other schema (normal mode) + mso_schema_template_bd: + <<: *bd_present + vrf: + name: VRF4 + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template3 + register: nm_change_bd_vrf4 + +- name: Verify nm_change_bd_vrf3 and nm_change_bd_vrf4 + assert: + that: + - nm_change_bd_vrf3 is changed + - nm_change_bd_vrf3.current.name == nm_change_bd_vrf4.current.name == 'ansible_test_1' + - nm_change_bd_vrf3.current.vrfRef.vrfName == 'VRF3' + - nm_change_bd_vrf3.current.vrfRef.templateName == "Template2" + - nm_change_bd_vrf4.current.vrfRef.vrfName == 'VRF4' + - nm_change_bd_vrf4.current.vrfRef.templateName == "Template3" + +- name: Change bd 1 settings(normal mode) + mso_schema_template_bd: + <<: *bd_present + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + intersite_bum_traffic: true + optimize_wan_bandwidth: true + layer2_stretch: true + layer2_unknown_unicast: flood + layer3_multicast: '{{ mso_l3mcast | default(true) }}' + subnets: + - subnet: 10.1.0.128/24 + - subnet: 10.1.1.254/24 + description: 1234567890 + - subnet: 172.17.0.1/24 + description: "My description for a subnet" + scope: public + shared: true + no_default_gateway: false + querier: true + - ip: 192.168.1.254/24 + description: "My description for a subnet" + scope: private + shared: false + no_default_gateway: true + vrf: + name: VRF3 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template2 + register: nm_change_bd_1_settings + +- name: Change bd 1 subnets (normal mode) + mso_schema_template_bd: + <<: *bd_present + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + intersite_bum_traffic: true + optimize_wan_bandwidth: true + layer2_stretch: true + layer2_unknown_unicast: flood + layer3_multicast: '{{ mso_l3mcast | default(true) }}' + subnets: + - subnet: 10.1.0.127/24 + - subnet: 172.17.0.1/24 + description: "New description for a subnet" + scope: private + shared: false + no_default_gateway: false + querier: false + - ip: 192.168.1.254/24 + description: "My description for a subnet" + scope: private + shared: false + no_default_gateway: false + querier: true + vrf: + name: VRF3 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template2 + register: nm_change_bd_1_subnets + +- name: Verify nm_change_bd_1_subnets + assert: + that: + - nm_change_bd_1_settings is changed + - nm_change_bd_1_settings.current.name == "ansible_test_1" + - nm_change_bd_1_settings.current.vrfRef.templateName == "Template2" + - nm_change_bd_1_settings.current.vrfRef.vrfName == "VRF3" + - nm_change_bd_1_settings.current.intersiteBumTrafficAllow == true + - nm_change_bd_1_settings.current.optimizeWanBandwidth == true + - nm_change_bd_1_settings.current.l2Stretch == true + - nm_change_bd_1_settings.current.l2UnknownUnicast == "flood" + - nm_change_bd_1_settings.current.subnets[0].description == "10.1.0.128/24" + - nm_change_bd_1_settings.current.subnets[0].ip == "10.1.0.128/24" + - nm_change_bd_1_settings.current.subnets[0].noDefaultGateway == false + - nm_change_bd_1_settings.current.subnets[0].scope == "private" + - nm_change_bd_1_settings.current.subnets[0].shared == false + - nm_change_bd_1_settings.current.subnets[0].querier == false + - nm_change_bd_1_settings.current.subnets[1].description == "1234567890" + - nm_change_bd_1_settings.current.subnets[1].ip == "10.1.1.254/24" + - nm_change_bd_1_settings.current.subnets[1].noDefaultGateway == false + - nm_change_bd_1_settings.current.subnets[1].scope == "private" + - nm_change_bd_1_settings.current.subnets[1].shared == false + - nm_change_bd_1_settings.current.subnets[1].querier == false + - nm_change_bd_1_settings.current.subnets[2].description == "My description for a subnet" + - nm_change_bd_1_settings.current.subnets[2].ip == "172.17.0.1/24" + - nm_change_bd_1_settings.current.subnets[2].noDefaultGateway == false + - nm_change_bd_1_settings.current.subnets[2].scope == "public" + - nm_change_bd_1_settings.current.subnets[2].shared == true + - nm_change_bd_1_settings.current.subnets[2].querier == true + - nm_change_bd_1_settings.current.subnets[3].description == "My description for a subnet" + - nm_change_bd_1_settings.current.subnets[3].ip == "192.168.1.254/24" + - nm_change_bd_1_settings.current.subnets[3].noDefaultGateway == true + - nm_change_bd_1_settings.current.subnets[3].scope == "private" + - nm_change_bd_1_settings.current.subnets[3].shared == false + - nm_change_bd_1_settings.current.subnets[3].querier == false + - nm_change_bd_1_settings is changed + - nm_change_bd_1_subnets.current.subnets | length == 3 + - nm_change_bd_1_subnets.current.name == "ansible_test_1" + - nm_change_bd_1_subnets.current.vrfRef.templateName == "Template2" + - nm_change_bd_1_subnets.current.vrfRef.vrfName == "VRF3" + - nm_change_bd_1_subnets.current.intersiteBumTrafficAllow == true + - nm_change_bd_1_subnets.current.optimizeWanBandwidth == true + - nm_change_bd_1_subnets.current.l2Stretch == true + - nm_change_bd_1_subnets.current.l2UnknownUnicast == "flood" + - nm_change_bd_1_subnets.current.subnets[0].description == "10.1.0.127/24" + - nm_change_bd_1_subnets.current.subnets[0].ip == "10.1.0.127/24" + - nm_change_bd_1_subnets.current.subnets[0].noDefaultGateway == false + - nm_change_bd_1_subnets.current.subnets[0].scope == "private" + - nm_change_bd_1_subnets.current.subnets[0].shared == false + - nm_change_bd_1_subnets.current.subnets[0].querier == false + - nm_change_bd_1_subnets.current.subnets[1].description == "New description for a subnet" + - nm_change_bd_1_subnets.current.subnets[1].ip == "172.17.0.1/24" + - nm_change_bd_1_subnets.current.subnets[1].noDefaultGateway == false + - nm_change_bd_1_subnets.current.subnets[1].scope == "private" + - nm_change_bd_1_subnets.current.subnets[1].shared == false + - nm_change_bd_1_subnets.current.subnets[1].querier == false + - nm_change_bd_1_subnets.current.subnets[2].description == "My description for a subnet" + - nm_change_bd_1_subnets.current.subnets[2].ip == "192.168.1.254/24" + - nm_change_bd_1_subnets.current.subnets[2].noDefaultGateway == false + - nm_change_bd_1_subnets.current.subnets[2].scope == "private" + - nm_change_bd_1_subnets.current.subnets[2].shared == false + - nm_change_bd_1_subnets.current.subnets[2].querier == true + +- name: Verify l3MCast nm_change_bd_1_subnets (version == 2.2.4) + assert: + that: + - nm_change_bd_1_settings.current.l3MCast == false + - nm_change_bd_1_subnets.current.l3MCast == false + when: version.current.version is version('2.2.4', '=') + +- name: Verify l3MCast nm_change_bd_1_subnets (version != 2.2.4) + assert: + that: + - nm_change_bd_1_settings.current.l3MCast == true + - nm_change_bd_1_subnets.current.l3MCast == true + when: version.current.version is version('2.2.4', '!=') + +- name: Add bd with multiple dhcp policies for mso version > 3.1.1g + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_multiple_dhcp + intersite_bum_traffic: true + optimize_wan_bandwidth: false + layer2_stretch: true + layer2_unknown_unicast: flood + layer3_multicast: false + unknown_multicast_flooding: flood + multi_destination_flooding: drop + ipv6_unknown_multicast_flooding: flood + arp_flooding: false + virtual_mac_address: 00:00:5E:00:01:3C + subnets: + - subnet: 10.0.0.128/24 + - subnet: 10.0.1.254/24 + description: 1234567890 + - ip: 192.168.0.254/24 + description: "My description for a subnet" + scope: private + shared: false + no_default_gateway: true + vrf: + name: VRF + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + dhcp_policies: + - name: ansible_test_dhcp_policy1 + version: 1 + dhcp_option_policy: + name: ansible_test_dhcp_policy_option1 + version: 1 + - name: ansible_test_dhcp_policy2 + version: 1 + dhcp_option_policy: + name: ansible_test_dhcp_policy_option1 + version: 1 + - name: ansible_test_dhcp_policy3 + version: 1 + dhcp_option_policy: + name: ansible_test_dhcp_policy_option2 + version: 1 + state: present + register: nm_bd_dhcp_policies + when: + - version.current.version is version('3.1.1g', '>') + # TODO dhcp policies api endpoint has changed after 4.0, fix when new module is created + - version.current.version is version('4.0', '<') + +- name: Verify addition of DHCP policies for mso version > 3.1.1g + assert: + that: + - nm_bd_dhcp_policies is changed + - nm_bd_dhcp_policies.current.dhcpLabels | length == 3 + - nm_bd_dhcp_policies.current.dhcpLabels[0].name == 'ansible_test_dhcp_policy1' + - nm_bd_dhcp_policies.current.dhcpLabels[1].name == 'ansible_test_dhcp_policy2' + - nm_bd_dhcp_policies.current.dhcpLabels[2].name == 'ansible_test_dhcp_policy3' + - nm_bd_dhcp_policies.current.dhcpLabels[0].version == 1 + - nm_bd_dhcp_policies.current.dhcpLabels[1].version == 1 + - nm_bd_dhcp_policies.current.dhcpLabels[2].version == 1 + - nm_bd_dhcp_policies.current.dhcpLabels[0].dhcpOptionLabel.name == 'ansible_test_dhcp_policy_option1' + - nm_bd_dhcp_policies.current.dhcpLabels[1].dhcpOptionLabel.name == 'ansible_test_dhcp_policy_option1' + - nm_bd_dhcp_policies.current.dhcpLabels[2].dhcpOptionLabel.name == 'ansible_test_dhcp_policy_option2' + - nm_bd_dhcp_policies.current.dhcpLabels[0].dhcpOptionLabel.version == 1 + - nm_bd_dhcp_policies.current.dhcpLabels[1].dhcpOptionLabel.version == 1 + - nm_bd_dhcp_policies.current.dhcpLabels[2].dhcpOptionLabel.version == 1 + when: + - version.current.version is version('3.1.1g', '>') + # TODO dhcp policies api endpoint has changed after 4.0, fix when new module is created + - version.current.version is version('4.0', '<') + +- name: Change bd with multiple dhcp policies for mso version > 3.1.1g + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_multiple_dhcp + intersite_bum_traffic: true + optimize_wan_bandwidth: false + layer2_stretch: true + layer2_unknown_unicast: flood + layer3_multicast: false + unknown_multicast_flooding: flood + multi_destination_flooding: drop + ipv6_unknown_multicast_flooding: flood + arp_flooding: false + virtual_mac_address: 00:00:5E:00:01:3C + subnets: + - subnet: 10.0.0.128/24 + - subnet: 10.0.1.254/24 + description: 1234567890 + - ip: 192.168.0.254/24 + description: "My description for a subnet" + scope: private + shared: false + no_default_gateway: true + vrf: + name: VRF + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + dhcp_policies: + - name: ansible_test_dhcp_policy1 + version: 1 + dhcp_option_policy: + name: ansible_test_dhcp_policy_option1 + version: 1 + - name: ansible_test_dhcp_policy2 + version: 1 + dhcp_option_policy: + name: ansible_test_dhcp_policy_option1 + version: 1 + state: present + register: change_nm_bd_dhcp_policies + when: + - version.current.version is version('3.1.1g', '>') + # TODO dhcp policies api endpoint has changed after 4.0, fix when new module is created + - version.current.version is version('4.0', '<') + +- name: Verify change in DHCP policies for mso version > 3.1.1g + assert: + that: + - change_nm_bd_dhcp_policies is changed + - change_nm_bd_dhcp_policies.current.dhcpLabels | length == 2 + - change_nm_bd_dhcp_policies.current.dhcpLabels[0].name == 'ansible_test_dhcp_policy1' + - change_nm_bd_dhcp_policies.current.dhcpLabels[1].name == 'ansible_test_dhcp_policy2' + - change_nm_bd_dhcp_policies.current.dhcpLabels[0].version == 1 + - change_nm_bd_dhcp_policies.current.dhcpLabels[1].version == 1 + - change_nm_bd_dhcp_policies.current.dhcpLabels[0].dhcpOptionLabel.name == 'ansible_test_dhcp_policy_option1' + - change_nm_bd_dhcp_policies.current.dhcpLabels[1].dhcpOptionLabel.name == 'ansible_test_dhcp_policy_option1' + - change_nm_bd_dhcp_policies.current.dhcpLabels[0].dhcpOptionLabel.version == 1 + - change_nm_bd_dhcp_policies.current.dhcpLabels[1].dhcpOptionLabel.version == 1 + when: + - version.current.version is version('3.1.1g', '>') + # TODO dhcp policies api endpoint has changed after 4.0, fix when new module is created + - version.current.version is version('4.0', '<') + +# Add BD with new options for mso version > 3.1.1g +- name: Add bd with new options available in mso versions > 3.1.1g + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_new_options + intersite_bum_traffic: true + optimize_wan_bandwidth: false + layer2_stretch: true + layer2_unknown_unicast: flood + layer3_multicast: false + unknown_multicast_flooding: flood + multi_destination_flooding: drop + ipv6_unknown_multicast_flooding: flood + arp_flooding: false + virtual_mac_address: 00:00:5E:00:01:3C + unicast_routing: true + subnets: + - subnet: 10.0.0.128/24 + - subnet: 10.0.1.254/24 + description: 1234567890 + - ip: 192.168.0.254/24 + description: "My description for a subnet" + scope: private + shared: false + no_default_gateway: true + virtual: true + primary: true + vrf: + name: VRF + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + state: present + register: nm_bd_new_subnet_options + when: version.current.version is version('3.1.1g', '>') + +- name: Verify subnets in nm_bd_new_subnet_options + assert: + that: + - nm_bd_new_subnet_options is changed + - nm_bd_new_subnet_options.current.name == 'ansible_test_new_options' + - nm_bd_new_subnet_options.current.vrfRef.templateName == "Template1" + - nm_bd_new_subnet_options.current.vrfRef.vrfName == "VRF" + - nm_bd_new_subnet_options.current.intersiteBumTrafficAllow == true + - nm_bd_new_subnet_options.current.optimizeWanBandwidth == false + - nm_bd_new_subnet_options.current.l2Stretch == true + - nm_bd_new_subnet_options.current.l2UnknownUnicast == "flood" + - nm_bd_new_subnet_options.current.unkMcastAct == "flood" + - nm_bd_new_subnet_options.current.multiDstPktAct == "drop" + - nm_bd_new_subnet_options.current.l3MCast == false + - nm_bd_new_subnet_options.current.arpFlood == true + - nm_bd_new_subnet_options.current.v6unkMcastAct == "flood" + - nm_bd_new_subnet_options.current.vmac == "00:00:5E:00:01:3C" + - nm_bd_new_subnet_options.current.unicastRouting == true + - nm_bd_new_subnet_options.current.subnets[1].primary == false + - nm_bd_new_subnet_options.current.subnets[0].virtual == false + - nm_bd_new_subnet_options.current.subnets[2].primary == true + - nm_bd_new_subnet_options.current.subnets[2].virtual == true + when: version.current.version is version('3.1.1g', '>') + +# Change BD with new options for mso version > 3.1.1g +- name: Try Changing bd with another subnet to primary IP + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_new_options + intersite_bum_traffic: true + optimize_wan_bandwidth: false + layer2_stretch: true + layer2_unknown_unicast: flood + layer3_multicast: false + unknown_multicast_flooding: flood + multi_destination_flooding: drop + ipv6_unknown_multicast_flooding: flood + arp_flooding: false + virtual_mac_address: 00:00:5E:00:01:3C + unicast_routing: true + subnets: + - subnet: 10.0.0.128/24 + - subnet: 10.0.1.254/24 + description: 1234567890 + primary: true + - ip: 192.168.0.254/24 + description: "My description for a subnet" + scope: private + shared: false + no_default_gateway: true + virtual: true + primary: true + vrf: + name: VRF + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + state: present + register: nm_bd_subnet_second_primary + ignore_errors: yes + when: version.current.version is version('3.1.1g', '>') + +- name: Verify subnets in nm_bd_subnet_second_primary + assert: + that: + - nm_bd_subnet_second_primary.msg is match ("MSO Error 400{{':'}} Bad Request{{':'}} Patch Failed, Received{{':'}} Only one preferred subnet per address family is allowed under BD ansible_test_new_options of Template Template1 exception while trying to update schema") + when: + - version.current.version is version('3.1.1g', '>') + - version.current.version is version('3.3', '<') + +- name: Add bd with new option flood in encap available in mso versions > 3.1.1g with l2 set to true + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_flood_encap + intersite_bum_traffic: true + optimize_wan_bandwidth: false + layer2_stretch: true + layer2_unknown_unicast: flood + layer3_multicast: false + unknown_multicast_flooding: flood + multi_destination_flooding: encap-flood + ipv6_unknown_multicast_flooding: flood + unicast_routing: true + vrf: + name: VRF + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + state: present + ignore_errors: yes + register: nm_bd_new_encap_flood_non + when: version.current.version is version('3.1.1g', '>') + +- name: Verify nm_bd_new_encap_flood_non + assert: + that: + - nm_bd_new_encap_flood_non.msg is match ("MSO Error 400{{':'}} Bad Request{{':'}} Patch Failed, Received{{':'}} Template 'Template1', BD 'ansible_test_flood_encap' {{':'}} Multi destination flood in encapsulation is only supported when l2Stretch is disabled exception while trying to update schema") + when: + - version.current.version is version('3.1.1g', '>') + - version.current.version is version('3.3', '<') + +- name: Add bd with new option flood in encap available in mso versions > 3.1.1g l2 set to false + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_flood_encap + layer2_stretch: false + layer2_unknown_unicast: flood + unknown_multicast_flooding: flood + multi_destination_flooding: encap-flood + ipv6_unknown_multicast_flooding: flood + unicast_routing: true + intersite_bum_traffic: false + vrf: + name: VRF + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + state: present + register: nm_bd_new_encap_flood + when: version.current.version is version('3.1.1g', '>') + +- name: Verify nm_bd_new_encap_flood + assert: + that: + - nm_bd_new_encap_flood.current.multiDstPktAct == "encap-flood" + when: version.current.version is version('3.1.1g', '>') + +- name: Add bd with new option description in mso versions >= 3.3 + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_description + description: ansible_test_bd + layer2_stretch: true + layer2_unknown_unicast: proxy + unknown_multicast_flooding: flood + ipv6_unknown_multicast_flooding: flood + unicast_routing: true + vrf: + name: VRF + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + state: present + register: nm_bd_desc + when: version.current.version is version('3.3', '>=') + +- name: Verify nm_bd_desc + assert: + that: + - nm_bd_desc.current.description == "ansible_test_bd" + when: version.current.version is version('3.3', '>=') + +- name: Add bd with change in description in mso versions >= 3.3 + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_description + description: ansible_test_bd_again + layer2_stretch: true + layer2_unknown_unicast: proxy + unknown_multicast_flooding: flood + ipv6_unknown_multicast_flooding: flood + unicast_routing: true + vrf: + name: VRF + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + state: present + register: nm_bd_desc_2 + when: version.current.version is version('3.3', '>=') + +- name: Verify nm_bd_desc_2 + assert: + that: + - nm_bd_desc_2.current.description == "ansible_test_bd_again" + when: version.current.version is version('3.3', '>=') + +- name: Ensure bd ansible_test_unicast_false is removed >= 3.1.1g + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_unicast_false + state: absent + when: version.current.version is version('3.1.1g', '>') + +- name: Ensure bd ansible_test_unicast_true is removed >= 3.1.1g + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_unicast_true + state: absent + when: version.current.version is version('3.1.1g', '>') + +- name: Add bd with change in unicast routing false in mso versions >= 3.1.1g (check mode) + mso_schema_template_bd: &unicast_routing_false_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_unicast_false + unicast_routing: false + vrf: + name: VRF + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + state: present + check_mode: yes + register: cm_ansible_test_unicast_false + when: version.current.version is version('3.1.1g', '>') + +- name: Add bd with change in unicast routing false in mso versions >= 3.1.1g + mso_schema_template_bd: + <<: *unicast_routing_false_present + register: nm_ansible_test_unicast_false + when: version.current.version is version('3.1.1g', '>') + +- name: Add bd again with unicast routing false in mso versions >= 3.1.1g + mso_schema_template_bd: + <<: *unicast_routing_false_present + register: nm_ansible_test_unicast_false_again + when: version.current.version is version('3.1.1g', '>') + +- name: Change bd with unicast routing to true in mso versions >= 3.1.1g + mso_schema_template_bd: + <<: *unicast_routing_false_present + unicast_routing: true + register: nm_ansible_test_unicast_false_to_true + when: version.current.version is version('3.1.1g', '>') + +- name: Add bd with change in unicast routing true in mso versions >= 3.1.1g (check mode) + mso_schema_template_bd: &unicast_routing_true_present + <<: *unicast_routing_false_present + bd: ansible_test_unicast_true + unicast_routing: true + check_mode: yes + register: cm_ansible_test_unicast_true + when: version.current.version is version('3.1.1g', '>') + +- name: Add bd with change in unicast routing true in mso versions >= 3.1.1g + mso_schema_template_bd: + <<: *unicast_routing_true_present + register: nm_ansible_test_unicast_true + when: version.current.version is version('3.1.1g', '>') + +- name: Add bd again with unicast routing true in mso versions >= 3.1.1g + mso_schema_template_bd: + <<: *unicast_routing_true_present + register: nm_ansible_test_unicast_true_again + when: version.current.version is version('3.1.1g', '>') + +- name: Change bd with unicast routing to false in mso versions >= 3.1.1g + mso_schema_template_bd: + <<: *unicast_routing_true_present + unicast_routing: false + register: nm_ansible_test_unicast_true_to_false + when: version.current.version is version('3.1.1g', '>') + +- name: Verify unicast routing + assert: + that: + - cm_ansible_test_unicast_false is changed + - cm_ansible_test_unicast_false.current.unicastRouting == false + - nm_ansible_test_unicast_false is changed + - nm_ansible_test_unicast_false.current.unicastRouting == false + - nm_ansible_test_unicast_false_again is not changed + - nm_ansible_test_unicast_false_again.previous.unicastRouting == false + - nm_ansible_test_unicast_false_again.current.unicastRouting == false + - nm_ansible_test_unicast_false_to_true is changed + - nm_ansible_test_unicast_false_to_true.current.unicastRouting == true + - cm_ansible_test_unicast_true is changed + - cm_ansible_test_unicast_true.current.unicastRouting == true + - nm_ansible_test_unicast_true is changed + - nm_ansible_test_unicast_true.current.unicastRouting == true + - nm_ansible_test_unicast_true_again is not changed + - nm_ansible_test_unicast_true_again.previous.unicastRouting == true + - nm_ansible_test_unicast_true_again.current.unicastRouting == true + - nm_ansible_test_unicast_true_to_false is changed + - nm_ansible_test_unicast_true_to_false.current.unicastRouting == false + when: version.current.version is version('3.1.1g', '>') + +- name: Remove bd with change in unicast routing false in mso versions >= 3.1.1g + mso_schema_template_bd: + <<: *unicast_routing_false_present + state: absent + register: ansible_test_unicast_false + when: version.current.version is version('3.1.1g', '>') + +- name: Remove bd with change in unicast routing true in mso versions >= 3.1.1g + mso_schema_template_bd: + <<: *unicast_routing_true_present + state: absent + register: ansible_test_unicast_true + when: version.current.version is version('3.1.1g', '>') + +# FIXME: Add missing DHCP Policy changes and checks (missing DHCP Policy module to make sure it is there.) + +# QUERY ALL BD +- name: Query all bd (check_mode) + mso_schema_template_bd: &bd_query + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + state: query + check_mode: yes + register: cm_query_all_bds + +- name: Query all bd (normal mode) + mso_schema_template_bd: + <<: *bd_query + register: nm_query_all_bds + +- name: Verify query_all_bds for version < 3.1.1g + assert: + that: + - cm_query_all_bds is not changed + - nm_query_all_bds is not changed + - cm_query_all_bds.current | length == nm_query_all_bds.current | length == 2 + when: version.current.version is version('3.1.1g', '<') + +- name: Verify query_all_bds for version > 3.1.1g and version < 3.3 + assert: + that: + - cm_query_all_bds is not changed + - nm_query_all_bds is not changed + - cm_query_all_bds.current | length == nm_query_all_bds.current | length == 5 + when: + - version.current.version is version('3.1.1g', '>') + - version.current.version is version('3.3', '<') + +- name: Verify query_all_bds for version >= 3.3 and < 4.0 + assert: + that: + - cm_query_all_bds is not changed + - nm_query_all_bds is not changed + - cm_query_all_bds.current | length == nm_query_all_bds.current | length == 6 + when: + - version.current.version is version('3.3', '>=') + - version.current.version is version('3.7', '<') + +- name: Verify query_all_bds for version >= 4.0 + assert: + that: + - cm_query_all_bds is not changed + - nm_query_all_bds is not changed + - cm_query_all_bds.current | length == nm_query_all_bds.current | length == 5 + when: version.current.version is version('4.0', '>=') + +# QUERY A BD +- name: Query bd 1 + mso_schema_template_bd: + <<: *bd_query + bd: ansible_test_1 + check_mode: yes + register: cm_query_bd + +- name: Query bd 1 + mso_schema_template_bd: + <<: *bd_query + bd: ansible_test_1 + register: nm_query_bd + +- name: Query bd 2 + mso_schema_template_bd: + <<: *bd_query + template: Template2 + bd: ansible_test_2 + register: nm_query_bd_2 + +- name: Query bd 3 + mso_schema_template_bd: + <<: *bd_query + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template3 + bd: ansible_test_3 + register: nm_query_bd_3 + +- name: Query bd 5 + mso_schema_template_bd: + <<: *bd_query + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template5 + bd: ansible_test_5 + register: nm_query_bd_5 + +- name: Verify query_bd + assert: + that: + - cm_query_bd is not changed + - nm_query_bd is not changed + - cm_query_bd.current.name == nm_query_bd.current.name == "ansible_test_1" + - cm_query_bd == nm_query_bd + - nm_query_bd_2.current.name == "ansible_test_2" + - nm_query_bd_3.current.name == "ansible_test_3" + - nm_query_bd_2.current.intersiteBumTrafficAllow == true + - nm_query_bd_2.current.optimizeWanBandwidth == true + - nm_query_bd_2.current.l2Stretch == true + - nm_query_bd_2.current.l2UnknownUnicast == "flood" + - nm_query_bd_2.current.l3MCast == true + - nm_query_bd_2.current.subnets[0].description == "10.0.0.128/24" + - nm_query_bd_2.current.subnets[0].ip == "10.0.0.128/24" + - nm_query_bd_2.current.subnets[0].noDefaultGateway == false + - nm_query_bd_2.current.subnets[0].scope == "private" + - nm_query_bd_2.current.subnets[0].shared == false + - nm_query_bd_2.current.subnets[1].description == "1234567890" + - nm_query_bd_2.current.subnets[1].ip == "10.0.1.254/24" + - nm_query_bd_2.current.subnets[1].noDefaultGateway == false + - nm_query_bd_2.current.subnets[1].scope == "private" + - nm_query_bd_2.current.subnets[1].shared == false + - nm_query_bd_2.current.subnets[2].description == "My description for a subnet" + - nm_query_bd_2.current.subnets[2].ip == "172.16.0.1/24" + - nm_query_bd_2.current.subnets[2].noDefaultGateway == false + - nm_query_bd_2.current.subnets[2].scope == "public" + - nm_query_bd_2.current.subnets[2].shared == true + - nm_query_bd_2.current.subnets[3].description == "My description for a subnet" + - nm_query_bd_2.current.subnets[3].ip == "192.168.0.254/24" + - nm_query_bd_2.current.subnets[3].noDefaultGateway == true + - nm_query_bd_2.current.subnets[3].scope == "private" + - nm_query_bd_2.current.subnets[3].shared == false + +- name: Verify nm_query_bd_5 for a version that's before 3.1 + assert: + that: + - nm_query_bd_5 is not changed + - nm_query_bd_5.current.name == "ansible_test_5" + - nm_query_bd_5.current.intersiteBumTrafficAllow == true + - nm_query_bd_5.current.optimizeWanBandwidth == true + - nm_query_bd_5.current.l2Stretch == true + - nm_query_bd_5.current.l2UnknownUnicast == "flood" + - nm_query_bd_5.current.l3MCast == false + when: version.current.version is version('3.1.1g', '<') + +- name: Verify nm_query_bd_5 for a version that's 3.1 + assert: + that: + - nm_query_bd_5 is not changed + - nm_query_bd_5.current.name == "ansible_test_5" + - nm_query_bd_5.current.intersiteBumTrafficAllow == true + - nm_query_bd_5.current.optimizeWanBandwidth == true + - nm_query_bd_5.current.l2Stretch == true + - nm_query_bd_5.current.l2UnknownUnicast == "flood" + - nm_query_bd_5.current.l3MCast == false + - nm_query_bd_5.current.unkMcastAct == "flood" + - nm_query_bd_5.current.v6unkMcastAct == "flood" + - nm_query_bd_5.current.vmac == "00:00:5E:00:01:3C" + - nm_query_bd_5.current.multiDstPktAct == "drop" + - nm_query_bd_5.current.arpFlood == true + when: version.current.version is version('3.1.1g', '>=') + +- name: Query bd with multiple dhcp policies for mso version > 3.1.1g + mso_schema_template_bd: + <<: *bd_query + bd: ansible_test_multiple_dhcp + state: query + register: query_nm_bd_dhcp_policies + when: + - version.current.version is version('3.1.1g', '>') + # TODO dhcp policies api endpoint has changed after 4.0, fix when new module is created + - version.current.version is version('4.0', '<') + +- name: Verify query of DHCP policies for mso version > 3.1.1g + assert: + that: + - query_nm_bd_dhcp_policies is not changed + - query_nm_bd_dhcp_policies.current.name == 'ansible_test_multiple_dhcp' + - query_nm_bd_dhcp_policies.current.dhcpLabels | length == 2 + - query_nm_bd_dhcp_policies.current.dhcpLabels[0].name == 'ansible_test_dhcp_policy1' + - query_nm_bd_dhcp_policies.current.dhcpLabels[1].name == 'ansible_test_dhcp_policy2' + - query_nm_bd_dhcp_policies.current.dhcpLabels[0].version == 1 + - query_nm_bd_dhcp_policies.current.dhcpLabels[1].version == 1 + - query_nm_bd_dhcp_policies.current.dhcpLabels[0].dhcpOptionLabel.name == 'ansible_test_dhcp_policy_option1' + - query_nm_bd_dhcp_policies.current.dhcpLabels[1].dhcpOptionLabel.name == 'ansible_test_dhcp_policy_option1' + - query_nm_bd_dhcp_policies.current.dhcpLabels[0].dhcpOptionLabel.version == 1 + - query_nm_bd_dhcp_policies.current.dhcpLabels[1].dhcpOptionLabel.version == 1 + when: + - version.current.version is version('3.1.1g', '>') + # TODO dhcp policies api endpoint has changed after 4.0, fix when new module is created + - version.current.version is version('4.0', '<') + +# Query BD with new options for mso version > 3.1.1g +- name: Query bd with new option flood in encap available in mso versions > 3.1.1g with l2 set to false + mso_schema_template_bd: + <<: *bd_query + bd: ansible_test_flood_encap + state: query + register: query_bd_new_encap_flood + when: version.current.version is version('3.1.1g', '>') + +- name: Verify query_bd_new_encap_flood + assert: + that: + - query_bd_new_encap_flood is not changed + - query_bd_new_encap_flood.current.name == 'ansible_test_flood_encap' + - query_bd_new_encap_flood.current.intersiteBumTrafficAllow == false + - query_bd_new_encap_flood.current.optimizeWanBandwidth == false + - query_bd_new_encap_flood.current.l2Stretch == false + - query_bd_new_encap_flood.current.l2UnknownUnicast == "flood" + - query_bd_new_encap_flood.current.unkMcastAct == "flood" + - query_bd_new_encap_flood.current.multiDstPktAct == "encap-flood" + - query_bd_new_encap_flood.current.arpFlood == true + - query_bd_new_encap_flood.current.v6unkMcastAct == "flood" + - query_bd_new_encap_flood.current.unicastRouting == true + when: version.current.version is version('3.1.1g', '>') + +- name: Verify query_bd_new_encap_flood + assert: + that: + - query_bd_new_encap_flood.current.l3MCast == false + when: version.current.version is version('3.2', '>=') + +# REMOVE BD +- name: Remove bd (check_mode) + mso_schema_template_bd: &bd_absent + <<: *bd_query + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + state: absent + check_mode: yes + register: cm_remove_bd + +- name: Verify cm_remove_bd + assert: + that: + - cm_remove_bd is changed + - cm_remove_bd.current == {} + +- name: Remove bd (normal mode) + mso_schema_template_bd: + <<: *bd_absent + register: nm_remove_bd + +- name: Verify nm_remove_bd + assert: + that: + - nm_remove_bd is changed + - nm_remove_bd.current == {} + +- name: Remove bd again (check_mode) + mso_schema_template_bd: + <<: *bd_absent + check_mode: yes + register: cm_remove_bd_again + +- name: Verify cm_remove_bd_again + assert: + that: + - cm_remove_bd_again is not changed + - cm_remove_bd_again.current == {} + +- name: Remove bd again (normal mode) + mso_schema_template_bd: + <<: *bd_absent + register: nm_remove_bd_again + +- name: Verify nm_remove_bd_again + assert: + that: + - nm_remove_bd_again is not changed + - nm_remove_bd_again.current == {} + +- name: Remove bd 5 (normal mode) + mso_schema_template_bd: + <<: *bd_absent + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template5 + bd: ansible_test_5 + register: nm_remove_bd_5 + +- name: Verify nm_remove_bd_5 + assert: + that: + - nm_remove_bd_5 is changed + - nm_remove_bd_5.current == {} + +- name: Remove bd ansible_test_multiple_dhcp (normal mode) + mso_schema_template_bd: + <<: *bd_absent + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_multiple_dhcp + register: nm_remove_ansible_test_multiple_dhcp + when: + - version.current.version is version('3.1.1g', '>') + # TODO dhcp policies api endpoint has changed after 4.0, fix when new module is created + - version.current.version is version('4.0', '<') + +- name: Verify nm_remove_ansible_test_multiple_dhcp + assert: + that: + - nm_remove_ansible_test_multiple_dhcp is changed + - nm_remove_ansible_test_multiple_dhcp.current == {} + when: + - version.current.version is version('3.1.1g', '>') + # TODO dhcp policies api endpoint has changed after 4.0, fix when new module is created + - version.current.version is version('4.0', '<') + +# QUERY NON-EXISTING BD +- name: Query non-existing bd (check_mode) + mso_schema_template_bd: + <<: *bd_query + bd: ansible_test_1 + check_mode: yes + ignore_errors: yes + register: cm_query_non_bd + +- name: Query non-existing bd (normal mode) + mso_schema_template_bd: + <<: *bd_query + bd: ansible_test_1 + ignore_errors: yes + register: nm_query_non_bd + +- name: Verify query_non_bd + assert: + that: + - cm_query_non_bd is not changed + - nm_query_non_bd is not changed + - cm_query_non_bd == nm_query_non_bd + - cm_query_non_bd.msg == nm_query_non_bd.msg == "BD 'ansible_test_1' not found" + + +# USE A NON-EXISTING STATE +- name: Non-existing state for bd (check_mode) + mso_schema_template_bd: + <<: *bd_query + state: non-existing-state + check_mode: yes + ignore_errors: yes + register: cm_non_existing_state + +- name: Non-existing state for bd (normal_mode) + mso_schema_template_bd: + <<: *bd_query + state: non-existing-state + ignore_errors: yes + register: nm_non_existing_state + +- name: Verify non_existing_state + assert: + that: + - cm_non_existing_state is not changed + - nm_non_existing_state is not changed + - cm_non_existing_state == nm_non_existing_state + - cm_non_existing_state.msg == nm_non_existing_state.msg == "value of state must be one of{{':'}} absent, present, query, got{{':'}} non-existing-state" + +# USE A NON-EXISTING SCHEMA +- name: Non-existing schema for bd (check_mode) + mso_schema_template_bd: + <<: *bd_query + schema: non-existing-schema + check_mode: yes + ignore_errors: yes + register: cm_non_existing_schema + +- name: Non-existing schema for bd (normal_mode) + mso_schema_template_bd: + <<: *bd_query + schema: non-existing-schema + ignore_errors: yes + register: nm_non_existing_schema + +- name: Verify non_existing_schema + assert: + that: + - cm_non_existing_schema is not changed + - nm_non_existing_schema is not changed + - cm_non_existing_schema == nm_non_existing_schema + - cm_non_existing_schema.msg == nm_non_existing_schema.msg == "Provided schema 'non-existing-schema' does not exist." + +# USE A NON-EXISTING TEMPLATE +- name: Non-existing template for bd (check_mode) + mso_schema_template_bd: + <<: *bd_query + template: non-existing-template + check_mode: yes + ignore_errors: yes + register: cm_non_existing_template + +- name: Non-existing template for bd (normal_mode) + mso_schema_template_bd: + <<: *bd_query + template: non-existing-template + ignore_errors: yes + register: nm_non_existing_template + +- name: Verify non_existing_template + assert: + that: + - cm_non_existing_template is not changed + - nm_non_existing_template is not changed + - cm_non_existing_template == nm_non_existing_template + - cm_non_existing_template.msg == nm_non_existing_template.msg == "Provided template 'non-existing-template' does not exist. Existing templates{{':'}} Template1, Template2" + +# CLEAN UP DHCP Policies +- name: Ensure DHCP policies are removed + mso_dhcp_relay_policy: + <<: *mso_info + dhcp_relay_policy: '{{ item }}' + tenant: ansible_test + state: absent + loop: + - 'ansible_test_dhcp_policy1' + - 'ansible_test_dhcp_policy2' + - 'ansible_test_dhcp_policy3' + when: + # TODO dhcp policies api endpoint has changed after 4.0, fix when new module is created + - version.current.version is version('4.0', '<') + +- name: Ensure DHCP option policies are removed + mso_dhcp_option_policy: + <<: *mso_info + dhcp_option_policy: '{{ item }}' + tenant: ansible_test + state: absent + loop: + - 'ansible_test_dhcp_policy_option1' + - 'ansible_test_dhcp_policy_option2' + - 'ansible_test_dhcp_policy_option3' + when: + # TODO dhcp policies api endpoint has changed after 4.0, fix when new module is created + - version.current.version is version('4.0', '<') + +# REMOVE Schemas for next CI Run +- name: Remove schemas for next ci test + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}'
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_bd_dhcp_policy/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_bd_dhcp_policy/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_bd_dhcp_policy/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_bd_dhcp_policy/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_bd_dhcp_policy/tasks/main.yml new file mode 100644 index 00000000..7c602691 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_bd_dhcp_policy/tasks/main.yml @@ -0,0 +1,454 @@ +# Test code for the MSO modules +# Copyright: (c) 2021, Shreyas Srish (@shrsr) <ssrish@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") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Execute tasks on MSO version > 3.1.1g + when: + - version.current.version is version('3.1.1g', '>') + # TODO dhcp policies api endpoint has changed after 4.0, fix when new module is created + - version.current.version is version('4.0', '<') + block: + - name: Remove schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + + - name: Remove DHCP policies + mso_dhcp_relay_policy: + <<: *mso_info + dhcp_relay_policy: '{{ item }}' + tenant: ansible_test + state: absent + loop: + - 'ansible_test_dhcp_policy1' + - 'ansible_test_dhcp_policy2' + - 'ansible_test_dhcp_policy3' + + - name: Remove DHCP option policies + mso_dhcp_option_policy: + <<: *mso_info + dhcp_option_policy: '{{ item }}' + tenant: ansible_test + state: absent + loop: + - 'ansible_test_dhcp_policy_option1' + - 'ansible_test_dhcp_policy_option2' + + - name: Ensure tenant ansible_test exist + mso_tenant: &tenant_present + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + sites: + - '{{ mso_site | default("ansible_test") }}' + state: present + + - name: Ensure schema 1 with Template1 exist + mso_schema_template: &schema_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template1 + state: present + + - name: Ensure VRF exists + mso_schema_template_vrf: &vrf_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + vrf: VRF + layer3_multicast: true + state: present + + - name: Ensure multiple DHCP policies exist + mso_dhcp_relay_policy: + <<: *mso_info + dhcp_relay_policy: '{{ item }}' + description: "My Test DHCP Policies" + tenant: ansible_test + state: present + loop: + - 'ansible_test_dhcp_policy1' + - 'ansible_test_dhcp_policy2' + - 'ansible_test_dhcp_policy3' + + - name: Ensure multiple DHCP option policies exist + mso_dhcp_option_policy: + <<: *mso_info + dhcp_option_policy: '{{ item }}' + description: "My Test DHCP Policy Options" + tenant: ansible_test + state: present + loop: + - 'ansible_test_dhcp_policy_option1' + - 'ansible_test_dhcp_policy_option2' + + # ADD BD + - name: Add bd + mso_schema_template_bd: &bd_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + intersite_bum_traffic: true + optimize_wan_bandwidth: true + layer2_stretch: true + layer2_unknown_unicast: proxy + vrf: + name: VRF + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + state: present + + - name: Add bd2 + mso_schema_template_bd: + <<: *bd_present + bd: ansible_test_2 + state: present + + # Add dhcp policies + - name: Add DHCP policy in check mode + mso_schema_template_bd_dhcp_policy: &dhcp_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + name: ansible_test_dhcp_policy1 + version: 1 + dhcp_option_policy: + name: ansible_test_dhcp_policy_option1 + version: 1 + register: cm_add_dhcp + check_mode: yes + + - name: Add DHCP policy in normal mode + mso_schema_template_bd_dhcp_policy: + <<: *dhcp_present + register: nm_add_dhcp + + - name: Add DHCP policy again in normal mode + mso_schema_template_bd_dhcp_policy: + <<: *dhcp_present + register: nm_add_dhcp_again + + - name: Add another DHCP policy in normal mode + mso_schema_template_bd_dhcp_policy: + <<: *dhcp_present + name: ansible_test_dhcp_policy2 + version: 1 + dhcp_option_policy: + name: ansible_test_dhcp_policy_option2 + version: 1 + register: nm_add_dhcp2 + + + - name: Add dhcp for query all (normal mode) + mso_schema_template_bd_dhcp_policy: + <<: *dhcp_present + name: ansible_test_dhcp_policy3 + version: 1 + register: nm_add_dhcp3 + + - name: Verify cm_add_dhcp, nm_add_dhcp, nm_add_dhcp2 and nm_add_dhcp3 + assert: + that: + - cm_add_dhcp is changed + - nm_add_dhcp is changed + - nm_add_dhcp_again is not changed + - nm_add_dhcp.current.name == 'ansible_test_dhcp_policy1' + - nm_add_dhcp.current.version == 1 + - nm_add_dhcp.current.dhcpOptionLabel.name == 'ansible_test_dhcp_policy_option1' + - nm_add_dhcp.current.dhcpOptionLabel.version == 1 + - nm_add_dhcp2.current.name == 'ansible_test_dhcp_policy2' + - nm_add_dhcp2.current.version == 1 + - nm_add_dhcp2.current.dhcpOptionLabel.name == 'ansible_test_dhcp_policy_option2' + - nm_add_dhcp2.current.dhcpOptionLabel.version == 1 + - nm_add_dhcp3.current.name == 'ansible_test_dhcp_policy3' + - nm_add_dhcp3.current.version == 1 + + # CHANGE dhcp policies + - name: Change dhcp policy (normal mode) + mso_schema_template_bd_dhcp_policy: + <<: *dhcp_present + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + name: ansible_test_dhcp_policy1 + version: 1 + dhcp_option_policy: + name: ansible_test_dhcp_policy_option2 + version: 1 + register: nm_change_dhcp + + - name: Verify nm_change_dhcp + assert: + that: + - nm_change_dhcp is changed + - nm_change_dhcp.current.name == 'ansible_test_dhcp_policy1' + - nm_change_dhcp.current.version == 1 + - nm_change_dhcp.current.dhcpOptionLabel.name == 'ansible_test_dhcp_policy_option2' + + - name: Change dhcp policy again (normal mode) + mso_schema_template_bd_dhcp_policy: + <<: *dhcp_present + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + name: ansible_test_dhcp_policy1 + version: 1 + dhcp_option_policy: + name: ansible_test_dhcp_policy_option1 + version: 1 + register: nm_change_dhcp_again + + + - name: Verify nm_change_dhcp + assert: + that: + - nm_change_dhcp_again is changed + - nm_change_dhcp_again.current.name == 'ansible_test_dhcp_policy1' + - nm_change_dhcp_again.current.version == 1 + - nm_change_dhcp_again.current.dhcpOptionLabel.name == 'ansible_test_dhcp_policy_option1' + + # QUERY ALL dhcp policies + - name: Query all dhcp (check_mode) + mso_schema_template_bd_dhcp_policy: &dhcp_query + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + state: query + check_mode: yes + register: cm_query_all_dhcp + + + - name: Query all dhcp (normal mode) + mso_schema_template_bd_dhcp_policy: + <<: *dhcp_query + register: nm_query_all_dhcp + + + - name: Verify query_all_dhcp + assert: + that: + - cm_query_all_dhcp is not changed + - nm_query_all_dhcp is not changed + - cm_query_all_dhcp.current | length == nm_query_all_dhcp.current | length == 3 + + # QUERY a DHCP policy + - name: Query single dhcp + mso_schema_template_bd_dhcp_policy: + <<: *dhcp_query + name: ansible_test_dhcp_policy1 + register: nm_query_dhcp + + - name: Verify nm_query_dhcp + assert: + that: + - nm_query_dhcp is not changed + - nm_query_dhcp.current.name == 'ansible_test_dhcp_policy1' + - nm_query_dhcp.current.version == 1 + - nm_query_dhcp.current.dhcpOptionLabel.name == 'ansible_test_dhcp_policy_option1' + + # QUERY a non associated DHCP policy + - name: Query non associated dhcp + mso_schema_template_bd_dhcp_policy: + <<: *dhcp_query + bd: ansible_test_2 + name: ansible_test_dhcp_policy1 + ignore_errors: yes + register: non_dhcp + + - name: Verify non_dhcp + assert: + that: + - non_dhcp.msg is match ("DHCP policy not associated with the bd") + + # REMOVE DHCP policy + - name: Remove dhcp policy + mso_schema_template_bd_dhcp_policy: &dhcp_absent + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + name: ansible_test_dhcp_policy1 + state: absent + register: nm_remove_dhcp + + - name: Verify nm_remove_dhcp + assert: + that: + - nm_remove_dhcp is changed + - nm_remove_dhcp.current == {} + + - name: Remove dhcp again (check_mode) + mso_schema_template_bd_dhcp_policy: + <<: *dhcp_absent + register: nm_remove_dhcp_again + + + - name: Verify nm_remove_dhcp_again + assert: + that: + - nm_remove_dhcp_again is not changed + - nm_remove_dhcp_again.current == {} + + # QUERY NON-EXISTING DHCP policy + - name: Query non-existing dhcp policy + mso_schema_template_bd_dhcp_policy: + <<: *dhcp_query + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + name: non_policy + version: 1 + dhcp_option_policy: + name: ansible_test_dhcp_policy_option1 + version: 1 + ignore_errors: yes + register: nm_query_non_dhcp + + - name: Verify nm_query_non_dhcp + assert: + that: + - nm_query_non_dhcp is not changed + - nm_query_non_dhcp.msg is match ("DHCP policy 'non_policy' does not exist") + + # QUERY NON-EXISTING DHCP policy option + - name: Query non-existing dhcp policy option + mso_schema_template_bd_dhcp_policy: + <<: *dhcp_query + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + name: ansible_test_dhcp_policy1 + version: 1 + dhcp_option_policy: + name: non_option + version: 1 + ignore_errors: yes + register: nm_query_non_dhcp_option + + - name: Verify nm_query_non_dhcp + assert: + that: + - nm_query_non_dhcp_option is not changed + - nm_query_non_dhcp_option.msg is match ("DHCP option policy 'non_option' does not exist") + + # USE A NON-EXISTING STATE + - name: Non-existing state for dhcp + mso_schema_template_bd_dhcp_policy: + <<: *dhcp_query + state: non-existing-state + ignore_errors: yes + register: nm_non_existing_state + + - name: Verify non_existing_state + assert: + that: + - nm_non_existing_state is not changed + - nm_non_existing_state.msg is match ("value of state must be one of{{':'}} absent, present, query, got{{':'}} non-existing-state") + + # USE A NON-EXISTING SCHEMA + - name: Non-existing schema for dhcp + mso_schema_template_bd_dhcp_policy: + <<: *dhcp_query + schema: non-existing-schema + ignore_errors: yes + register: nm_non_existing_schema + + - name: Verify non_existing_schema + assert: + that: + - nm_non_existing_schema is not changed + - nm_non_existing_schema.msg is match ("Provided schema 'non-existing-schema' does not exist.") + + # USE A NON-EXISTING TEMPLATE + - name: Non-existing template for dhcp + mso_schema_template_bd_dhcp_policy: + <<: *dhcp_query + template: non-existing-template + ignore_errors: yes + register: nm_non_existing_template + + - name: Verify non_existing_template + assert: + that: + - nm_non_existing_template is not changed + - nm_non_existing_template.msg is match ("Provided template 'non-existing-template' does not exist. Existing templates{{':'}} Template1") + + # USE A NON-EXISTING BD + - name: Non-existing bd for dhcp + mso_schema_template_bd_dhcp_policy: + <<: *dhcp_query + bd: non-existing-bd + ignore_errors: yes + register: nm_non_existing_bd + + - name: Verify non_existing_bd + assert: + that: + - nm_non_existing_bd is not changed + - nm_non_existing_bd.msg is match ("Provided BD 'non-existing-bd' does not exist. Existing BDs{{':'}} ansible_test_1") + + # REMOVE Schemas for next CI Run + - name: Remove schemas for next ci test + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + + # CLEAN UP DHCP Policies + - name: Ensure DHCP policies are removed + mso_dhcp_relay_policy: + <<: *mso_info + dhcp_relay_policy: '{{ item }}' + tenant: ansible_test + state: absent + loop: + - 'ansible_test_dhcp_policy1' + - 'ansible_test_dhcp_policy2' + - 'ansible_test_dhcp_policy3' + + - name: Ensure DHCP option policies are removed + mso_dhcp_option_policy: + <<: *mso_info + dhcp_option_policy: '{{ item }}' + tenant: ansible_test + state: absent + loop: + - 'ansible_test_dhcp_policy_option1' + - 'ansible_test_dhcp_policy_option2'
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_bd_subnet/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_bd_subnet/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_bd_subnet/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_bd_subnet/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_bd_subnet/tasks/main.yml new file mode 100644 index 00000000..e29c1e4c --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_bd_subnet/tasks/main.yml @@ -0,0 +1,630 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Lionel Hercot (@lhercot) <lhercot@cisco.com> +# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> (based on mso_site test case) +# + +# 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") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Set version vars + set_fact: + mso_l3mcast: false + when: version.current.version is version('2.2.4', '=') + +- name: Ensure site exist + mso_site: &site_present + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + apic_username: '{{ apic_username }}' + apic_password: '{{ apic_password }}' + apic_site_id: '{{ apic_site_id | default(101) }}' + urls: + - https://{{ apic_hostname }} + state: present + +- name: Remove schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Ensure tenant ansible_test exist + mso_tenant: &tenant_present + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + sites: + - '{{ mso_site | default("ansible_test") }}' + state: present + +- name: Ensure schema 1 with Template1 exist + mso_schema_template: &schema_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template1 + state: present + +- name: Ensure schema 2 with Template2 exists + mso_schema_template: + <<: *schema_present + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template2 + state: present + +- name: Ensure VRF exists + mso_schema_template_vrf: &vrf_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + vrf: VRF + layer3_multicast: true + state: present + +- name: Ensure VRF2 exists + mso_schema_template_vrf: + <<: *vrf_present + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template2 + vrf: VRF2 + +# ADD BD +- name: Add bd + mso_schema_template_bd: &bd_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + intersite_bum_traffic: true + optimize_wan_bandwidth: true + layer2_stretch: true + layer2_unknown_unicast: proxy + vrf: + name: VRF + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + dhcp_policy: + name: ansible_test + version: 1 + dhcp_option_policy: + name: ansible_test_option + version: 1 + state: present + +- name: Add bd 2 + mso_schema_template_bd: + <<: *bd_present + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template2 + bd: ansible_test_2 + intersite_bum_traffic: true + optimize_wan_bandwidth: true + layer2_stretch: true + layer2_unknown_unicast: proxy + vrf: + name: VRF2 + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template2 + dhcp_policy: + name: ansible_test + version: 1 + dhcp_option_policy: + name: ansible_test_option + version: 1 + +- name: Add bd + mso_schema_template_bd: + <<: *bd_present + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_3 + intersite_bum_traffic: true + optimize_wan_bandwidth: true + layer2_stretch: true + layer2_unknown_unicast: proxy + vrf: + name: VRF + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + dhcp_policy: + name: ansible_test + version: 1 + dhcp_option_policy: + name: ansible_test_option + version: 1 + state: present + +# Add subnet +- name: Add subnet in check mode + mso_schema_template_bd_subnet: &subnet_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + subnet: 172.16.0.1/24 + description: "My description for a subnet" + scope: public + shared: true + no_default_gateway: false + querier: true + state: present + register: cm_add_subnet + check_mode: yes + +- name: Add subnet (normal mode) + mso_schema_template_bd_subnet: + <<: *subnet_present + register: nm_add_subnet + +- name: Add subnet again (normal mode) + mso_schema_template_bd_subnet: + <<: *subnet_present + register: nm_add_subnet_again + +- name: Add subnet for query all (normal mode) + mso_schema_template_bd_subnet: + <<: *subnet_present + subnet: 2.16.0.1/24 + +- name: Verify cm_add_subnet and nm_add_subnet + assert: + that: + - cm_add_subnet is changed + - nm_add_subnet is changed + - nm_add_subnet_again is not changed + - cm_add_subnet.current.description == "My description for a subnet" + - cm_add_subnet.current.ip == "172.16.0.1/24" + - cm_add_subnet.current.noDefaultGateway == false + - cm_add_subnet.current.scope == "public" + - cm_add_subnet.current.shared == true + - cm_add_subnet.current.querier == true + - nm_add_subnet.current.description == "My description for a subnet" + - nm_add_subnet.current.ip == "172.16.0.1/24" + - nm_add_subnet.current.noDefaultGateway == false + - nm_add_subnet.current.scope == "public" + - nm_add_subnet.current.shared == true + - nm_add_subnet.current.querier == true + +- name: Add subnet 2 (normal mode) + mso_schema_template_bd_subnet: + <<: *subnet_present + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template2 + bd: ansible_test_2 + subnet: 10.1.1.1/24 + description: "My description for a subnet with virtual ip" + scope: public + shared: true + no_default_gateway: false + querier: true + is_virtual_ip: true + register: nm_add_subnet_2 + +- name: Verify nm_bd_2 for a version that's < 3.1 + assert: + that: + - nm_add_subnet_2.current.ip == "10.1.1.1/24" + - nm_add_subnet_2.current.noDefaultGateway == false + - nm_add_subnet_2.current.scope == "public" + - nm_add_subnet_2.current.shared == true + - nm_add_subnet_2.current.querier == true + when: version.current.version is version('3.1.1g', '<') + +- name: Verify nm_bd_2 for a version that's >= 3.1 + assert: + that: + - nm_add_subnet_2.current.ip == "10.1.1.1/24" + - nm_add_subnet_2.current.noDefaultGateway == false + - nm_add_subnet_2.current.scope == "public" + - nm_add_subnet_2.current.shared == true + - nm_add_subnet_2.current.querier == true + - nm_add_subnet_2.current.virtual == true + when: version.current.version is version('3.1.1g', '>=') + +# CHANGE Subnet +- name: Change subnet 2 (normal mode) + mso_schema_template_bd_subnet: + <<: *subnet_present + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template2 + bd: ansible_test_2 + subnet: 10.1.1.1/24 + description: "My description for a subnet with virtual ip" + scope: public + shared: true + no_default_gateway: false + querier: true + is_virtual_ip: false + register: nm_change_subnet2 + +- name: Verify nm_change_subnet2 for a version < 3.1 + assert: + that: + - nm_change_subnet2 is not changed + - nm_change_subnet2.current.ip == "10.1.1.1/24" + - nm_change_subnet2.current.noDefaultGateway == false + - nm_change_subnet2.current.scope == "public" + - nm_change_subnet2.current.shared == true + - nm_change_subnet2.current.querier == true + when: version.current.version is version('3.1.1g', '<') + +- name: Verify nm_change_subnet2 for a version >= 3.1 + assert: + that: + - nm_change_subnet2 is changed + - nm_change_subnet2.current.ip == "10.1.1.1/24" + - nm_change_subnet2.current.noDefaultGateway == false + - nm_change_subnet2.current.scope == "public" + - nm_change_subnet2.current.shared == true + - nm_change_subnet2.current.querier == true + - nm_change_subnet2.current.virtual == false + when: version.current.version is version('3.1.1g', '>=') + +- name: Change subnet2 again (normal mode) + mso_schema_template_bd_subnet: + <<: *subnet_present + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template2 + bd: ansible_test_2 + subnet: 10.1.1.1/24 + description: "My description for a subnet with virtual ip" + scope: public + shared: true + no_default_gateway: false + querier: true + is_virtual_ip: false + register: nm_change_subnet2_again + +- name: Verify nm_change_subnet2_again for a version that's < 3.1 + assert: + that: + - nm_change_subnet2_again is not changed + - nm_change_subnet2_again.current.ip == "10.1.1.1/24" + - nm_change_subnet2_again.current.noDefaultGateway == false + - nm_change_subnet2_again.current.scope == "public" + - nm_change_subnet2_again.current.shared == true + - nm_change_subnet2_again.current.querier == true + when: version.current.version is version('3.1.1g', '<') + +- name: Verify cm_change_subnet2 for a version that's >= 3.1 + assert: + that: + - nm_change_subnet2_again is not changed + - nm_change_subnet2_again.current.ip == "10.1.1.1/24" + - nm_change_subnet2_again.current.noDefaultGateway == false + - nm_change_subnet2_again.current.scope == "public" + - nm_change_subnet2_again.current.shared == true + - nm_change_subnet2_again.current.querier == true + - nm_change_subnet2_again.current.virtual == false + when: version.current.version is version('3.1.1g', '>=') + +# Primary parameter +- name: Add subnet 3 with primary and querier parameters (normal mode) + mso_schema_template_bd_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + subnet: 10.1.1.5/24 + description: "My description for a subnet with virtual ip" + scope: public + shared: true + no_default_gateway: false + querier: true + primary: true + is_virtual_ip: true + state: present + register: nm_add_subnet_3 + +- name: Verify nm_add_subnet_3 for a version that's < 3.1 + assert: + that: + - nm_add_subnet_3.current.ip == "10.1.1.5/24" + - nm_add_subnet_3.current.noDefaultGateway == false + - nm_add_subnet_3.current.scope == "public" + - nm_add_subnet_3.current.shared == true + - nm_add_subnet_3.current.querier == true + when: version.current.version is version('3.1.1g', '<') + +- name: Verify nm_add_subnet_3 for a version that's >= 3.1 + assert: + that: + - nm_add_subnet_3.current.ip == "10.1.1.5/24" + - nm_add_subnet_3.current.noDefaultGateway == false + - nm_add_subnet_3.current.scope == "public" + - nm_add_subnet_3.current.shared == true + - nm_add_subnet_3.current.querier == true + - nm_add_subnet_3.current.virtual == true + - nm_add_subnet_3.current.primary == true + when: version.current.version is version('3.1.1g', '>=') + +# CHANGE Subnet +- name: Change subnet 3 (normal mode) + mso_schema_template_bd_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + subnet: 10.1.1.5/24 + description: "My description for a subnet with virtual ip" + scope: public + shared: true + no_default_gateway: false + querier: true + is_virtual_ip: false + primary: true + state: present + register: nm_change_subnet3 + +- name: Verify nm_change_subnet3 for a version < 3.1 + assert: + that: + - nm_change_subnet3 is not changed + - nm_change_subnet3.current.ip == "10.1.1.5/24" + - nm_change_subnet3.current.noDefaultGateway == false + - nm_change_subnet3.current.scope == "public" + - nm_change_subnet3.current.shared == true + - nm_change_subnet3.current.querier == true + when: version.current.version is version('3.1.1g', '<') + +- name: Verify nm_change_subnet2 for a version >= 3.1 + assert: + that: + - nm_change_subnet3 is changed + - nm_change_subnet3.current.ip == "10.1.1.5/24" + - nm_change_subnet3.current.noDefaultGateway == false + - nm_change_subnet3.current.scope == "public" + - nm_change_subnet3.current.shared == true + - nm_change_subnet3.current.querier == true + - nm_change_subnet3.current.virtual == false + - nm_change_subnet3.current.primary == true + when: version.current.version is version('3.1.1g', '>=') + +- name: Change subnet3 again (normal mode) + mso_schema_template_bd_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + subnet: 10.1.1.5/24 + description: "My description for a subnet with virtual ip" + scope: public + shared: true + no_default_gateway: false + querier: true + is_virtual_ip: false + primary: true + state: present + register: nm_change_subnet3_again + +- name: Verify nm_change_subnet2_again for a version that's < 3.1 + assert: + that: + - nm_change_subnet3_again is not changed + - nm_change_subnet3_again.current.ip == "10.1.1.5/24" + - nm_change_subnet3_again.current.noDefaultGateway == false + - nm_change_subnet3_again.current.scope == "public" + - nm_change_subnet3_again.current.shared == true + - nm_change_subnet3_again.current.querier == true + when: version.current.version is version('3.1.1g', '<') + +- name: Verify cm_change_subnet2 for a version that's >= 3.1 + assert: + that: + - nm_change_subnet3_again is not changed + - nm_change_subnet3_again.current.ip == "10.1.1.5/24" + - nm_change_subnet3_again.current.noDefaultGateway == false + - nm_change_subnet3_again.current.scope == "public" + - nm_change_subnet3_again.current.shared == true + - nm_change_subnet3_again.current.querier == true + - nm_change_subnet3_again.current.virtual == false + - nm_change_subnet3_again.current.primary == true + when: version.current.version is version('3.1.1g', '>=') + +# QUERY ALL Subnets +- name: Query all subnet (check_mode) + mso_schema_template_bd_subnet: &subnet_query + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + state: query + check_mode: yes + register: cm_query_all_subnet + +- name: Query all subnet (normal mode) + mso_schema_template_bd_subnet: + <<: *subnet_query + register: nm_query_all_subnet + +- name: Verify query_all_subnet + assert: + that: + - cm_query_all_subnet is not changed + - nm_query_all_subnet is not changed + - cm_query_all_subnet.current | length == nm_query_all_subnet.current | length == 3 + +# QUERY A subnet +- name: Query subnet2 + mso_schema_template_bd_subnet: + <<: *subnet_query + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template2 + bd: ansible_test_2 + subnet: 10.1.1.1/24 + register: nm_query_subnet2 + +- name: Verify nm_query_subnet2 for a version that's < 3.1 + assert: + that: + - nm_query_subnet2 is not changed + - nm_query_subnet2.current.ip == "10.1.1.1/24" + - nm_query_subnet2.current.noDefaultGateway == false + - nm_query_subnet2.current.scope == "public" + - nm_query_subnet2.current.shared == true + - nm_query_subnet2.current.querier == true + when: version.current.version is version('3.1.1g', '<') + +- name: Verify nm_query_subnet2 for a version that's >= 3.1 + assert: + that: + - nm_query_subnet2 is not changed + - nm_query_subnet2.current.ip == "10.1.1.1/24" + - nm_query_subnet2.current.noDefaultGateway == false + - nm_query_subnet2.current.scope == "public" + - nm_query_subnet2.current.shared == true + - nm_query_subnet2.current.querier == true + - nm_query_subnet2.current.virtual == false + when: version.current.version is version('3.1.1g', '>=') + +# REMOVE Subnet +- name: Remove subnet + mso_schema_template_bd_subnet: &subnet_absent + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_1 + subnet: 172.16.0.1/24 + state: absent + register: nm_remove_subnet + +- name: Verify nm_remove_subnet + assert: + that: + - nm_remove_subnet is changed + - nm_remove_subnet.current == {} + +- name: Remove subnet again (check_mode) + mso_schema_template_bd_subnet: + <<: *subnet_absent + register: nm_remove_subnet_again + +- name: Verify nm_remove_subnet_again + assert: + that: + - nm_remove_subnet_again is not changed + - nm_remove_subnet_again.current == {} + +# QUERY NON-EXISTING Subnet +- name: Query non-existing subnet + mso_schema_template_bd_subnet: + <<: *subnet_query + bd: ansible_test_1 + subnet: 172.16.0.3/24 + ignore_errors: yes + register: nm_query_non_subnet + +- name: Verify nm_query_non_subnet + assert: + that: + - nm_query_non_subnet is not changed + - nm_query_non_subnet.msg is match ("Subnet IP '172.16.0.3/24' not found") + +# USE A NON-EXISTING STATE +- name: Non-existing state for subnet + mso_schema_template_bd_subnet: + <<: *subnet_query + state: non-existing-state + ignore_errors: yes + register: nm_non_existing_state + +- name: Verify non_existing_state + assert: + that: + - nm_non_existing_state is not changed + - nm_non_existing_state.msg is match ("value of state must be one of{{':'}} absent, present, query, got{{':'}} non-existing-state") + +# USE A NON-EXISTING SCHEMA +- name: Non-existing schema for subnet + mso_schema_template_bd_subnet: + <<: *subnet_query + schema: non-existing-schema + ignore_errors: yes + register: nm_non_existing_schema + +- name: Verify non_existing_schema + assert: + that: + - nm_non_existing_schema is not changed + - nm_non_existing_schema.msg is match ("Provided schema 'non-existing-schema' does not exist.") + +# USE A NON-EXISTING TEMPLATE +- name: Non-existing template for subnet + mso_schema_template_bd_subnet: + <<: *subnet_query + template: non-existing-template + ignore_errors: yes + register: nm_non_existing_template + +- name: Verify non_existing_template + assert: + that: + - nm_non_existing_template is not changed + - nm_non_existing_template.msg is match ("Provided template 'non-existing-template' does not exist. Existing templates{{':'}} Template1") + +# USE NON-EXISTING OPTIONS +- name: Add subnet with no description + mso_schema_template_bd_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: ansible_test_3 + subnet: 172.16.0.5/24 + state: present + register: nm_add_subnet_no_desc + +- name: Verify nm_add_subnet_no_desc + assert: + that: + - nm_add_subnet_no_desc.current.description == "172.16.0.5/24" + +# USE A NON-EXISTING BD +- name: Non-existing bd for subnet + mso_schema_template_bd_subnet: + <<: *subnet_query + bd: non-existing-bd + ignore_errors: yes + register: nm_non_existing_bd + +- name: Verify non_existing_bd + assert: + that: + - nm_non_existing_bd is not changed + - nm_non_existing_bd.msg is match ("Provided BD 'non-existing-bd' does not exist. Existing BDs{{':'}} ansible_test_1") + +- name: Remove schemas for next ci test + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}'
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_clone/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_clone/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_clone/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_clone/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_clone/tasks/main.yml new file mode 100644 index 00000000..3425b450 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_clone/tasks/main.yml @@ -0,0 +1,293 @@ +# Test code for the MSO modules +# Copyright: (c) 2021, Anvitha Jain (@anvitha-jain) <anvjain@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") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Remove schemas + cisco.mso.mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + ignore_errors: yes + loop: + - Schema1 + - Schema2 + +- name: Ensure tenant ansible_test exists + mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + sites: + - '{{ mso_site | default("ansible_test") }}' + state: present + +- name: Ensure user is defined under common tenant + mso_tenant: + <<: *mso_info + tenant: common + users: + - '{{ mso_username }}' + state: present + when: version.current.version is version('3.2', '<') + +- name: Create Schema1 with Template 1, and Template 2 exist + cisco.mso.mso_schema_template: + <<: *mso_info + schema: Schema1 + tenant: ansible_test + template: '{{ item }}' + state: present + loop: + - Template1 + - Template2 + +- name: Create Schema2 with Template 3 exist + cisco.mso.mso_schema_template: + <<: *mso_info + schema: Schema2 + tenant: ansible_test + template: Template3 + state: present + +- name: Ensure ANP exist + cisco.mso.mso_schema_template_anp: + <<: *mso_info + schema: '{{ item.schema }}' + template: '{{ item.template }}' + anp: ANP + state: present + loop: + - { schema: 'Schema1', template: 'Template1' } + - { schema: 'Schema1', template: 'Template2' } + - { schema: 'Schema2', template: 'Template3' } + +- name: Ensure EPGs exist + cisco.mso.mso_schema_template_anp_epg: + <<: *mso_info + schema: '{{ item.schema }}' + template: '{{ item.template }}' + anp: ANP + epg: '{{ item.epg }}' + state: present + loop: + - { schema: 'Schema1', template: 'Template1', epg: 'ansible_test_1' } + - { schema: 'Schema1', template: 'Template2', epg: 'ansible_test_2' } + - { schema: 'Schema2', template: 'Template3', epg: 'ansible_test_3' } + +- name: Add Selector to EPG (normal_mode) + mso_schema_template_anp_epg_selector: + <<: *mso_info + schema: 'Schema1' + template: Template1 + anp: ANP + epg: ansible_test_1 + selector: selector_1 + state: present + +- name: Clone template in the same schema (check_mode) + cisco.mso.mso_schema_template_clone: + <<: *mso_info + source_schema: Schema1 + destination_schema: Schema1 + destination_tenant: ansible_test + source_template_name: Template1 + destination_template_name: Template1_clone + destination_template_display_name: Template1_clone + state: clone + check_mode: yes + register: cm_add_template + +- name: Clone template in the same schema (normal mode) + cisco.mso.mso_schema_template_clone: + <<: *mso_info + source_schema: Schema1 + destination_schema: Schema1 + destination_tenant: ansible_test + source_template_name: Template1 + destination_template_name: Template1_clone + destination_template_display_name: Template1_clone + state: clone + register: add_template + +- name: Clone template in the same schema without destination_schema being specified + cisco.mso.mso_schema_template_clone: + <<: *mso_info + source_schema: Schema1 + source_template_name: Template1 + destination_template_name: Template1_clone_nodestschema + state: clone + register: add_template_nodestschema + +- name: Clone template to different schema + cisco.mso.mso_schema_template_clone: + <<: *mso_info + source_schema: Schema1 + destination_schema: Schema2 + destination_tenant: ansible_test + source_template_name: Template2 + destination_template_name: Cloned_template_1 + destination_template_display_name: Cloned_template_1 + state: clone + register: add_template_schema + +- name: Clone template to different schema but keep template name + cisco.mso.mso_schema_template_clone: + <<: *mso_info + source_schema: Schema1 + destination_schema: Schema2 + source_template_name: Template2 + state: clone + register: add_template_schema_2 + +- name: Clone template in the same schema but different tenant attached + cisco.mso.mso_schema_template_clone: + <<: *mso_info + source_schema: Schema1 + destination_schema: Schema1 + destination_tenant: common + source_template_name: Template1_clone + destination_template_name: Template1_clone_2 + state: clone + register: add_template_tenant + +- name: Verify add_templates + assert: + that: + - cm_add_template is not changed + - add_template is changed + - (add_template.current.templates | selectattr('displayName', 'contains', 'Template1_clone')|first).name == 'Template1_clone' + - add_template_nodestschema is changed + - (add_template_nodestschema.current.templates | selectattr('displayName', 'contains', 'Template1_clone_nodestschema')|first).name == 'Template1_clone_nodestschema' + - add_template_schema is changed + - (add_template_schema.current.templates | selectattr('displayName', 'contains', 'Cloned_template_1')|first).name == 'Cloned_template_1' + - add_template_schema_2 is changed + - (add_template_schema_2.current.templates | selectattr('displayName', 'contains', 'Template2')|first).name == 'Template2' + - add_template_tenant is changed + - (add_template_tenant.current.templates | selectattr('displayName', 'contains', 'Template1_clone_2')|first).name == 'Template1_clone_2' + +# Checking for other cases +- name: Clone non existing template + cisco.mso.mso_schema_template_clone: + <<: *mso_info + source_schema: Schema2 + destination_schema: Schema2 + destination_tenant: common + source_template_name: non_existing_template + destination_template_name: Cloned_template_2 + destination_template_display_name: Cloned_template_2 + state: clone + ignore_errors: yes + register: non_existing_template + +- name: Verify non_existing_template + assert: + that: + - non_existing_template is not changed + - non_existing_template.msg == "Source template with the name 'non_existing_template' does not exist." + +- name: Clone non existing source schema + cisco.mso.mso_schema_template_clone: + <<: *mso_info + source_schema: non_existing_schema + destination_schema: Schema2 + source_template_name: Template2 + destination_template_name: NewTemplate2 + state: clone + ignore_errors: yes + register: non_existing_source_schema + +- name: Verify non_existing_source_schema + assert: + that: + - non_existing_source_schema is not changed + - non_existing_source_schema.msg == "Schema with the name 'non_existing_schema' does not exist." + +- name: Clone non existing destination schema + cisco.mso.mso_schema_template_clone: + <<: *mso_info + source_schema: Schema1 + destination_schema: non_existing_schema + destination_tenant: common + source_template_name: Template2 + destination_template_name: Template_clone + destination_template_display_name: Template_clone + state: clone + ignore_errors: yes + register: non_existing_schema + +- name: Verify non_existing_schema + assert: + that: + - non_existing_schema is not changed + - non_existing_schema.msg == "Schema with the name 'non_existing_schema' does not exist." + +- name: Clone to same schema with same template name + cisco.mso.mso_schema_template_clone: + <<: *mso_info + source_schema: Schema1 + source_template_name: Template1 + state: clone + ignore_errors: yes + register: wrong_template_name + +- name: Verify wrong_template_name + assert: + that: + - wrong_template_name is not changed + - wrong_template_name.msg == "Source and destination templates in the same schema cannot have same names." + +- name: Clone schema to schema with existing template with same name + cisco.mso.mso_schema_template_clone: + <<: *mso_info + source_schema: Schema1 + destination_schema: Schema2 + source_template_name: Template2 + state: clone + ignore_errors: yes + register: template_already_exist + +- name: Verify template_already_exist + assert: + that: + - template_already_exist is not changed + - template_already_exist.msg == "Template with the name 'Template2' already exists. Please use another name." + +- name: Remove schemas + cisco.mso.mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + register: rm_schema + loop: + - Schema2 + - Schema1 + +- name: Verify rm_schema + assert: + that: + - rm_schema is changed
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_contract_filter/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_contract_filter/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_contract_filter/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_contract_filter/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_contract_filter/tasks/main.yml new file mode 100644 index 00000000..f7867ac3 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_contract_filter/tasks/main.yml @@ -0,0 +1,1088 @@ +# Test code for the MSO modules +# Copyright: (c) 2021, Akini Ross (@akinross) <akinross@cisco.com> +# Copyright: (c) 2021, Anvitha Jain (@anvitha-jain) <anvjain@cisco.com> +# Copyright: (c) 2020, Cindy Zhao (@cizhao) <cizhao@cisco.com> +# Copyright: (c) 2020, Lionel Hercot (@lhercot) <lhercot@cisco.com> +# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> (based on mso_site test case) +# + +# 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(false) }}' + output_level: '{{ mso_output_level | default("info") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Remove schema 2 + mso_schema: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + state: absent + +- name: Remove schema 1 + mso_schema: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + state: absent + +- name: Ensure tenant ansible_test exist + mso_tenant: &tenant_present + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + state: present + +- name: Ensure schema 1 with Template 1 exist + mso_schema_template: &schema_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template 1 + state: present + +- name: Ensure schema 1 with Template 2 exist + mso_schema_template: + <<: *schema_present + template: Template 2 + state: present + +- name: Ensure schema 2 with Template 3 exist + mso_schema_template: + <<: *schema_present + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template 3 + state: present + +- name: Ensure Filter1 exist + cisco.mso.mso_schema_template_filter_entry: &filter_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + filter: Filter1 + #add filter entry + entry: Filter1Entry + state: present + register: add_filter + +- name: Ensure Filter2 exist + mso_schema_template_filter_entry: + <<: *filter_present + template: Template 2 + filter: Filter2 + entry: Filter2Entry + state: present + +- name: Ensure Filter3 exist + mso_schema_template_filter_entry: + <<: *filter_present + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + filter: Filter3 + entry: Filter3Entry + state: present + +- name: Ensure Filter4 exist + mso_schema_template_filter_entry: + <<: *filter_present + filter: Filter4 + entry: Filter4Entry + state: present + +- name: Ensure Filter5 exist + mso_schema_template_filter_entry: + <<: *filter_present + filter: Filter5 + entry: Filter5Entry + state: present + +- name: Ensure Filter-6 exist + mso_schema_template_filter_entry: + <<: *filter_present + filter: Filter-6 + entry: Filter-6Entry + state: present + +- name: Ensure Contract_1 contract does not exist + mso_schema_template_contract_filter: &contract_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract1 + filter: Filter1 + filter_schema: '{{ mso_schema | default("ansible_test") }}' + filter_template: Template 1 + state: absent + +- name: Ensure Contract_2 contract does not exist + mso_schema_template_contract_filter: + <<: *contract_present + template: Template 2 + contract: Contract2 + state: absent + +- name: Ensure Contract_3 contract does not exist + mso_schema_template_contract_filter: + <<: *contract_present + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + contract: Contract3 + state: absent + +- name: Ensure Contract_4 contract does not exist + mso_schema_template_contract_filter: + <<: *contract_present + contract: Contract4 + state: absent + +- name: Ensure Contract_5 contract does not exist + mso_schema_template_contract_filter: + <<: *contract_present + contract: Contract5 + state: absent + +- name: Ensure Contract_6 contract does not exist + mso_schema_template_contract_filter: + <<: *contract_present + contract: Contract-6 + state: absent + +# ADD CONTRACT +- name: Add contract (check_mode) + mso_schema_template_contract_filter: + <<: *contract_present + contract: Contract1 + filter: Filter1 + state: present + check_mode: yes + register: cm_add_contract + +- name: Verify cm_add_contract + assert: + that: + - cm_add_contract is changed + - cm_add_contract.previous == {} + - cm_add_contract.current.filterRef.filterName == "Filter1" + - cm_add_contract.current.filterRef.templateName == "Template1" + +- name: Add contract (normal mode) + mso_schema_template_contract_filter: + <<: *contract_present + contract: Contract1 + filter: Filter1 + state: present + register: nm_add_contract + +- name: Verify nm_add_contract + assert: + that: + - nm_add_contract is changed + - nm_add_contract.previous == {} + - nm_add_contract.current.filterRef.filterName == "Filter1" + - nm_add_contract.current.filterRef.templateName == "Template1" + - cm_add_contract.current.filterRef.schemaId == nm_add_contract.current.filterRef.schemaId + +- name: Add contract again (check_mode) + mso_schema_template_contract_filter: + <<: *contract_present + contract: Contract1 + filter: Filter1 + state: present + check_mode: yes + register: cm_add_contract_again + +- name: Verify cm_add_contract_again + assert: + that: + - cm_add_contract_again is not changed + - cm_add_contract_again.current.filterRef.filterName == "Filter1" + - cm_add_contract_again.current.filterRef.templateName == "Template1" + - cm_add_contract_again.previous.filterRef.filterName == "Filter1" + - cm_add_contract_again.previous.filterRef.templateName == "Template1" + - cm_add_contract_again.previous.filterRef.schemaId == cm_add_contract_again.current.filterRef.schemaId + +- name: Add contract again (normal mode) + mso_schema_template_contract_filter: + <<: *contract_present + contract: Contract1 + filter: Filter1 + state: present + register: nm_add_contract_again + +- name: Verify nm_add_contract_again + assert: + that: + - nm_add_contract_again is not changed + - nm_add_contract_again.current.filterRef.filterName == "Filter1" + - nm_add_contract_again.current.filterRef.templateName == "Template1" + - nm_add_contract_again.current.filterRef.templateName == "Template1" + - nm_add_contract_again.previous.filterRef.filterName == "Filter1" + - nm_add_contract_again.previous.filterRef.templateName == "Template1" + - nm_add_contract_again.previous.filterRef.schemaId == nm_add_contract_again.current.filterRef.schemaId + +- name: Add Contract2 (check_mode) + mso_schema_template_contract_filter: + <<: *contract_present + template: Template 2 + contract: Contract2 + filter: Filter1 + filter_template: Template 1 + state: present + check_mode: yes + register: cm_add_contract_2 + +- name: Verify cm_add_contract_2 + assert: + that: + - cm_add_contract_2 is changed + - cm_add_contract_2.current.filterRef.filterName == "Filter1" + - cm_add_contract_2.current.filterRef.templateName == "Template1" + +- name: Add Contract2 (nomal mode) + mso_schema_template_contract_filter: + <<: *contract_present + template: Template 2 + contract: Contract2 + filter: Filter1 + filter_template: Template 1 + state: present + register: nm_add_contract_2 + +- name: Verify nm_add_contract_2 + assert: + that: + - nm_add_contract_2 is changed + - nm_add_contract_2.current.filterRef.filterName == "Filter1" + - nm_add_contract_2.current.filterRef.templateName == "Template1" + - cm_add_contract_2.current.filterRef.schemaId == nm_add_contract_2.current.filterRef.schemaId + +- name: Add Contract3 (nomal mode) + mso_schema_template_contract_filter: + <<: *contract_present + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + contract: Contract3 + filter: Filter1 + filter_template: Template 1 + filter_schema: '{{ mso_schema | default("ansible_test") }}' + state: present + register: nm_add_contract_3 + +- name: Verify nm_add_contract_3 + assert: + that: + - nm_add_contract_3 is changed + - nm_add_contract_3.current.filterRef.filterName == "Filter1" + - nm_add_contract_3.current.filterRef.templateName == "Template1" + +- name: Add Contract4 (nomal mode) + mso_schema_template_contract_filter: + <<: *contract_present + contract: Contract4 + filter: Filter1 + contract_display_name: displayContract4 + state: present + register: nm_add_contract_4 + +- name: Verify nm_add_contract_4 + assert: + that: + - nm_add_contract_4 is changed + - nm_add_contract_4.current.filterRef.filterName == "Filter1" + - nm_add_contract_4.current.filterRef.templateName == "Template1" + - nm_add_contract_3.current.filterRef.schemaId == nm_add_contract_4.current.filterRef.schemaId == nm_add_contract_2.current.filterRef.schemaId == nm_add_contract.current.filterRef.schemaId + +# create CONTRACT FILTER with diff options +- name: Add Contract filter to both-way(check_mode) + mso_schema_template_contract_filter: + <<: *contract_present + contract: Contract1 + contract_filter_type: both-way + filter: Filter4 + filter_type: both-way + state: present + check_mode: yes + register: cm_add_contract_filter_both_way + +- name: Add Contract filter to both-way(normal_mode) + mso_schema_template_contract_filter: + <<: *contract_present + contract: Contract1 + contract_filter_type: both-way + filter: Filter4 + filter_type: both-way + state: present + register: nm_add_contract_filter_both_way + +- name: Verify cm_change_contract_filter_both_way + assert: + that: + - cm_add_contract_filter_both_way is changed + - nm_add_contract_filter_both_way is changed + - cm_add_contract_filter_both_way.previous == {} + - nm_add_contract_filter_both_way.previous == {} + - cm_add_contract_filter_both_way.current.filterRef.filterName == "Filter4" + - cm_add_contract_filter_both_way.current.filterRef.templateName == "Template1" + - nm_add_contract_filter_both_way.current.filterRef.filterName == "Filter4" + - nm_add_contract_filter_both_way.current.filterRef.templateName == "Template1" + - cm_add_contract_filter_both_way.current.filterRef.schemaId == nm_add_contract_filter_both_way.current.filterRef.schemaId + - cm_add_contract_filter_both_way.current.contractFilterType == "bothWay" + - cm_add_contract_filter_both_way.current.contractScope == "context" + - cm_add_contract_filter_both_way.current.displayName == "Contract1" + - cm_add_contract_filter_both_way.current.filterType == "both-way" + +- name: Change Contract type one_way Filter type consumer-to-provider(normal_mode) + mso_schema_template_contract_filter: + <<: *contract_present + contract: Contract5 + contract_filter_type: one-way + filter: Filter5 + filter_type: consumer-to-provider + state: present + register: nm_one_way_and_consumer_to_provider + +- name: Verify nm_one_way_and_consumer_to_provider + assert: + that: + - nm_one_way_and_consumer_to_provider is changed + - nm_one_way_and_consumer_to_provider.previous == {} + - nm_one_way_and_consumer_to_provider.current.contractFilterType == "oneWay" + - nm_one_way_and_consumer_to_provider.current.contractScope == "context" + - nm_one_way_and_consumer_to_provider.current.displayName == "Contract5" + - nm_one_way_and_consumer_to_provider.current.filterType == "consumer-to-provider" + +- name: Change Contract type one_way Filter type provider-to-consumer(normal_mode) + mso_schema_template_contract_filter: + <<: *contract_present + contract: Contract-6 + contract_filter_type: one-way + filter: Filter-6 + filter_type: provider-to-consumer + state: present + register: nm_one_way_and_provider_to_consumer + +- name: Verify nm create contract filter with different type + assert: + that: + - nm_one_way_and_provider_to_consumer is changed + - nm_one_way_and_provider_to_consumer.current.contractFilterType == "oneWay" + - nm_one_way_and_provider_to_consumer.current.contractScope == "context" + - nm_one_way_and_provider_to_consumer.current.displayName == "Contract-6" + - nm_one_way_and_provider_to_consumer.current.filterType == "provider-to-consumer" + +# change contract display name +- name: change contract display name + mso_schema_template_contract_filter: + <<: *contract_present + contract: Contract4 + filter: Filter1 + contract_display_name: newDisplayContract4 + state: present + register: nm_change_display_name + +- name: Verify nm_change_display_name + assert: + that: + - nm_change_display_name is changed + - nm_change_display_name.current.displayName == "newDisplayContract4" + - nm_change_display_name.previous.displayName == "displayContract4" + +# change contract filter_directives to log +- name: change contract filter_directives to log(check_mode) + mso_schema_template_contract_filter: + <<: *contract_present + contract: Contract4 + filter: Filter1 + filter_directives: log + state: present + check_mode: yes + register: cm_change_filter_directives_log + +- name: change contract filter_directives to log(normal_mode) + mso_schema_template_contract_filter: + <<: *contract_present + contract: Contract4 + filter: Filter1 + filter_directives: log + state: present + register: nm_change_filter_directives_log + +- name: Verify change_contract_filter_directives to log + assert: + that: + - cm_change_filter_directives_log is changed + - nm_change_filter_directives_log is changed + - cm_change_filter_directives_log.previous.directives[0] == "none" + - nm_change_filter_directives_log.previous.directives[0] == "none" + - cm_change_filter_directives_log.current.directives[0] == "log" + - nm_change_filter_directives_log.current.directives[0] == "log" + +- name: change contract filter_directives to log and none(normal_mode) + mso_schema_template_contract_filter: + <<: *contract_present + contract: Contract4 + filter: Filter1 + filter_directives: ['log', 'none'] + state: present + register: nm_change_filter_directives_log_and_none + +- name: Verify nm_change_filter_directives_log_and_none + assert: + that: + - nm_change_filter_directives_log_and_none is changed + - nm_change_filter_directives_log_and_none.previous.directives[0] == "log" + - nm_change_filter_directives_log_and_none.current.directives == ['log', 'none'] + +# change contract filter_directives to policy_compression +- name: change contract filter_directives to policy_compression (check_mode) + mso_schema_template_contract_filter: + <<: *contract_present + contract: Contract4 + filter: Filter1 + filter_directives: policy_compression + state: present + check_mode: yes + register: cm_change_filter_directives_pc + +- name: change contract filter_directives to policy_compression (normal_mode) + mso_schema_template_contract_filter: + <<: *contract_present + contract: Contract4 + filter: Filter1 + filter_directives: policy_compression + state: present + register: nm_change_filter_directives_pc + +- name: Verify change_contract_filter_directives to pc + assert: + that: + - cm_change_filter_directives_pc is changed + - nm_change_filter_directives_pc is changed + - cm_change_filter_directives_pc.previous.directives == ['log', 'none'] + - nm_change_filter_directives_pc.previous.directives == ['log', 'none'] + - cm_change_filter_directives_pc.current.directives[0] == "no_stats" + - nm_change_filter_directives_pc.current.directives[0] == "no_stats" + +- name: change contract filter_directives to log, none, policy compression (normal_mode) + mso_schema_template_contract_filter: + <<: *contract_present + contract: Contract4 + filter: Filter1 + filter_directives: ['log', 'none', 'policy_compression'] + state: present + register: nm_change_filter_directives_log_and_none_pc + +- name: Verify nm_change_filter_directives_log_and_none_pc + assert: + that: + - nm_change_filter_directives_log_and_none_pc is changed + - nm_change_filter_directives_log_and_none_pc.previous.directives[0] == "no_stats" + - nm_change_filter_directives_log_and_none_pc.current.directives == ["log", "none", "no_stats"] + +- name: Change Contract1 scope to global (normal mode) + mso_schema_template_contract_filter: + <<: *contract_present + contract: Contract1 + contract_scope: global + state: present + register: nm_change_contract_scope_global + +- name: Verify nm_change_contract_scope_global + assert: + that: + - nm_change_contract_scope_global is changed + - nm_change_contract_scope_global.current.contractScope == "global" + - nm_change_contract_scope_global.previous.contractScope == "context" + +- name: Change Contract1 scope to tenant(normal mode) + mso_schema_template_contract_filter: + <<: *contract_present + contract: Contract1 + contract_scope: tenant + state: present + register: nm_change_contract_scope_tenant + +- name: Verify nm_change_contract_scope_tenant + assert: + that: + - nm_change_contract_scope_tenant is changed + - nm_change_contract_scope_tenant.previous.contractScope == "global" + - nm_change_contract_scope_tenant.current.contractScope == "tenant" + +- name: Change Contract1 scope application_profile(normal mode) + mso_schema_template_contract_filter: + <<: *contract_present + contract: Contract1 + contract_scope: application-profile + state: present + register: nm_change_contract_scope_application_profile + +- name: Verify nm_change_contract_scope_application_profile + assert: + that: + - nm_change_contract_scope_application_profile is changed + - nm_change_contract_scope_application_profile.previous.contractScope == "tenant" + - nm_change_contract_scope_application_profile.current.contractScope == "application-profile" + +- name: Change Contract1 scope to vrf(normal mode) + mso_schema_template_contract_filter: + <<: *contract_present + contract: Contract1 + contract_scope: vrf + state: present + register: nm_change_contract_scope_vrf + +- name: Verify nm_change_contract_scope_vrf + assert: + that: + - nm_change_contract_scope_vrf is changed + - nm_change_contract_scope_vrf.current.contractScope == "context" + - nm_change_contract_scope_vrf.previous.contractScope == "application-profile" + +- name: Change Contract1 scope to default(normal mode) + mso_schema_template_contract_filter: + <<: *contract_present + contract: Contract1 + state: present + register: nm_change_contract_scope_default + +- name: Verify nm_change_contract_scope_default + assert: + that: + - nm_change_contract_scope_default is not changed + - nm_change_contract_scope_default.current.contractScope == "context" + - nm_change_contract_scope_default.previous.contractScope == "context" + +- name: Change Contract1 description (normal mode) + mso_schema_template_contract_filter: + <<: *contract_present + contract: Contract1 + description: changed description + state: present + register: nm_change_contract_description + when: version.current.version is version('3.3', '>=') + +- name: Verify nm_change_contract_description + assert: + that: + - nm_change_contract_description is changed + - nm_change_contract_description.current.description == "changed description" + - nm_change_contract_description.previous.description == "" + when: version.current.version is version('3.3', '>=') + +- name: Change Contract1 description empty (normal mode) + mso_schema_template_contract_filter: + <<: *contract_present + contract: Contract1 + description: "" + state: present + register: nm_change_contract_description_empty + when: version.current.version is version('3.3', '>=') + +- name: Verify nm_change_contract_description_empty + assert: + that: + - nm_change_contract_description_empty is changed + - nm_change_contract_description_empty.current.description == "" + - nm_change_contract_description_empty.previous.description == "changed description" + when: version.current.version is version('3.3', '>=') + +- name: Change Contract1 qos_level (normal mode) + mso_schema_template_contract_filter: + <<: *contract_present + contract: Contract1 + qos_level: level1 + state: present + register: nm_change_contract_qos + when: version.current.version is version('3.3', '>=') + +- name: Verify nm_change_contract_qos_level + assert: + that: + - nm_change_contract_qos is changed + - nm_change_contract_qos.current.prio == "level1" + when: version.current.version is version('3.3', '>=') + +- name: Change Contract1 qos_level unspecified (normal mode) + mso_schema_template_contract_filter: + <<: *contract_present + contract: Contract1 + qos_level: unspecified + state: present + register: nm_change_contract_qos_unspecified + when: version.current.version is version('3.3', '>=') + +- name: Verify nm_change_contract_qos_level_unspecified + assert: + that: + - nm_change_contract_qos_unspecified is changed + - nm_change_contract_qos_unspecified.current.prio == "unspecified" + - nm_change_contract_qos_unspecified.previous.prio == "level1" + when: version.current.version is version('3.3', '>=') + +- name: Ensure contract filter_type set to both-way (normal mode) + mso_schema_template_contract_filter: + <<: *contract_present + contract: Contract1 + filter: Filter1 + filter_type: both-way + state: present + register: nm_contract_filter_both_way + when: version.current.version is version('3.3', '>=') + +- name: Verify nm_contract_filter_both_way + assert: + that: + - nm_contract_filter_both_way.current.contractFilterType == "bothWay" + - nm_contract_filter_both_way.current.filterType == "both-way" + when: version.current.version is version('3.3', '>=') + +- name: Change contract filter_type set to one-way with consumer-to-provider (normal mode) + # Test to check that filter type cannot be changed from two-way to one-way type + # changed behaviour due to error handling is now handled in code + mso_schema_template_contract_filter: + <<: *contract_present + contract: Contract1 + filter: Filter1 + filter_type: consumer-to-provider + state: present + register: nm_contract_filter_consumer_to_provider + ignore_errors: yes + when: version.current.version is version('3.3', '>=') + +- name: Verify nm_contract_filter_consumer_to_provider + assert: + that: + - nm_contract_filter_consumer_to_provider.msg == "Current filter type 'bothWay' for contract 'Contract1' is not allowed to change to 'oneWay'." + when: version.current.version is version('3.3', '>=') + +# QUERY ALL CONTRACT +- name: Query Contract1 filters (check_mode) + mso_schema_template_contract_filter: &Contract_query + 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") }}' + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract1 + state: query + check_mode: yes + register: cm_contract1_query_result + +- name: Query Contract1 filters (normal_mode) + mso_schema_template_contract_filter: + <<: *Contract_query + register: nm_contract1_query_result + +- name: Verify query_contract_1 + assert: + that: + - cm_contract1_query_result is not changed + - nm_contract1_query_result is not changed + - cm_contract1_query_result.current | length == nm_contract1_query_result.current | length == 2 + +- name: Query Contract2 filters (normal_mode) + mso_schema_template_contract_filter: + <<: *Contract_query + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + contract: Contract2 + state: query + register: nm_contract2_query_result + +- name: Query Contract3 filters (normal_mode) + mso_schema_template_contract_filter: + <<: *Contract_query + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + contract: Contract3 + register: nm_contract3_query_result + +- name: Query Contract4 filters (normal_mode) + mso_schema_template_contract_filter: + <<: *Contract_query + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract4 + register: nm_contract4_query_result + +- name: Query Contract5 filters (normal_mode) + mso_schema_template_contract_filter: + <<: *Contract_query + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract5 + contract_filter_type: one-way + filter_type: consumer-to-provider + register: nm_contract5_query_result + +- name: Query Contract-6 filters (normal_mode) + mso_schema_template_contract_filter: + <<: *Contract_query + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract-6 + contract_filter_type: one-way + filter_type: provider-to-consumer + register: nm_contract6_query_result + +- name: Verify query_contract + assert: + that: + - nm_contract2_query_result is not changed + - nm_contract3_query_result is not changed + - nm_contract4_query_result is not changed + - nm_contract2_query_result.current | length == nm_contract3_query_result.current | length == nm_contract4_query_result.current | length == 1 + - nm_contract5_query_result is not changed + - nm_contract6_query_result is not changed + - nm_contract5_query_result.current | length == 1 + - nm_contract6_query_result.current | length == 1 + +# QUERY A SPECIFIC CONTRACT FILTER +- name: Query Contract1 Filter1 (check_mode) + mso_schema_template_contract_filter: &Contract_filter_query + 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") }}' + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract1 + filter: Filter1 + state: query + check_mode: yes + register: cm_contract1_filter1_query_result + +- name: Query Contract1 Filter4 (normal_mode) + mso_schema_template_contract_filter: + <<: *Contract_filter_query + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract1 + filter: Filter4 + state: query + register: nm_contract1_filter4_query_result + +- name: Query Contract2 Filter1 (normal_mode) + mso_schema_template_contract_filter: + <<: *Contract_filter_query + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + contract: Contract2 + filter_template: Template 1 + filter: Filter1 + state: query + register: nm_contract2_filter1_query_result + +- name: Query Contract3 Filter1 (normal_mode) + mso_schema_template_contract_filter: + <<: *Contract_filter_query + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + contract: Contract3 + filter: Filter1 + filter_template: Template 1 + filter_schema: '{{ mso_schema | default("ansible_test") }}' + state: query + register: nm_contract3_filter1_query_result + +- name: Query Contract4 Filter1 (normal_mode) + mso_schema_template_contract_filter: + <<: *Contract_filter_query + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract4 + filter: Filter1 + state: query + register: nm_contract4_filter1_query_result + +- name: Query Contract5 Filter5 (normal_mode) + mso_schema_template_contract_filter: + <<: *Contract_filter_query + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract5 + filter: Filter5 + contract_filter_type: one-way + filter_type: consumer-to-provider + state: query + register: nm_contract5_filter5_query_result + +- name: Query Contract-6 Filter-6 (normal_mode) + mso_schema_template_contract_filter: + <<: *Contract_filter_query + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract-6 + filter: Filter-6 + contract_filter_type: one-way + filter_type: provider-to-consumer + state: query + register: nm_contract6_filter6_query_result + +- name: Verify contract1_filter1_query_result + assert: + that: + - cm_contract1_filter1_query_result is not changed + - nm_contract1_filter4_query_result is not changed + - nm_contract2_filter1_query_result is not changed + - nm_contract3_filter1_query_result is not changed + - nm_contract4_filter1_query_result is not changed + - nm_contract5_filter5_query_result is not changed + - nm_contract6_filter6_query_result is not changed + +# REMOVE CONTRACT Filter +- name: Remove contract1 filter1 (check_mode) + mso_schema_template_contract_filter: &contract1_filter1_absent + 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") }}' + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract1 + filter: Filter1 + state: absent + check_mode: yes + register: cm_remove_contract1_filter1 + +- name: Verify cm_remove_contract1_filter1 + assert: + that: + - cm_remove_contract1_filter1 is changed + - cm_remove_contract1_filter1.current == {} + - cm_remove_contract1_filter1.previous.filterRef.filterName == "Filter1" + - cm_remove_contract1_filter1.previous.filterRef.templateName == "Template1" + +- name: Remove contract1 filter1 (normal_mode) + mso_schema_template_contract_filter: + <<: *contract1_filter1_absent + register: nm_remove_contract1_filter1 + +- name: Verify nm_remove_contract1_filter1 + assert: + that: + - nm_remove_contract1_filter1 is changed + - nm_remove_contract1_filter1.current == {} + - nm_remove_contract1_filter1.previous.filterRef.filterName == "Filter1" + - nm_remove_contract1_filter1.previous.filterRef.templateName == "Template1" + +- name: Remove contract1 filter1 again (check_mode) + mso_schema_template_contract_filter: + <<: *contract1_filter1_absent + check_mode: yes + register: cm_remove_contract1_filter1_again + +- name: Verify cm_remove_contract1_filter1_again + assert: + that: + - cm_remove_contract1_filter1_again is not changed + - cm_remove_contract1_filter1_again.current == {} + - cm_remove_contract1_filter1_again.previous == {} + +- name: Remove contract1 filter1 again (normal_mode) + mso_schema_template_contract_filter: + <<: *contract1_filter1_absent + register: nm_remove_contract1_filter1_again + +- name: Verify nm_remove_contract1_filter1_again + assert: + that: + - nm_remove_contract1_filter1_again is not changed + - nm_remove_contract1_filter1_again.current == {} + - nm_remove_contract1_filter1_again.previous == {} + +- name: Remove contract1 filter4 (normal_mode) + mso_schema_template_contract_filter: + <<: *contract1_filter1_absent + filter: Filter4 + register: nm_remove_contract1_filter4 + +- name: Verify nm_remove_contract1_filter4 + assert: + that: + - nm_remove_contract1_filter4 is changed + - nm_remove_contract1_filter4.current == {} + - nm_remove_contract1_filter4.previous.filterRef.filterName == "Filter4" + - nm_remove_contract1_filter4.previous.filterRef.templateName == "Template1" + +- name: Remove contract1 filter4 again (normal_mode) + mso_schema_template_contract_filter: + <<: *contract1_filter1_absent + filter: Filter4 + register: nm_remove_contract1_filter4_again + +- name: Verify nm_remove_contract1_filter4_again + assert: + that: + - nm_remove_contract1_filter4_again is not changed + - nm_remove_contract1_filter4_again.previous == nm_remove_contract1_filter4_again.current == {} + +# QUERY NON-EXISTING FILTER +- name: Query non-existing filter (check_mode) + mso_schema_template_contract_filter: + <<: *Contract_query + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract4 + filter: non-existing-filter + check_mode: yes + ignore_errors: yes + register: cm_query_non_filter + +- name: Query non-existing filter (normal_mode) + mso_schema_template_contract_filter: + <<: *Contract_query + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract4 + filter: non-existing-filter + ignore_errors: yes + register: nm_query_non_filter + +- name: Verify query_non_filter + assert: + that: + - cm_query_non_filter is not changed + - nm_query_non_filter is not changed + +- name: Add contract (for version greater than 3.3) + mso_schema_template_contract_filter: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract1 + description: "This is contract description" + filter: Filter1 + qos_level: level1 + action: deny + priority: 'lowest_priority' + state: present + register: add_contract + when: version.current.version is version('3.3', '>=') + +- name: Verify Add contract for version greater than 3.3 + assert: + that: + - add_contract is changed + - add_contract.current.action == "deny" + - add_contract.current.priorityOverride == "level1" + when: version.current.version is version('3.3', '>=') + +# # QUERY NON-EXISTING CONTRACT +- name: Query non-existing contract (check_mode) + mso_schema_template_contract_filter: + <<: *Contract_query + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: non-existing-contract + check_mode: yes + ignore_errors: yes + register: cm_query_non_contract + +- name: Query non-existing contract (normal_mode) + mso_schema_template_contract_filter: + <<: *Contract_query + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: non-existing-contract + ignore_errors: yes + register: nm_query_non_contract + +- name: Verify query_non_contract + assert: + that: + - cm_query_non_contract is not changed + - nm_query_non_contract is not changed + - nm_query_non_contract == cm_query_non_contract + - cm_query_non_contract.msg == nm_query_non_contract.msg == "Provided contract 'non-existing-contract' does not exist. Existing contracts{{':'}} Contract4, Contract5, Contract-6" + when: version.current.version is version('3.3', '<') + +- name: Verify query_non_contract when version greater than 3.3 + assert: + that: + - cm_query_non_contract.msg == nm_query_non_contract.msg == "Provided contract 'non-existing-contract' does not exist. Existing contracts{{':'}} Contract4, Contract5, Contract-6, Contract1" + when: version.current.version is version('3.3', '>=') + +# USE A NON-EXISTING SCHEMA +- name: Non-existing schema for contrct (check_mode) + mso_schema_template_contract_filter: + <<: *Contract_query + template: Template 1 + schema: non-existing-schema + check_mode: yes + ignore_errors: yes + register: cm_query_non_schema + +- name: Non-existing schema for contrct (normal_mode) + mso_schema_template_contract_filter: + <<: *Contract_query + template: Template 1 + schema: non-existing-schema + ignore_errors: yes + register: nm_query_non_schema + + +- name: Verify non_existing_schema + assert: + that: + - cm_query_non_schema is not changed + - nm_query_non_schema is not changed + - cm_query_non_schema == nm_query_non_schema + - cm_query_non_schema.msg == nm_query_non_schema.msg == "Provided schema 'non-existing-schema' does not exist." + +# USE A NON-EXISTING TEMPLATE +- name: Non-existing template for contract (check_mode) + mso_schema_template_contract_filter: + <<: *Contract_query + schema: '{{ mso_schema | default("ansible_test") }}' + template: non-existing-template + check_mode: yes + ignore_errors: yes + register: cm_query_non_template + +- name: Non-existing template for contract (normal_mode) + mso_schema_template_contract_filter: + <<: *Contract_query + schema: '{{ mso_schema | default("ansible_test") }}' + template: non-existing-template + ignore_errors: yes + register: nm_query_non_template + +- name: Verify non_existing_template + assert: + that: + - cm_query_non_template is not changed + - nm_query_non_template is not changed + - cm_query_non_template == nm_query_non_template + - cm_query_non_template.msg == nm_query_non_template.msg == "Provided template 'non-existing-template' does not exist. Existing templates{{':'}} Template1, Template2"
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_contract_service_graph/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_contract_service_graph/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_contract_service_graph/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_contract_service_graph/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_contract_service_graph/tasks/main.yml new file mode 100644 index 00000000..bc655f1c --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_contract_service_graph/tasks/main.yml @@ -0,0 +1,744 @@ +# Test code for the MSO modules +# Copyright: (c) 2022, 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: 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(false) }}' + output_level: '{{ mso_output_level | default("info") }}' + +- name: Remove schema 2 + mso_schema: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + state: absent + +- name: Remove schema 1 + mso_schema: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + state: absent + +- name: Ensure tenant ansible_test exist + mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + state: present + +- name: Ensure schema 1 with Template 1 exist + mso_schema_template: &schema_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template 1 + state: present + +- name: Ensure schema 1 with Template 2 exist + mso_schema_template: + <<: *schema_present + template: Template 2 + state: present + +- name: Ensure schema 2 with Template 1 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template 1 + state: present + +- name: Ensure Filter1 exist + cisco.mso.mso_schema_template_filter_entry: &filter_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + filter: Filter1 + entry: Filter1Entry + state: present + +- name: Ensure Filter2 exist + cisco.mso.mso_schema_template_filter_entry: + <<: *filter_present + filter: Filter2 + entry: Filter2Entry + state: present + +- name: Ensure Filter3 exist + cisco.mso.mso_schema_template_filter_entry: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 1 + filter: Filter3 + entry: Filter3Entry + state: present + +- name: Ensure Contract_1 contract exist + mso_schema_template_contract_filter: &contract_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract1 + filter: Filter1 + state: present + +- name: Ensure Contract_2 contract exist + mso_schema_template_contract_filter: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 1 + contract: Contract2 + filter: Filter3 + state: present + +- name: Ensure SG_1 service graph exist + cisco.mso.mso_schema_template_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + service_graph: SG1 + display_name: sg1 + service_nodes: + - type: firewall + - type: load-balancer + state: present + +- name: Ensure SG_2 service graph exist + cisco.mso.mso_schema_template_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 1 + service_graph: SG2 + display_name: sg2 + service_nodes: + - type: firewall + - type: load-balancer + state: present + +- name: Ensure VRF_1 vrf exist + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF1 + layer3_multicast: true + state: present + +- name: Ensure BD_1 bd exist + mso_schema_template_bd: &bd_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + bd: BD1 + vrf: + name: VRF1 + state: present + +- name: Ensure BD_2 bd exist + mso_schema_template_bd: + <<: *bd_present + bd: BD2 + state: present + +- name: Ensure BD_3 bd exist + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 1 + bd: BD3 + vrf: + name: VRF1 + schema: '{{ mso_schema | default("ansible_test") }}' + state: present + +- name: Ensure AP1 in Template 1 exists + mso_schema_template_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: AP1 + state: present + +- name: Ensure AP1 in Template 1 exists + mso_schema_template_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 1 + anp: AP2 + state: present + +- name: Ensure EPG1 in AP1 in Template 1 exists + mso_schema_template_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: AP1 + epg: EPG1 + bd: + name: BD1 + state: present + +- name: Ensure EPG2 in AP1 in Template 1 exists + mso_schema_template_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 1 + anp: AP2 + epg: EPG2 + bd: + name: BD3 + state: present + +- name: Add Contract1 to EPG1 provider + mso_schema_template_anp_epg_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: AP1 + epg: EPG1 + contract: + name: Contract1 + type: provider + state: present + +- name: Add Contract1 to EPG1 consumer + mso_schema_template_anp_epg_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: AP1 + epg: EPG1 + contract: + name: Contract1 + type: consumer + state: present + +- name: Add Contract2 to EPG2 provider + mso_schema_template_anp_epg_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 1 + anp: AP2 + epg: EPG2 + contract: + name: Contract2 + type: provider + state: present + +- name: Add Contract2 to EPG2 consumer + mso_schema_template_anp_epg_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 1 + anp: AP2 + epg: EPG2 + contract: + name: Contract2 + type: consumer + state: present + +# TESTS + +- name: Add service graph 1 to Contract1 (check_mode) + mso_schema_template_contract_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract1 + service_graph: SG1 + service_nodes: + - consumer: BD1 + provider: BD2 + - consumer: BD1 + provider: BD2 + state: present + check_mode: yes + register: cm_add_sg1_to_c1 + +- name: Add service graph 1 to Contract1 + mso_schema_template_contract_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract1 + service_graph: SG1 + service_nodes: + - consumer: BD1 + provider: BD2 + - consumer: BD1 + provider: BD2 + state: present + register: nm_add_sg1_to_c1 + +- name: Verify service graph 1 is added to Contract1 + assert: + that: + - cm_add_sg1_to_c1 is changed + - cm_add_sg1_to_c1.previous == {} + - cm_add_sg1_to_c1.current.serviceGraphRef.serviceGraphName == "SG1" + - cm_add_sg1_to_c1.current.serviceGraphRef.templateName == "Template1" + - cm_add_sg1_to_c1.current.serviceNodesRelationship.0.consumerConnector.bdRef.bdName == "BD1" + - cm_add_sg1_to_c1.current.serviceNodesRelationship.0.consumerConnector.connectorType == "general" + - cm_add_sg1_to_c1.current.serviceNodesRelationship.0.providerConnector.bdRef.bdName == "BD2" + - cm_add_sg1_to_c1.current.serviceNodesRelationship.0.providerConnector.connectorType == "general" + - cm_add_sg1_to_c1.current.serviceNodesRelationship.0.serviceNodeRef.serviceGraphName == "SG1" + - cm_add_sg1_to_c1.current.serviceNodesRelationship.0.serviceNodeRef.serviceNodeName == "firewall" + - cm_add_sg1_to_c1.current.serviceNodesRelationship.1.serviceNodeRef.serviceNodeName == "load-balancer" + - nm_add_sg1_to_c1 is changed + - nm_add_sg1_to_c1.previous == {} + - nm_add_sg1_to_c1.current.serviceGraphRef.serviceGraphName == "SG1" + - nm_add_sg1_to_c1.current.serviceGraphRef.templateName == "Template1" + - nm_add_sg1_to_c1.current.serviceNodesRelationship.0.consumerConnector.bdRef.bdName == "BD1" + - nm_add_sg1_to_c1.current.serviceNodesRelationship.0.consumerConnector.connectorType == "general" + - nm_add_sg1_to_c1.current.serviceNodesRelationship.0.providerConnector.bdRef.bdName == "BD2" + - nm_add_sg1_to_c1.current.serviceNodesRelationship.0.providerConnector.connectorType == "general" + - nm_add_sg1_to_c1.current.serviceNodesRelationship.0.serviceNodeRef.serviceGraphName == "SG1" + - nm_add_sg1_to_c1.current.serviceNodesRelationship.0.serviceNodeRef.serviceNodeName == "firewall" + - nm_add_sg1_to_c1.current.serviceNodesRelationship.1.serviceNodeRef.serviceNodeName == "load-balancer" + +- name: Add service graph 1 to Contract1 again (check_mode) + mso_schema_template_contract_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract1 + service_graph: SG1 + service_nodes: + - consumer: BD1 + provider: BD2 + - consumer: BD1 + provider: BD2 + state: present + check_mode: yes + register: cm_add_sg1_to_c1_again + +- name: Add service graph 1 to Contract1 again + mso_schema_template_contract_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract1 + service_graph: SG1 + service_nodes: + - consumer: BD1 + provider: BD2 + - consumer: BD1 + provider: BD2 + state: present + register: nm_add_sg1_to_c1_again + +- name: Verify service graph 1 is added to Contract1 again + assert: + that: + - cm_add_sg1_to_c1_again is not changed + - cm_add_sg1_to_c1_again.previous.serviceGraphRef.serviceGraphName == "SG1" + - cm_add_sg1_to_c1_again.previous.serviceGraphRef.templateName == "Template1" + - cm_add_sg1_to_c1_again.previous.serviceNodesRelationship.0.consumerConnector.bdRef.bdName == "BD1" + - cm_add_sg1_to_c1_again.previous.serviceNodesRelationship.0.consumerConnector.connectorType == "general" + - cm_add_sg1_to_c1_again.previous.serviceNodesRelationship.0.providerConnector.bdRef.bdName == "BD2" + - cm_add_sg1_to_c1_again.previous.serviceNodesRelationship.0.providerConnector.connectorType == "general" + - cm_add_sg1_to_c1_again.previous.serviceNodesRelationship.0.serviceNodeRef.serviceGraphName == "SG1" + - cm_add_sg1_to_c1_again.previous.serviceNodesRelationship.0.serviceNodeRef.serviceNodeName == "firewall" + - cm_add_sg1_to_c1_again.previous.serviceNodesRelationship.1.serviceNodeRef.serviceNodeName == "load-balancer" + - nm_add_sg1_to_c1_again is not changed + - nm_add_sg1_to_c1_again.previous.serviceGraphRef.serviceGraphName == "SG1" + - nm_add_sg1_to_c1_again.previous.serviceGraphRef.templateName == "Template1" + - nm_add_sg1_to_c1_again.previous.serviceNodesRelationship.0.consumerConnector.bdRef.bdName == "BD1" + - nm_add_sg1_to_c1_again.previous.serviceNodesRelationship.0.consumerConnector.connectorType == "general" + - nm_add_sg1_to_c1_again.previous.serviceNodesRelationship.0.providerConnector.bdRef.bdName == "BD2" + - nm_add_sg1_to_c1_again.previous.serviceNodesRelationship.0.providerConnector.connectorType == "general" + - nm_add_sg1_to_c1_again.previous.serviceNodesRelationship.0.serviceNodeRef.serviceGraphName == "SG1" + - nm_add_sg1_to_c1_again.previous.serviceNodesRelationship.0.serviceNodeRef.serviceNodeName == "firewall" + - nm_add_sg1_to_c1_again.previous.serviceNodesRelationship.1.serviceNodeRef.serviceNodeName == "load-balancer" + +- name: Change service graph 1 node to Contract1 (check_mode) + mso_schema_template_contract_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract1 + service_graph: SG1 + service_nodes: + - consumer: BD2 + provider: BD1 + - consumer: BD2 + provider: BD1 + state: present + check_mode: yes + register: cm_change_sg1_to_c1 + +- name: Change service graph 1 node to Contract1 + mso_schema_template_contract_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract1 + service_graph: SG1 + service_nodes: + - consumer: BD2 + provider: BD1 + - consumer: BD2 + provider: BD1 + state: present + register: nm_change_sg1_to_c1 + +- name: Verify service graph 1 is added to Contract1 again + assert: + that: + - cm_change_sg1_to_c1 is changed + - cm_change_sg1_to_c1.current.serviceNodesRelationship.0.consumerConnector.bdRef.bdName == "BD2" + - cm_change_sg1_to_c1.current.serviceNodesRelationship.0.consumerConnector.connectorType == "general" + - cm_change_sg1_to_c1.current.serviceNodesRelationship.0.providerConnector.bdRef.bdName == "BD1" + - cm_change_sg1_to_c1.current.serviceNodesRelationship.0.providerConnector.connectorType == "general" + - cm_change_sg1_to_c1.previous.serviceNodesRelationship.0.consumerConnector.bdRef.bdName == "BD1" + - cm_change_sg1_to_c1.previous.serviceNodesRelationship.0.consumerConnector.connectorType == "general" + - cm_change_sg1_to_c1.previous.serviceNodesRelationship.0.providerConnector.bdRef.bdName == "BD2" + - cm_change_sg1_to_c1.previous.serviceNodesRelationship.0.providerConnector.connectorType == "general" + - cm_change_sg1_to_c1 is changed + - nm_change_sg1_to_c1.current.serviceNodesRelationship.0.consumerConnector.bdRef.bdName == "BD2" + - nm_change_sg1_to_c1.current.serviceNodesRelationship.0.consumerConnector.connectorType == "general" + - nm_change_sg1_to_c1.current.serviceNodesRelationship.0.providerConnector.bdRef.bdName == "BD1" + - nm_change_sg1_to_c1.current.serviceNodesRelationship.0.providerConnector.connectorType == "general" + - nm_change_sg1_to_c1.previous.serviceNodesRelationship.0.consumerConnector.bdRef.bdName == "BD1" + - nm_change_sg1_to_c1.previous.serviceNodesRelationship.0.consumerConnector.connectorType == "general" + - nm_change_sg1_to_c1.previous.serviceNodesRelationship.0.providerConnector.bdRef.bdName == "BD2" + - nm_change_sg1_to_c1.previous.serviceNodesRelationship.0.providerConnector.connectorType == "general" + +- name: Query service graph 1 to Contract1 (check_mode) + mso_schema_template_contract_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract1 + service_graph: SG1 + state: query + register: cm_query_sg1_to_c1 + +- name: Query service graph 1 to Contract1 + mso_schema_template_contract_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract1 + service_graph: SG1 + state: query + register: nm_query_sg1_to_c1 + +- name: Verify queried service graph 1 + assert: + that: + - cm_query_sg1_to_c1 is not changed + - cm_query_sg1_to_c1.current.serviceNodesRelationship.0.consumerConnector.bdRef.bdName == "BD2" + - cm_query_sg1_to_c1.current.serviceNodesRelationship.0.consumerConnector.bdRef.templateName == "Template1" + - cm_query_sg1_to_c1.current.serviceNodesRelationship.0.consumerConnector.connectorType == "general" + - cm_query_sg1_to_c1.current.serviceNodesRelationship.0.providerConnector.bdRef.bdName == "BD1" + - cm_query_sg1_to_c1.current.serviceNodesRelationship.0.consumerConnector.bdRef.templateName == "Template1" + - cm_query_sg1_to_c1.current.serviceNodesRelationship.0.providerConnector.connectorType == "general" + - cm_query_sg1_to_c1 is not changed + - nm_query_sg1_to_c1.current.serviceNodesRelationship.0.consumerConnector.bdRef.bdName == "BD2" + - cm_query_sg1_to_c1.current.serviceNodesRelationship.0.consumerConnector.bdRef.templateName == "Template1" + - nm_query_sg1_to_c1.current.serviceNodesRelationship.0.consumerConnector.connectorType == "general" + - nm_query_sg1_to_c1.current.serviceNodesRelationship.0.providerConnector.bdRef.bdName == "BD1" + - cm_query_sg1_to_c1.current.serviceNodesRelationship.0.consumerConnector.bdRef.templateName == "Template1" + - nm_query_sg1_to_c1.current.serviceNodesRelationship.0.providerConnector.connectorType == "general" + +- name: Remove service graph 1 from Contract1 (check_mode) + mso_schema_template_contract_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract1 + service_graph: SG1 + state: absent + check_mode: yes + register: cm_remove_sg1_from_c1 + +- name: Remove service graph 1 from Contract1 + mso_schema_template_contract_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract1 + service_graph: SG1 + state: absent + register: nm_remove_sg1_from_c1 + +- name: Verify service graph 1 is removed from Contract1 + assert: + that: + - cm_remove_sg1_from_c1 is changed + - cm_remove_sg1_from_c1.current == {} + - cm_remove_sg1_from_c1.previous.serviceGraphRef.serviceGraphName == "SG1" + - cm_remove_sg1_from_c1.previous.serviceGraphRef.templateName == "Template1" + - cm_remove_sg1_from_c1.previous.serviceNodesRelationship.0.consumerConnector.bdRef.bdName == "BD2" + - cm_remove_sg1_from_c1.previous.serviceNodesRelationship.0.consumerConnector.connectorType == "general" + - cm_remove_sg1_from_c1.previous.serviceNodesRelationship.0.providerConnector.bdRef.bdName == "BD1" + - cm_remove_sg1_from_c1.previous.serviceNodesRelationship.0.providerConnector.connectorType == "general" + - cm_remove_sg1_from_c1.previous.serviceNodesRelationship.0.serviceNodeRef.serviceGraphName == "SG1" + - cm_remove_sg1_from_c1.previous.serviceNodesRelationship.0.serviceNodeRef.serviceNodeName == "firewall" + - cm_remove_sg1_from_c1.previous.serviceNodesRelationship.1.serviceNodeRef.serviceNodeName == "load-balancer" + - nm_remove_sg1_from_c1 is changed + - nm_remove_sg1_from_c1.current == {} + - nm_remove_sg1_from_c1.previous.serviceGraphRef.serviceGraphName == "SG1" + - nm_remove_sg1_from_c1.previous.serviceGraphRef.templateName == "Template1" + - nm_remove_sg1_from_c1.previous.serviceNodesRelationship.0.consumerConnector.bdRef.bdName == "BD2" + - nm_remove_sg1_from_c1.previous.serviceNodesRelationship.0.consumerConnector.connectorType == "general" + - nm_remove_sg1_from_c1.previous.serviceNodesRelationship.0.providerConnector.bdRef.bdName == "BD1" + - nm_remove_sg1_from_c1.previous.serviceNodesRelationship.0.providerConnector.connectorType == "general" + - nm_remove_sg1_from_c1.previous.serviceNodesRelationship.0.serviceNodeRef.serviceGraphName == "SG1" + - nm_remove_sg1_from_c1.previous.serviceNodesRelationship.0.serviceNodeRef.serviceNodeName == "firewall" + - nm_remove_sg1_from_c1.previous.serviceNodesRelationship.1.serviceNodeRef.serviceNodeName == "load-balancer" + +- name: Add service graph 2 to Contract2 with BD in other schema (check_mode) + mso_schema_template_contract_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 1 + contract: Contract2 + service_graph: SG2 + service_nodes: + - consumer: BD1 + consumer_template: Template 1 + consumer_schema: '{{ mso_schema | default("ansible_test") }}' + provider: BD3 + - consumer: BD3 + provider: BD2 + provider_template: Template 1 + provider_schema: '{{ mso_schema | default("ansible_test") }}' + state: present + check_mode: yes + register: cm_add_sg2_to_c2 + +- name: Add service graph 2 to Contract2 with BD in other schema + mso_schema_template_contract_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 1 + contract: Contract2 + service_graph: SG2 + service_nodes: + - consumer: BD1 + consumer_template: Template 1 + consumer_schema: '{{ mso_schema | default("ansible_test") }}' + provider: BD3 + - consumer: BD3 + provider: BD2 + provider_template: Template 1 + provider_schema: '{{ mso_schema | default("ansible_test") }}' + state: present + register: nm_add_sg2_to_c2 + +- name: Verify service graph 2 is added to Contract2 + assert: + that: + - cm_add_sg2_to_c2 is changed + - cm_add_sg2_to_c2.previous == {} + - cm_add_sg2_to_c2.current.serviceGraphRef.serviceGraphName == "SG2" + - cm_add_sg2_to_c2.current.serviceGraphRef.templateName == "Template1" + - cm_add_sg2_to_c2.current.serviceNodesRelationship.0.consumerConnector.bdRef.bdName == "BD1" + - cm_add_sg2_to_c2.current.serviceNodesRelationship.0.consumerConnector.connectorType == "general" + - cm_add_sg2_to_c2.current.serviceNodesRelationship.0.providerConnector.bdRef.bdName == "BD3" + - cm_add_sg2_to_c2.current.serviceNodesRelationship.0.providerConnector.connectorType == "general" + - cm_add_sg2_to_c2.current.serviceNodesRelationship.0.serviceNodeRef.serviceGraphName == "SG2" + - cm_add_sg2_to_c2.current.serviceNodesRelationship.0.serviceNodeRef.serviceNodeName == "firewall" + - cm_add_sg2_to_c2.current.serviceNodesRelationship.1.serviceNodeRef.serviceNodeName == "load-balancer" + - nm_add_sg2_to_c2 is changed + - nm_add_sg2_to_c2.previous == {} + - nm_add_sg2_to_c2.current.serviceGraphRef.serviceGraphName == "SG2" + - nm_add_sg2_to_c2.current.serviceGraphRef.templateName == "Template1" + - nm_add_sg2_to_c2.current.serviceNodesRelationship.0.consumerConnector.bdRef.bdName == "BD1" + - nm_add_sg2_to_c2.current.serviceNodesRelationship.0.consumerConnector.connectorType == "general" + - nm_add_sg2_to_c2.current.serviceNodesRelationship.0.providerConnector.bdRef.bdName == "BD3" + - nm_add_sg2_to_c2.current.serviceNodesRelationship.0.providerConnector.connectorType == "general" + - nm_add_sg2_to_c2.current.serviceNodesRelationship.0.serviceNodeRef.serviceGraphName == "SG2" + - nm_add_sg2_to_c2.current.serviceNodesRelationship.0.serviceNodeRef.serviceNodeName == "firewall" + - nm_add_sg2_to_c2.current.serviceNodesRelationship.1.serviceNodeRef.serviceNodeName == "load-balancer" + +- name: Query service graph 2 to Contract2 (check_mode) + mso_schema_template_contract_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 1 + contract: Contract2 + service_graph: SG2 + state: query + register: cm_query_sg2_to_c2 + +- name: Query service graph 2 to Contract2 + mso_schema_template_contract_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 1 + contract: Contract2 + service_graph: SG2 + state: query + register: nm_query_sg2_to_c2 + +- name: Verify queried service graph 1 + assert: + that: + - cm_query_sg2_to_c2 is not changed + - cm_query_sg2_to_c2.current.serviceNodesRelationship.0.consumerConnector.bdRef.bdName == "BD1" + - cm_query_sg2_to_c2.current.serviceNodesRelationship.0.consumerConnector.bdRef.templateName == "Template1" + - cm_query_sg2_to_c2.current.serviceNodesRelationship.0.consumerConnector.connectorType == "general" + - cm_query_sg2_to_c2.current.serviceNodesRelationship.0.providerConnector.bdRef.bdName == "BD3" + - cm_query_sg2_to_c2.current.serviceNodesRelationship.0.consumerConnector.bdRef.templateName == "Template1" + - cm_query_sg2_to_c2.current.serviceNodesRelationship.0.providerConnector.connectorType == "general" + - cm_query_sg2_to_c2.current.serviceNodesRelationship.0.consumerConnector.bdRef.schemaId != cm_query_sg2_to_c2.current.serviceGraphRef.schemaId + - cm_query_sg2_to_c2 is not changed + - nm_query_sg2_to_c2.current.serviceNodesRelationship.0.consumerConnector.bdRef.bdName == "BD1" + - cm_query_sg2_to_c2.current.serviceNodesRelationship.0.consumerConnector.bdRef.templateName == "Template1" + - nm_query_sg2_to_c2.current.serviceNodesRelationship.0.consumerConnector.connectorType == "general" + - nm_query_sg2_to_c2.current.serviceNodesRelationship.0.providerConnector.bdRef.bdName == "BD3" + - cm_query_sg2_to_c2.current.serviceNodesRelationship.0.consumerConnector.bdRef.templateName == "Template1" + - nm_query_sg2_to_c2.current.serviceNodesRelationship.0.providerConnector.connectorType == "general" + - nm_query_sg2_to_c2.current.serviceNodesRelationship.0.consumerConnector.bdRef.schemaId != nm_query_sg2_to_c2.current.serviceGraphRef.schemaId + +# NOT EXISTING INPUT + +- name: Not existing template provided for absent + mso_schema_template_contract_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template False + contract: Contract1 + service_graph: SG1 + state: absent + ignore_errors: yes + register: not_existing_template_input_absent + +- name: Not existing contract provided for absent + mso_schema_template_contract_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract False + service_graph: SG1 + state: absent + ignore_errors: yes + register: not_existing_contract_input_absent + +- name: Not existing service graph provided for absent + mso_schema_template_contract_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract1 + service_graph: SG False + state: absent + register: not_existing_service_graph_input_absent + +- name: Not existing service graph provided for query + mso_schema_template_contract_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract1 + service_graph: SG False + state: query + register: not_existing_service_graph_input_query + +- name: Not existing template provided for present + mso_schema_template_contract_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract1 + service_graph: SG1 + service_graph_template: Template False + service_nodes: + - consumer: BD2 + provider: BD1 + - consumer: BD2 + provider: BD1 + state: present + ignore_errors: yes + register: not_existing_template_input_present + +- name: Not existing service graph provided for present + mso_schema_template_contract_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract1 + service_graph: SG False + service_graph_template: Template 2 + service_nodes: + - consumer: BD2 + provider: BD1 + - consumer: BD2 + provider: BD1 + state: present + ignore_errors: yes + register: not_existing_service_graph_input_present + +- name: Verify non_existing_input + assert: + that: + - not_existing_template_input_absent is not changed + - not_existing_template_input_absent.msg.startswith("Provided template") + - not_existing_contract_input_absent is not changed + - not_existing_contract_input_absent.msg.startswith("Provided contract") + - not_existing_service_graph_input_absent is not changed + - not_existing_service_graph_input_query is not changed + - not_existing_template_input_present is not changed + - not_existing_template_input_present.msg.startswith("Provided template") + - not_existing_service_graph_input_present is not changed + - not_existing_service_graph_input_present.msg.startswith("Provided service graph") + +# False input + +- name: False service graph node amount provided ( less than 2 as provided in SG1 config ) + mso_schema_template_contract_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract1 + service_graph: SG1 + service_nodes: + - consumer: BD1 + provider: BD2 + state: present + ignore_errors: yes + register: nm_false_sg1_to_c1_less_than_2 + +- name: False service graph node amount provided ( more than 2 as provided in SG1 config ) + mso_schema_template_contract_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract1 + service_graph: SG1 + service_nodes: + - consumer: BD1 + provider: BD2 + - consumer: BD1 + provider: BD2 + - consumer: BD1 + provider: BD2 + state: present + ignore_errors: yes + register: nm_false_sg1_to_c1_more_than_2 + +- name: Verify false_sg1_to_c1 + assert: + that: + - nm_false_sg1_to_c1_less_than_2 is not changed + - nm_false_sg1_to_c1_less_than_2.msg.startswith("Not enough service nodes defined") + - nm_false_sg1_to_c1_more_than_2 is not changed + - nm_false_sg1_to_c1_more_than_2.msg.startswith("Too many service nodes defined") diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_deploy/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_deploy/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_deploy/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_deploy/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_deploy/tasks/main.yml new file mode 100644 index 00000000..4d480bdb --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_deploy/tasks/main.yml @@ -0,0 +1,237 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Cindy Zhao (@cizhao) <cizhao@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 + ansible.builtin.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") }}' + +- name: Query MSO version + cisco.mso.mso_version: + <<: *mso_info + state: query + register: version + +# mso_schema_template_deploy is deprecated in MSO/NDO v4.0+, different api endpoint thus different module +- name: Execute tasks only for MSO version < 4.0 + when: version.current.version is version('4.0', '<') + block: + - name: Ensure site exist + cisco.mso.mso_site: + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + apic_username: '{{ apic_username }}' + apic_password: '{{ apic_password }}' + apic_site_id: '{{ apic_site_id | default(101) }}' + urls: + - https://{{ apic_hostname }} + state: present + + - name: Undeploy template + cisco.mso.mso_schema_template_deploy: + <<: *mso_info + schema: ansible_test + template: "{{ item }}" + site: '{{ mso_site | default("ansible_test") }}' + state: undeploy + ignore_errors: yes + loop: + - Template 1 + - Template 2 + - Template 3 + - Template 4 + - Template_5 + - Template 5 + - Template5 + + - name: Remove schemas + cisco.mso.mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + + - name: Ensure tenant ansible_test exists + cisco.mso.mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + sites: + - '{{ mso_site | default("ansible_test") }}' + state: present + + - name: Ensure schema 1 with Template 1, and Template 2, Template 3 exist + cisco.mso.mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: '{{ item }}' + state: present + loop: + - Template 1 + - Template 2 + - Template 3 + - Template 4 + - Template_5 + + - name: Add physical site to a schema + cisco.mso.mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: '{{ item }}' + state: present + loop: + - Template 1 + - Template 2 + - Template 3 + - Template 4 + - Template_5 + + - name: Deploy templates (check_mode) + cisco.mso.mso_schema_template_deploy: &schema_deploy + <<: *mso_info + schema: ansible_test + template: "{{ item }}" + site: '{{ mso_site | default("ansible_test") }}' + state: deploy + check_mode: yes + register: cm_deploy_template + loop: + - Template 1 + - Template 2 + - Template 3 + - Template 4 + - Template_5 + + - name: Verify cm_deploy_template + ansible.builtin.assert: + that: + - item is not changed + loop: "{{ cm_deploy_template.results }}" + + - name: Deploy templates (normal_mode) + cisco.mso.mso_schema_template_deploy: + <<: *schema_deploy + schema: ansible_test + template: "{{ item }}" + site: '{{ mso_site | default("ansible_test") }}' + state: deploy + register: nm_deploy_template + loop: + - Template 1 + - Template 2 + - Template 3 + - Template 4 + - Template_5 + + - name: Verify nm_deploy_template + ansible.builtin.assert: + that: + - item is not changed + - item.msg == "Successfully deployed" + loop: "{{ nm_deploy_template.results }}" + + - name: Get deployment status + cisco.mso.mso_schema_template_deploy: + <<: *schema_deploy + schema: ansible_test + template: "{{ item }}" + state: status + register: query_deploy_status + loop: + - Template 1 + - Template 2 + - Template 3 + - Template 4 + - Template_5 + + - name: Verify query_deploy_status + ansible.builtin.assert: + that: + - item is not changed + - item.status.0.status.siteStatus == "Succeeded" + loop: "{{ query_deploy_status.results }}" + + - name: Undeploy templates + cisco.mso.mso_schema_template_deploy: + <<: *schema_deploy + schema: ansible_test + template: '{{ item }}' + site: '{{ mso_site | default("ansible_test") }}' + state: undeploy + register: undeploy_template + loop: + - Template 1 + - Template 2 + - Template 3 + - Template 4 + - Template_5 + + - name: Verify undeploy_template + ansible.builtin.assert: + that: + - item is not changed + - item.msg == "Successfully Un-deployed" + loop: "{{ undeploy_template.results }}" + when: version.current.version is version('3.1', '>=') + + - name: Verify undeploy_template + ansible.builtin.assert: + that: + - item is not changed + - item.msg == "Successfully deployed" + loop: "{{ undeploy_template.results }}" + when: version.current.version is version('3.1', '<') + + # Validate schema when MSO version >= 3.3 + - name: Execute tasks only for MSO version >= 3.3 + when: version.current.version is version('3.3', '>=') + block: + - name: Add VRF1 with validation error + cisco.mso.mso_schema_template_vrf: &fail_validation + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + vrf: VRF1 + layer3_multicast: true + vzany: true + state: present + + - name: Deploy template with validation error + cisco.mso.mso_schema_template_deploy: + <<: *mso_info + schema: ansible_test + template: Template 2 + site: '{{ mso_site | default("ansible_test") }}' + state: deploy + register: failed_validaton_deploy + ignore_errors: yes + + - name: Verify validation errors before deploy and redploy + ansible.builtin.assert: + that: + - failed_validaton_deploy.msg == "MSO Error 400{{':'}} Bad Request{{':'}} Patch Failed, Received{{':'}} vzAny contract must be configured if vzAny flag is set. VRF(s) {{':'}} VRF1 exception while trying to update schema" + + - name: Remove VRF1 with validation error + cisco.mso.mso_schema_template_vrf: + <<: *fail_validation + state: absent
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_deploy_status/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_deploy_status/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_deploy_status/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_deploy_status/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_deploy_status/tasks/main.yml new file mode 100644 index 00000000..abec0edc --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_deploy_status/tasks/main.yml @@ -0,0 +1,627 @@ +# Test code for the MSO modules +# Copyright: (c) 2021, Shreyas Srish (@shrsr) <ssrish@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") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Ensure site exist + mso_site: &site_present + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + apic_username: '{{ apic_username }}' + apic_password: '{{ apic_password }}' + apic_site_id: '{{ apic_site_id | default(101) }}' + urls: + - https://{{ apic_hostname }} + state: present + +- name: Ensure aws site exists + mso_site: + <<: *mso_info + site: 'aws_{{ mso_site | default("ansible_test") }}' + apic_username: '{{ aws_apic_username }}' + apic_password: '{{ aws_apic_password }}' + apic_site_id: '{{ aws_site_id | default(102) }}' + urls: + - https://{{ aws_apic_hostname }} + state: present + +- name: Undeploy templates if deployed to clean the environment before ndo 4.0 + mso_schema_template_deploy: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: "{{ item }}" + site: '{{ mso_site | default("ansible_test") }}' + state: undeploy + ignore_errors: yes + loop: + - Template 1 + - Template 2 + when: version.current.version is version('4.0', '<') + +#- name: Undeploy templates if deployed to clean the environment after ndo 4.0 +# <TBD>: +# <<: *mso_info +# schema: '{{ mso_schema | default("ansible_test") }}' +# template: "{{ item }}" +# site: '{{ mso_site | default("ansible_test") }}' +# state: undeploy +# ignore_errors: yes +# loop: +# - Template 1 +# - Template 2 +# when: version.current.version is version('4.0', '>=') + +- name: Remove schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Ensure tenant ansible_test exists + mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + sites: + - '{{ mso_site | default("ansible_test") }}' + state: present + +- name: Ensure schema 1 with Template 1, Template 2 + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: '{{ item }}' + state: present + loop: + - Template 1 + - Template 2 + +- name: Add a new site to a schema with Template 1, Template 2 + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: '{{ item }}' + state: present + loop: + - Template 1 + - Template 2 + +- name: Ensure VRF1 exists on Template1 + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF1 + state: present + +- name: Ensure VRF2 exists on Template2 + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + vrf: VRF2 + state: present + +- name: Ensure ANP exists + mso_schema_template_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + state: present + +- name: Ensure ANP2 exists + mso_schema_template_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + anp: ANP2 + state: present + +- name: Check deployment status of Template 1 + mso_schema_template_deploy_status: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + state: query + register: status1_temp1 + +- name: Check deployment status of Template 2 + mso_schema_template_deploy_status: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + state: query + register: status1_temp2 + +- name: Verify status after adding VRFs and ANPs + assert: + that: + - status1_temp1.current[0].anps[0].state == 'created' + - status1_temp1.current[0].vrfs[0].state == 'created' + - status1_temp2.current[0].anps[0].state == 'created' + - status1_temp2.current[0].vrfs[0].state == 'created' + +- name: Check deployment status by querying site + mso_schema_template_deploy_status: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + state: query + register: status_site + +- name: Check deployment status by querying site and Template1 + mso_schema_template_deploy_status: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + site: '{{ mso_site | default("ansible_test") }}' + state: query + register: status_site_temp1 + +- name: Check deployment status by querying site and Template2 + mso_schema_template_deploy_status: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template2 + site: '{{ mso_site | default("ansible_test") }}' + state: query + register: status_site_temp2 + +- name: Verify status after querying site before deployment + assert: + that: + - status_site.current | length == 2 + - status_site_temp1.current.anps[0].state == 'created' + - status_site_temp1.current.vrfs[0].state == 'created' + - status_site_temp2.current.anps[0].state == 'created' + - status_site_temp2.current.vrfs[0].state == 'created' + + +- name: Ensure ansible_test_1 BD exists + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + bd: ansible_test_1 + vrf: + name: VRF1 + template: Template 1 + state: present + +- name: Ensure ansible_test_2 BD exists + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + bd: ansible_test_2 + vrf: + name: VRF2 + template: Template 2 + state: present + +- name: Add EPG to Template 1 + mso_schema_template_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + bd: + name: ansible_test_1 + vrf: + name: VRF1 + state: present + +- name: Add EPG to Template 2 + mso_schema_template_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + anp: ANP2 + epg: ansible_test_2 + bd: + name: ansible_test_2 + vrf: + name: VRF2 + state: present + +- name: Check deployment status of Template 1 + mso_schema_template_deploy_status: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + state: query + register: status2_temp1 + +- name: Check deployment status of Template 2 + mso_schema_template_deploy_status: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + state: query + register: status2_temp2 + +- name: Verify status after adding BDs and EPGs + assert: + that: + - status2_temp1.current[0].bds[0].state == 'created' + - status2_temp1.current[0].anps[0].epgs[0].state == 'created' + - status2_temp2.current[0].bds[0].state == 'created' + - status2_temp2.current[0].anps[0].epgs[0].state == 'created' + +- name: Add VRF3 exists to Template1 + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF3 + state: present + +- name: Add ansible_test_3 BD + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + bd: ansible_test_3 + vrf: + name: VRF3 + template: Template 1 + state: present + +- name: Check deployment status of Template 1 + mso_schema_template_deploy_status: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + state: query + register: status3_temp1 + +- name: Verify status after adding new BD and VRF and changing EPG1 + assert: + that: + - status3_temp1.current[0].bds[0].state == 'created' + - status3_temp1.current[0].vrfs[0].state == 'created' + +# mso_schema_template_deploy is deprecated in MSO/NDO v4.0+, different api endpoint thus different module +# when new module created, remove block and do execution for each mso_schema_template_deploy tasks +- name: Execute tasks only for MSO version < 4.0 + when: version.current.version is version('4.0', '<') + block: + - name: Deploy templates + mso_schema_template_deploy: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: "{{ item }}" + site: '{{ mso_site | default("ansible_test") }}' + state: deploy + register: cm_deploy_template + loop: + - Template 1 + - Template 2 + + - name: Change EPG + mso_schema_template_anp_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + epg: ansible_test_1 + bd: + name: ansible_test_3 + vrf: + name: VRF3 + state: present + + - name: Check deployment status of Template 1 + mso_schema_template_deploy_status: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + state: query + register: status_change_temp1 + + - name: Verify status after changing EPG + assert: + that: + - status_change_temp1.current[0].anps[0].epgs[0].state == 'modified' + + - name: Delete ansible_test_1 BD + mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + bd: ansible_test_1 + vrf: + name: VRF1 + template: Template 1 + state: absent + + - name: Delete VRF1 + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF1 + state: absent + + - name: Check deployment status of Template 1 + mso_schema_template_deploy_status: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + state: query + register: status4_temp1 + + - name: Verify status after deleting VRF1 + assert: + that: + - status4_temp1.current[0].bds[0].state == 'deleted' + - status4_temp1.current[0].vrfs[0].state == 'deleted' + + - name: Try deploy and check results + block: + - name: Deploy templates Template 1 + mso_schema_template_deploy: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + site: '{{ mso_site | default("ansible_test") }}' + state: deploy + + - name: Check deployment status of Template 1 + mso_schema_template_deploy_status: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + state: query + register: status5_temp1 + + - name: Increment the retry count + set_fact: + retry_count: "{{ 0 if retry_count is undefined else retry_count | int + 1 }}" + + rescue: + - fail: + msg: Status5_temp1 correct value retrieved continuing + when: + - status5_temp1.current[0] is defined + - status5_temp1.current[0].anps == [] + + - fail: + msg: Maximum retries of deploy and check group for status5_temp1 reached + when: retry_count | int == 10 + + - debug: + msg: "Deploy and check group for status5_temp1 failed, let's give it another shot" + + - name: Reset the retry count + set_fact: + retry_count: + + - name: Try deploy and check results + block: + - name: Deploy templates Template 2 + mso_schema_template_deploy: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + site: '{{ mso_site | default("ansible_test") }}' + state: deploy + + - name: Check deployment status of Template 2 + mso_schema_template_deploy_status: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + state: query + register: status5_temp2 + + - name: Increment the retry count + set_fact: + retry_count: "{{ 0 if retry_count is undefined else retry_count | int + 1 }}" + + rescue: + - fail: + msg: status5_temp2 correct value retrieved continuing + when: + - status5_temp2.current[0] is defined + - status5_temp2.current[0].anps == [] + + - fail: + msg: Maximum retries of deploy and check group for status5_temp2 reached + when: retry_count | int == 10 + + - debug: + msg: "Deploy and check group for status5_temp2 failed, let's give it another shot" + + - name: Verify status after deploying Templates to site + assert: + that: + - status5_temp1.current[0].anps == [] + - status5_temp1.current[0].bds == [] + - status5_temp1.current[0].vrfs == [] + - status5_temp2.current[0].anps == [] + - status5_temp2.current[0].bds == [] + - status5_temp2.current[0].vrfs == [] + + - name: Check status of all templates + mso_schema_template_deploy_status: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + state: query + register: all_templates + + - name: Verify all + assert: + that: + - all_templates.current.policyStates | length == 2 + + - name: Check deployment status by querying site + mso_schema_template_deploy_status: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + state: query + register: status2_site + + - name: Reset the retry count + set_fact: + retry_count: + + - name: Try deploy and check results for a site and Template1 + block: + - name: Deploy templates Template1 + mso_schema_template_deploy: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + site: '{{ mso_site | default("ansible_test") }}' + state: deploy + + - name: Check deployment status by querying site and Template1 + mso_schema_template_deploy_status: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + site: '{{ mso_site | default("ansible_test") }}' + state: query + register: status2_site_temp1 + + - name: Increment the retry count + set_fact: + retry_count: "{{ 0 if retry_count is undefined else retry_count | int + 1 }}" + + rescue: + - fail: + msg: status2_site_temp1 correct value retrieved continuing + when: + - status2_site_temp1.current is defined + - status2_site_temp1.current.anps == [] + + - fail: + msg: Maximum retries of deploy and check group for status2_site_temp1 reached + when: retry_count | int == 10 + + - debug: + msg: "Deploy and check group for status2_site_temp1 failed, let's give it another shot" + + - name: Try deploy and check results for a site and Template2 + block: + - name: Deploy templates Template2 + mso_schema_template_deploy: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template2 + site: '{{ mso_site | default("ansible_test") }}' + state: deploy + + - name: Check deployment status by querying site and Template2 + mso_schema_template_deploy_status: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template2 + site: '{{ mso_site | default("ansible_test") }}' + state: query + register: status2_site_temp2 + + - name: Increment the retry count + set_fact: + retry_count: "{{ 0 if retry_count is undefined else retry_count | int + 1 }}" + + rescue: + - fail: + msg: status2_site_temp2 correct value retrieved continuing + when: + - status2_site_temp2.current is defined + - status2_site_temp2.current.anps == [] + + - fail: + msg: Maximum retries of deploy and check group for status2_site_temp2 reached + when: retry_count | int == 10 + + - debug: + msg: "Deploy and check group for status2_site_temp2 failed, let's give it another shot" + + - name: Verify status after querying site post deployment + assert: + that: + - status2_site.current | length == 2 + - status2_site_temp1.current.anps == [] + - status2_site_temp1.current.bds == [] + - status2_site_temp1.current.vrfs == [] + - status2_site_temp2.current.anps == [] + - status2_site_temp2.current.bds == [] + - status2_site_temp2.current.vrfs == [] + + - name: Check deployment status by querying site and non associated Template 1 + mso_schema_template_deploy_status: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + site: 'aws_{{ mso_site | default("ansible_test") }}' + state: query + ignore_errors: yes + register: status_site_temp3 + + - name: Verify status after querying site with non associated Template 1 + assert: + that: + - status_site_temp3.msg == "Provided Template 'Template1' not associated with Site 'aws_ansible_test'." + + - name: Check Non-existing schema + mso_schema_template_deploy_status: + <<: *mso_info + schema: non-existing-schema + state: query + ignore_errors: yes + register: non_schema + + - name: Verify non_existing_schema + assert: + that: + - non_schema.msg == "Schema 'non-existing-schema' not found." + + - name: Check deployment status of non-existing-template + mso_schema_template_deploy_status: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: non-existing-template + state: query + ignore_errors: yes + register: non_temp + + - name: Verify non_existing_template + assert: + that: + - non_temp.msg == "Template 'non-existing-template' not found."
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_external_epg/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_external_epg/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_external_epg/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_external_epg/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_external_epg/tasks/main.yml new file mode 100644 index 00000000..dc8372c9 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_external_epg/tasks/main.yml @@ -0,0 +1,1158 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Cindy Zhao (@cizhao) <cizhao@cisco.com> +# Copyright: (c) 2020, Lionel Hercot (@lhercot) <lhercot@cisco.com> +# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> (based on mso_site test case) +# + +# 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") }}' + +# - name: Ensure site exist +# mso_site: &site_present +# 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") }}' +# site: '{{ mso_site | default("ansible_test") }}' +# apic_username: '{{ apic_username }}' +# apic_password: '{{ apic_password }}' +# apic_site_id: '{{ apic_site_id | default(101) }}' +# urls: +# - https://{{ apic_hostname }} +# state: present + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Undeploy templates if deployed from previous test case + mso_schema_template_deploy: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: "{{ item }}" + site: '{{ mso_site | default("ansible_test") }}' + state: undeploy + ignore_errors: yes + loop: + - Template 1 + - Template 2 + +- name: Remove schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Ensure tenant ansible_test exist + mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + # sites: + # - '{{ mso_site | default("ansible_test") }}' + state: present + +- name: Ensure schema 1 with Template 1 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template 1 + state: present + +- name: Ensure schema 1 with Template 2 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template 2 + state: present + +- name: Ensure schema 2 with Template 3 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template 3 + state: present + +- name: Ensure Filter 1 exist + mso_schema_template_filter_entry: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + filter: Filter1 + entry: Filter1-Entry + state: present + +- name: Ensure Contract1 exist + mso_schema_template_contract_filter: &contract_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract1 + filter: Filter1 + filter_schema: '{{ mso_schema | default("ansible_test") }}' + filter_template: Template 1 + state: present + +- name: Ensure Filter 2 exist + mso_schema_template_filter_entry: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + filter: Filter2 + entry: Filter2-Entry + state: present + +- name: Ensure Contract2 exist + mso_schema_template_contract_filter: &contract2_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + contract: Contract2 + filter: Filter2 + filter_schema: '{{ mso_schema | default("ansible_test") }}' + filter_template: Template 2 + state: present + +- name: Ensure VRF exist + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF + #layer3_multicast: true + state: present + +- name: Ensure VRF2 exist + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF2 + state: present + +- name: Ensure VRF3 exist + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + vrf: VRF3 + state: present + +- name: Ensure VRF4 exist + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + vrf: VRF4 + state: present + +- name: Ensure L3out exist + mso_schema_template_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + l3out: L3out + vrf: + name: VRF + state: present + +- name: Ensure L3out2 exist + mso_schema_template_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + l3out: L3out2 + vrf: + name: VRF2 + state: present + +- name: Ensure L3out3 exist + mso_schema_template_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + l3out: L3out3 + vrf: + name: VRF3 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + state: present + +- name: Ensure L3out4 exist + mso_schema_template_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + l3out: L3out4 + vrf: + name: VRF4 + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + state: present + +- name: Ensure ANP exists + mso_schema_template_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP1 + state: present + +- name: Ensure ANP2 exist + mso_schema_template_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP2 + state: present + +- name: Ensure ANP3 exist + mso_schema_template_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP3 + state: present + +- name: Ensure ANP4 exist + mso_schema_template_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + anp: ANP4 + state: present + +- name: Ensure ansible_test_1 external EPG does not exist + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_1 + state: absent + +- name: Ensure ansible_test_2 external EPG does not exist + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + external_epg: ansible_test_2 + state: absent + +- name: Ensure ansible_test_3 external EPG does not exist + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + external_epg: ansible_test_3 + state: absent + +- name: Ensure ansible_test_4 external EPG does not exist + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_4 + state: absent + +- name: Ensure ansible_test_6 external EPG does not exist + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + external_epg: ansible_test_6 + state: absent + +- name: Ensure ansible_test_7 external EPG does not exist + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + external_epg: ansible_test_7 + state: absent + +# ADD external EPG +- name: Add external EPG (check_mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_1 + vrf: + name: VRF + state: present + check_mode: yes + register: cm_add_epg + +- name: Verify cm_add_epg + assert: + that: + - cm_add_epg is changed + - cm_add_epg.previous == {} + - cm_add_epg.current.name == "ansible_test_1" + - cm_add_epg.current.vrfRef.templateName == "Template1" + - cm_add_epg.current.vrfRef.vrfName == "VRF" + +- name: Add external EPG (normal mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_1 + vrf: + name: VRF + state: present + register: nm_add_epg + +- name: Verify nm_add_epg + assert: + that: + - nm_add_epg is changed + - nm_add_epg.previous == {} + - nm_add_epg.current.name == "ansible_test_1" + - nm_add_epg.current.vrfRef.templateName == "Template1" + - nm_add_epg.current.vrfRef.vrfName == "VRF" + - cm_add_epg.current.vrfRef.schemaId == nm_add_epg.current.vrfRef.schemaId + +- name: Add external EPG again (check_mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_1 + vrf: + name: VRF + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + state: present + check_mode: yes + register: cm_add_epg_again + +- name: Verify cm_add_epg_again + assert: + that: + - cm_add_epg_again is not changed + - cm_add_epg_again.previous.name == "ansible_test_1" + - cm_add_epg_again.current.name == "ansible_test_1" + - cm_add_epg_again.previous.vrfRef.templateName == "Template1" + - cm_add_epg_again.current.vrfRef.templateName == "Template1" + - cm_add_epg_again.previous.vrfRef.vrfName == "VRF" + - cm_add_epg_again.current.vrfRef.vrfName == "VRF" + - cm_add_epg_again.previous.vrfRef.schemaId == cm_add_epg_again.current.vrfRef.schemaId + + +- name: Add epg again (normal mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_1 + vrf: + name: VRF + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + state: present + register: nm_add_epg_again + +- name: Verify nm_add_epg_again + assert: + that: + - nm_add_epg_again is not changed + - nm_add_epg_again.previous.name == "ansible_test_1" + - nm_add_epg_again.current.name == "ansible_test_1" + - nm_add_epg_again.previous.vrfRef.templateName == "Template1" + - nm_add_epg_again.current.vrfRef.templateName == "Template1" + - nm_add_epg_again.previous.vrfRef.vrfName == "VRF" + - nm_add_epg_again.current.vrfRef.vrfName == "VRF" + - nm_add_epg_again.previous.vrfRef.schemaId == nm_add_epg_again.current.vrfRef.schemaId + +- name: Add external EPG 2(normal mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + external_epg: ansible_test_2 + vrf: + name: VRF3 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + l3out: + name: L3out3 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + state: present + register: nm_add_epg_2 + +- name: Add external EPG 3 (normal mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + external_epg: ansible_test_3 + vrf: + name: VRF4 + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + l3out: + name: L3out4 + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + state: present + register: nm_add_epg_3 + +- name: Add external EPG 4 (normal mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_4 + vrf: + name: VRF + state: present + register: nm_add_epg_4 + +- name: Verify nm_add_epg_2 and nm_add_epg_3 + assert: + that: + - nm_add_epg_2 is changed + - nm_add_epg_3 is changed + - nm_add_epg_2.current.name == "ansible_test_2" + - nm_add_epg_3.current.name == "ansible_test_3" + - nm_add_epg_2.current.vrfRef.templateName == "Template2" + - nm_add_epg_3.current.vrfRef.templateName == "Template3" + - nm_add_epg_2.current.vrfRef.vrfName == "VRF3" + - nm_add_epg_3.current.vrfRef.vrfName == "VRF4" + - nm_add_epg_2.current.vrfRef.schemaId == nm_add_epg.current.vrfRef.schemaId + - nm_add_epg_3.current.vrfRef.schemaId != nm_add_epg.current.vrfRef.schemaId + +- name: Add external EPG 5 (normal mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + external_epg: ansible_test_5 + vrf: + name: VRF + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: + name: ANP1 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + state: present + register: nm_add_epg_5 + +- name: Verify nm_add_epg_5 + assert: + that: + - nm_add_epg_5 is changed + - nm_add_epg_5.current.name == "ansible_test_5" + +- name: Add external EPG 5 again with L3Out (normal mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + external_epg: ansible_test_5 + vrf: + name: VRF + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + l3out: + name: L3out + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: + name: ANP1 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + state: present + register: nm_add_epg_5_again + +- name: Verify nm_add_epg_5_again + assert: + that: + - nm_add_epg_5_again is changed + - nm_add_epg_5_again.current.name == "ansible_test_5" + +- name: Add external EPG 6 with external epg type cloud (normal mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + external_epg: ansible_test_6 + type: cloud + vrf: + name: VRF + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: + name: ANP1 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + state: present + register: nm_add_epg_6 + +- name: Verify nm_add_epg_6 + assert: + that: + - nm_add_epg_6 is changed + - nm_add_epg_6.current.name == "ansible_test_6" + - nm_add_epg_6.current.vrfRef.templateName == "Template1" + - nm_add_epg_6.current.vrfRef.vrfName == "VRF" + - nm_add_epg_6.current.anpRef.anpName == "ANP1" + +- name: Add external EPG 6 with external epg type cloud again(normal mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + external_epg: ansible_test_6 + type: cloud + vrf: + name: VRF + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: + name: ANP1 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + state: present + register: nm_add_epg_6_again + +- name: Verify nm_add_epg_6_again + assert: + that: + - nm_add_epg_6_again is not changed + - nm_add_epg_6_again.current.name == "ansible_test_6" + +- name: Add external EPG 6 with external epg type cloud with modification(normal mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + external_epg: ansible_test_6 + type: cloud + vrf: + name: VRF2 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: + name: ANP1 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + state: present + register: nm_add_epg_6_again_2 + +- name: Verify nm_add_epg_6_again + assert: + that: + - nm_add_epg_6_again_2 is changed + - nm_add_epg_6_again_2.current.name == "ansible_test_6" + - nm_add_epg_6_again_2.current.vrfRef.vrfName == "VRF2" + - nm_add_epg_6_again_2.current.anpRef.anpName == "ANP1" + +- name: Add external EPG 7 with external epg type on-premise explicitly mentioned again(normal mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + external_epg: ansible_test_7 + type: on-premise + vrf: + name: VRF + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + l3out: + name: L3out + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + state: present + register: nm_add_epg_7 + +- name: Verify nm_add_epg_7 + assert: + that: + - nm_add_epg_7 is changed + - nm_add_epg_7.current.name == "ansible_test_7" + - nm_add_epg_7.current.vrfRef.templateName == "Template1" + - nm_add_epg_7.current.vrfRef.vrfName == "VRF" + +- name: Add external EPG 7 with external epg type not mentioned again(normal mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + external_epg: ansible_test_7 + vrf: + name: VRF + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + l3out: + name: L3out + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + state: present + register: nm_add_epg_7_again + +- name: Verify nm_add_epg_7_again + assert: + that: + - nm_add_epg_7_again is not changed + - nm_add_epg_7_again.current.name == "ansible_test_7" + +# CHANGE external EPG +- name: Change epg from different template (check_mode) + mso_schema_template_external_epg: &change_epg_template + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + external_epg: ansible_test_2 + vrf: + name: VRF + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + state: present + check_mode: yes + register: cm_change_epg + +- name: Verify cm_change_epg from different template to own template + assert: + that: + - cm_change_epg is changed + - cm_change_epg.current.name == 'ansible_test_2' + - cm_change_epg.current.vrfRef.vrfName == 'VRF' + - cm_change_epg.current.vrfRef.templateName == "Template1" + - cm_change_epg.current.vrfRef.schemaId == cm_change_epg.previous.vrfRef.schemaId + +- name: Change epg from different template to own template (normal_mode) + mso_schema_template_external_epg: + <<: *change_epg_template + state: present + register: nm_change_epg + +- name: Verify nm_change_epg from different template to own template + assert: + that: + - nm_change_epg is changed + - nm_change_epg.current.name == 'ansible_test_2' + - nm_change_epg.current.vrfRef.vrfName == 'VRF' + - nm_change_epg.current.vrfRef.templateName == "Template1" + - nm_change_epg.current.vrfRef.schemaId == nm_change_epg.previous.vrfRef.schemaId + +- name: Change epg again from different template (check_mode) + mso_schema_template_external_epg: + <<: *change_epg_template + check_mode: yes + register: cm_change_epg_again + +- name: Verify cm_change_epg_again + assert: + that: + - cm_change_epg_again is not changed + - cm_change_epg_again.current.name == 'ansible_test_2' + - cm_change_epg_again.current.vrfRef.vrfName == 'VRF' + - cm_change_epg_again.current.vrfRef.templateName == "Template1" + - cm_change_epg_again.current.vrfRef.schemaId == cm_change_epg_again.previous.vrfRef.schemaId + +- name: Change epg again from different template (normal_mode) + mso_schema_template_external_epg: + <<: *change_epg_template + state: present + register: nm_change_epg_again + +- name: Verify nm_change_epg_again from different template to own template + assert: + that: + - nm_change_epg_again is not changed + - nm_change_epg_again.current.name == 'ansible_test_2' + - nm_change_epg_again.current.vrfRef.vrfName == 'VRF' + - nm_change_epg_again.current.vrfRef.templateName == "Template1" + - nm_change_epg_again.current.vrfRef.schemaId == nm_change_epg_again.previous.vrfRef.schemaId + +- name: Change VRF from different schema (normal mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + external_epg: ansible_test_3 + vrf: + name: VRF + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + state: present + register: nm_change_epg_vrf4 + +- name: Verify nm_change_epg_vrf4 and nm_change_epg_vrf2 + assert: + that: + - nm_change_epg_vrf4 is changed + - nm_change_epg_vrf4.current.name == 'ansible_test_3' + - nm_change_epg_vrf4.current.vrfRef.vrfName == 'VRF' + - nm_change_epg_vrf4.current.vrfRef.templateName == "Template1" + - nm_change_epg_vrf4.current.vrfRef.schemaId != nm_change_epg_vrf4.previous.vrfRef.schemaId + +- name: Change epg 1 l3out(normal mode) + mso_schema_template_external_epg: &change_l3out + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_1 + vrf: + name: VRF2 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + l3out: + name: L3out2 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + state: present + register: nm_change_epg_1_l3out + +- name: Change epg 1 settings(normal mode) + mso_schema_template_external_epg: + <<: *change_l3out + vrf: + name: VRF + l3out: + name: L3out + state: present + register: nm_change_epg_1_settings + +- name: Verify nm_change_epg_1_settings and nm_change_epg_1_l3out + assert: + that: + - nm_change_epg_1_settings is changed + - nm_change_epg_1_settings.previous.vrfRef.vrfName == 'VRF2' + - nm_change_epg_1_settings.previous.vrfRef.templateName == 'Template1' + - nm_change_epg_1_settings.current.vrfRef.vrfName == 'VRF' + - nm_change_epg_1_settings.current.vrfRef.templateName == 'Template1' + - nm_change_epg_1_settings.current.l3outRef.l3outName == 'L3out' + - nm_change_epg_1_settings.current.l3outRef.templateName == 'Template1' + - nm_change_epg_1_settings.previous.l3outRef.schemaId == nm_change_epg_1_settings.current.l3outRef.schemaId + - nm_change_epg_1_l3out is changed + - nm_change_epg_1_l3out.previous.vrfRef.vrfName == 'VRF' + - nm_change_epg_1_l3out.previous.vrfRef.templateName == 'Template1' + - nm_change_epg_1_l3out.current.vrfRef.vrfName == 'VRF2' + - nm_change_epg_1_l3out.current.vrfRef.templateName == 'Template1' + - nm_change_epg_1_l3out.current.l3outRef.l3outName == 'L3out2' + - nm_change_epg_1_l3out.current.l3outRef.templateName == 'Template1' + +- name: Change epg 4 preferredGroup(normal mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_4 + vrf: + name: VRF + preferred_group: true + state: present + register: nm_change_epg_4_preferred_group + +- name: Change epg 4 preferredGroup again(normal mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_4 + vrf: + name: VRF + preferred_group: false + state: present + register: nm_change_epg_4_preferred_group_again + +- name: Verify nm_change_epg_4_preferred_group and nm_change_epg_4_preferred_group_again + assert: + that: + - nm_change_epg_4_preferred_group is changed + - nm_change_epg_4_preferred_group_again is changed + - nm_change_epg_4_preferred_group.current.preferredGroup == true + - nm_change_epg_4_preferred_group_again.current.preferredGroup == false + +# QUERY ALL EPG +- name: Query all EPG (check_mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + state: query + check_mode: yes + register: cm_query_all_epgs + +- name: Query all EPG (normal mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + state: query + register: nm_query_all_epgs + +- name: Verify query_all_epgs + assert: + that: + - cm_query_all_epgs is not changed + - nm_query_all_epgs is not changed + - cm_query_all_epgs.current | length == nm_query_all_epgs.current | length == 2 + +# QUERY AN EPG +- name: Query epg 1(check_mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_1 + state: query + check_mode: yes + register: cm_query_epg_1 + +- name: Query epg 1(normal_mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_1 + state: query + register: nm_query_epg_1 + +- name: Verify cm_query_epg_1 and nm_query_epg_1 + assert: + that: + - cm_query_epg_1 is not changed + - nm_query_epg_1 is not changed + - cm_query_epg_1.current.l3outRef.l3outName == 'L3out' == nm_query_epg_1.current.l3outRef.l3outName + - cm_query_epg_1.current.l3outRef.templateName == nm_query_epg_1.current.l3outRef.templateName == 'Template1' + - cm_query_epg_1.current.l3outRef.schemaId == nm_query_epg_1.current.l3outRef.schemaId + - cm_query_epg_1.current.vrfRef.vrfName == nm_query_epg_1.current.vrfRef.vrfName == 'VRF' + - cm_query_epg_1.current.vrfRef.templateName == nm_query_epg_1.current.vrfRef.templateName == 'Template1' + - cm_query_epg_1.current.vrfRef.schemaId == nm_query_epg_1.current.vrfRef.schemaId + - nm_query_epg_1.current.l3outRef.schemaId == nm_query_epg_1.current.vrfRef.schemaId + +- name: Query epg 5(normal_mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + external_epg: ansible_test_5 + state: query + register: nm_query_epg_5 + +- name: Verify nm_query_epg_5 + assert: + that: + - nm_query_epg_5.current.l3outRef.l3outName == 'L3out' + +- name: Query epg 6(normal_mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + external_epg: ansible_test_6 + state: query + register: nm_query_epg_6 + +- name: Verify nm_query_epg_5 + assert: + that: + - nm_add_epg_6.current.anpRef.anpName == "ANP1" + +# REMOVE EPG +- name: Remove EPG 4 (check_mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_4 + state: absent + check_mode: yes + register: cm_remove_epg_4 + +- name: Verify cm_remove_epg_4 + assert: + that: + - cm_remove_epg_4 is changed + - cm_remove_epg_4.current == {} + +- name: Remove EPG 4 (normal_mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_4 + state: absent + register: nm_remove_epg_4 + +- name: Verify nm_remove_epg_4 + assert: + that: + - nm_remove_epg_4 is changed + - nm_remove_epg_4.current == {} + +- name: Remove EPG 4 again (normal mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_4 + state: absent + register: nm_remove_epg_4_again + +- name: Verify nm_remove_epg_4_again + assert: + that: + - nm_remove_epg_4_again is not changed + - nm_remove_epg_4_again.previous == nm_remove_epg_4_again.current == {} + +- name: Add external EPG 4 description for version greater than 3.3 + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_4 + description: "Description of an external EPG 4" + vrf: + name: VRF + state: present + register: add_epg_4 + when: version.current.version is version('3.3', '>=') + +- name: Verify add_epg_4 for version greater than 3.3 + assert: + that: + - add_epg_4 is changed + - add_epg_4.current.name == "ansible_test_4" + - add_epg_4.current.description == "Description of an external EPG 4" + - add_epg_4.current.vrfRef.templateName == "Template1" + - add_epg_4.current.vrfRef.vrfName == "VRF" + - add_epg_4.current.vrfRef.schemaId == add_epg_4.current.vrfRef.schemaId + when: version.current.version is version('3.3', '>=') + + +# QUERY NON-EXISTING EPG +- name: Query non-existing EPG (check_mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: non-existing-epg + state: query + ignore_errors: yes + check_mode: yes + register: cm_query_non_existing_epg + +- name: Query non-existing EPG (normal_mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: non-existing-epg + state: query + ignore_errors: yes + register: nm_query_non_existing_epg + +- name: Verify cm_query_non_existing_epg and nm_query_non_existing_epg + assert: + that: + - cm_query_non_existing_epg is not changed + - nm_query_non_existing_epg is not changed + - cm_query_non_existing_epg == nm_query_non_existing_epg + - cm_query_non_existing_epg.msg == nm_query_non_existing_epg.msg == "External EPG 'non-existing-epg' not found" + +# USE A NON-EXISTING SCHEMA +- name: Non-existing schema for epg (check_mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: non-existing-schema + template: Template 1 + state: query + check_mode: yes + ignore_errors: yes + register: cm_non_existing_schema + +- name: Non-existing schema for epg (normal_mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: non-existing-schema + template: Template 1 + state: query + ignore_errors: yes + register: nm_non_existing_schema + +- name: Verify non_existing_schema + assert: + that: + - cm_non_existing_schema is not changed + - nm_non_existing_schema is not changed + - cm_non_existing_schema == nm_non_existing_schema + - cm_non_existing_schema.msg == nm_non_existing_schema.msg == "Provided schema 'non-existing-schema' does not exist." + +# USE A NON-EXISTING TEMPLATE +- name: Non-existing template for epg (check_mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: non-existing-template + state: query + check_mode: yes + ignore_errors: yes + register: cm_non_existing_template + +- name: Non-existing template for epg (normal_mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: non-existing-template + state: query + ignore_errors: yes + register: nm_non_existing_template + +- name: Verify non_existing_template + assert: + that: + - cm_non_existing_template is not changed + - nm_non_existing_template is not changed + - cm_non_existing_template == nm_non_existing_template + - cm_non_existing_template.msg == nm_non_existing_template.msg == "Provided template 'non-existing-template' does not exist. Existing templates{{':'}} Template1, Template2" + +# Checking if contract are removed after re-applying an EPG. (#13 | #62137) +- name: Remove EPG 2/5/6/7 to avoid circle errors (normal mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + external_epg: '{{ item }}' + state: absent + loop: + - ansible_test_2 + - ansible_test_5 + - ansible_test_6 + - ansible_test_7 + +- name: Add Contracts to EPG 1 + mso_schema_template_external_epg_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_1 + contract: + name: '{{ item.name }}' + template: '{{ item.template }}' + type: '{{ item.type }}' + state: present + loop: + - { name: Contract1, template: Template 1, type: consumer } + - { name: Contract1, template: Template 1, type: provider } + - { name: Contract2, template: Template 2, type: consumer } + - { name: Contract2, template: Template 2, type: provider } + +- name: Query contract EPG 1(normal mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_1 + state: query + register: nm_query_epg1_contract + +- name: Verify nm_query_epg1_contract + assert: + that: + - nm_query_epg1_contract.current.contractRelationships | length == 4 + +- name: Add EPG 1 again (normal_mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_1 + vrf: + name: VRF + l3out: + name: L3out + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + state: present + register: nm_add_epg_1_again + +- name: Verify that EPG 1 didn't change + assert: + that: + - nm_add_epg_1_again is not changed + +- name: Query contract EPG 1 again + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_1 + state: query + register: nm_query_epg1_contract_again + +- name: Verify that 4 contracts are in EPG 1 using nm_query_epg1_contract_again + assert: + that: + - nm_query_epg1_contract_again.current.contractRelationships | length == 4 + +# Checking if modifying an external EPG with existing contracts throw an MSO error. (#82) +- name: Change external EPG 1 VRF (normal_mode) + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_1 + vrf: + name: VRF2 + l3out: + name: L3out2 + state: present + register: nm_change_ext_epg_1_vrf + +- name: Verify that external EPG 1 did change + assert: + that: + - nm_change_ext_epg_1_vrf is changed + - nm_change_ext_epg_1_vrf.current.vrfRef.templateName == "Template1" + - nm_change_ext_epg_1_vrf.current.vrfRef.vrfName == "VRF2" + - nm_change_ext_epg_1_vrf.current.l3outRef.l3outName == "L3out2" + +- name: Query EPG 1 + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_1 + state: query + register: nm_query_contract_ext_epg_1 + +- name: Verify that 4 contracts are in external EPG 1 using nm_query_contract_ext_epg_1 + assert: + that: + - nm_query_contract_ext_epg_1.current.contractRelationships | length == 4
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_external_epg_contract/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_external_epg_contract/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_external_epg_contract/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_external_epg_contract/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_external_epg_contract/tasks/main.yml new file mode 100644 index 00000000..b4a803e1 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_external_epg_contract/tasks/main.yml @@ -0,0 +1,645 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Lionel Hercot (@lhercot) <lhercot@cisco.com> +# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> (based on mso_site test case) +# + +# 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: Ensure site exist +# mso_site: &site_present +# 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") }}' +# site: '{{ mso_site | default("ansible_test") }}' +# apic_username: '{{ apic_username }}' +# apic_password: '{{ apic_password }}' +# apic_site_id: '{{ apic_site_id | default(101) }}' +# urls: +# - https://{{ apic_hostname }} +# state: present + +- name: Remove schemas + mso_schema: + 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") }}' + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Ensure tenant ansible_test exist + mso_tenant: &tenant_present + 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") }}' + tenant: ansible_test + users: + - '{{ mso_username }}' + # sites: + # - '{{ mso_site | default("ansible_test") }}' + state: present + +- name: Ensure schema 1 with Template 1 exist + mso_schema_template: &schema_present + 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") }}' + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template 1 + state: present + +- name: Ensure schema 1 with Template 2 exist + mso_schema_template: + <<: *schema_present + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template 2 + state: present + +- name: Ensure schema 2 with Template 3 exist + mso_schema_template: + <<: *schema_present + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template 3 + state: present + +- name: Ensure VRF exist + mso_schema_template_vrf: + 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") }}' + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF + state: present + +- name: Ensure Filter 1 exist + mso_schema_template_filter_entry: + 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") }}' + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + filter: Filter1 + entry: Filter1-Entry + state: present + +- name: Ensure Filter 2 exist + mso_schema_template_filter_entry: + 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") }}' + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + filter: Filter2 + entry: Filter2-Entry + state: present + +- name: Ensure Contract1 exist + mso_schema_template_contract_filter: &contract_present + 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") }}' + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract1 + filter: Filter1 + filter_schema: '{{ mso_schema | default("ansible_test") }}' + filter_template: Template 1 + state: present + +- name: Ensure Contract2 exist + mso_schema_template_contract_filter: + <<: *contract_present + template: Template 2 + contract: Contract2 + filter: Filter2 + filter_schema: '{{ mso_schema | default("ansible_test") }}' + filter_template: Template 2 + state: present + +- name: Ensure external EPGs exist + mso_schema_template_externalepg: + 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") }}' + state: present + schema: '{{ item.schema }}' + template: '{{ item.template }}' + externalepg: '{{ item.externalepg }}' + vrf: + name: VRF + template: Template 1 + schema: '{{ mso_schema | default("ansible_test") }}' + loop: + - { schema: '{{ mso_schema | default("ansible_test") }}', template: 'Template 1', externalepg: 'ansible_test_1' } + - { schema: '{{ mso_schema | default("ansible_test") }}_2', template: 'Template 3', externalepg: 'ansible_test_3' } + +# ADD Contract to External EPG +- name: Add Contract1 to External EPG (check_mode) + mso_schema_template_external_epg_contract: &contract_ext_epg_present + 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") }}' + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_1 + contract: + name: Contract1 + type: consumer + state: present + check_mode: yes + register: cm_add_contract_rel + +- name: Verify cm_add_contract_rel + assert: + that: + - cm_add_contract_rel is changed + - cm_add_contract_rel.previous == {} + - cm_add_contract_rel.current.contractRef.templateName == "Template1" + - cm_add_contract_rel.current.contractRef.contractName == "Contract1" + - cm_add_contract_rel.current.relationshipType == "consumer" + +- name: Add Contract to External EPG (normal mode) + mso_schema_template_external_epg_contract: + <<: *contract_ext_epg_present + register: nm_add_contract_rel + +- name: Verify nm_add_contract_rel + assert: + that: + - nm_add_contract_rel is changed + - nm_add_contract_rel.previous == {} + - nm_add_contract_rel.current.contractRef.templateName == "Template1" + - nm_add_contract_rel.current.contractRef.contractName == "Contract1" + - nm_add_contract_rel.current.relationshipType == "consumer" + - cm_add_contract_rel.current.contractRef.schemaId == nm_add_contract_rel.current.contractRef.schemaId + +- name: Add Contract to External EPG again (check_mode) + mso_schema_template_external_epg_contract: + <<: *contract_ext_epg_present + check_mode: yes + register: cm_add_contract_rel_again + +- name: Verify cm_add_contract_rel_again + assert: + that: + - cm_add_contract_rel_again is not changed + - cm_add_contract_rel_again.previous.contractRef.templateName == "Template1" + - cm_add_contract_rel_again.current.contractRef.templateName == "Template1" + - cm_add_contract_rel_again.previous.contractRef.contractName == "Contract1" + - cm_add_contract_rel_again.current.contractRef.contractName == "Contract1" + - cm_add_contract_rel_again.previous.relationshipType == "consumer" + - cm_add_contract_rel_again.current.relationshipType == "consumer" + - cm_add_contract_rel_again.previous.contractRef.schemaId == cm_add_contract_rel_again.current.contractRef.schemaId + + +- name: Add Contract to External EPG again (normal mode) + mso_schema_template_external_epg_contract: + <<: *contract_ext_epg_present + register: nm_add_contract_rel_again + +- name: Verify nm_add_contract_rel_again + assert: + that: + - nm_add_contract_rel_again is not changed + - nm_add_contract_rel_again.previous.contractRef.templateName == "Template1" + - nm_add_contract_rel_again.current.contractRef.templateName == "Template1" + - nm_add_contract_rel_again.previous.contractRef.contractName == "Contract1" + - nm_add_contract_rel_again.current.contractRef.contractName == "Contract1" + - nm_add_contract_rel_again.previous.relationshipType == "consumer" + - nm_add_contract_rel_again.current.relationshipType == "consumer" + - nm_add_contract_rel_again.previous.contractRef.schemaId == nm_add_contract_rel_again.current.contractRef.schemaId + +- name: Add Contract1 to External EPG - provider (normal mode) + mso_schema_template_external_epg_contract: + <<: *contract_ext_epg_present + contract: + name: Contract1 + type: provider + register: nm_add_contract1_rel_provider + +- name: Add Contract2 to External EPG - consumer (normal mode) + mso_schema_template_external_epg_contract: + <<: *contract_ext_epg_present + contract: + name: Contract2 + template: Template 2 + type: consumer + register: nm_add_contract2_rel_consumer + +- name: Add Contract1 to External EPG 3 - provider (normal mode) + mso_schema_template_external_epg_contract: + <<: *contract_ext_epg_present + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: 'Template 3' + external_epg: ansible_test_3 + contract: + name: Contract1 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + type: provider + register: nm_add_contract3_rel_provider + +- name: Verify nm_add_contract1_rel_provider, nm_add_contract2_rel_consumer and nm_add_contract3_rel_provider + assert: + that: + - nm_add_contract1_rel_provider is changed + - nm_add_contract2_rel_consumer is changed + - nm_add_contract3_rel_provider is changed + - nm_add_contract1_rel_provider.current.contractRef.contractName == "Contract1" + - nm_add_contract2_rel_consumer.current.contractRef.contractName == "Contract2" + - nm_add_contract3_rel_provider.current.contractRef.contractName == "Contract1" + - nm_add_contract1_rel_provider.current.contractRef.templateName == "Template1" + - nm_add_contract2_rel_consumer.current.contractRef.templateName == "Template2" + - nm_add_contract3_rel_provider.current.contractRef.templateName == "Template1" + - nm_add_contract1_rel_provider.current.contractRef.schemaId == nm_add_contract2_rel_consumer.current.contractRef.schemaId == nm_add_contract3_rel_provider.current.contractRef.schemaId + - nm_add_contract2_rel_consumer.current.relationshipType == "consumer" + - nm_add_contract1_rel_provider.current.relationshipType == nm_add_contract3_rel_provider.current.relationshipType == "provider" + +# # QUERY ALL Contract to External EPG +- name: Query all contract relationship for External EPG (check_mode) + mso_schema_template_external_epg_contract: &contract_ext_epg_query + 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") }}' + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_1 + state: query + check_mode: yes + register: cm_query_all_contract_rels + +- name: Query all contract relationship for External EPG (normal mode) + mso_schema_template_external_epg_contract: + <<: *contract_ext_epg_query + register: nm_query_all_contract_rels + +- name: Verify query_all_contract_rels + assert: + that: + - cm_query_all_contract_rels is not changed + - nm_query_all_contract_rels is not changed + - cm_query_all_contract_rels.current | length == nm_query_all_contract_rels.current | length == 3 + + +# QUERY A Contract to External EPG +- name: Query Contract1 relationship for External EPG - consumer (check_mode) + mso_schema_template_external_epg_contract: + <<: *contract_ext_epg_query + contract: + name: Contract1 + type: consumer + check_mode: yes + register: cm_query_contract1_consumer_rel + +- name: Query Contract1 relationship for External EPG - consumer (normal mode) + mso_schema_template_external_epg_contract: + <<: *contract_ext_epg_query + contract: + name: Contract1 + type: consumer + register: nm_query_contract1_consumer_rel + +- name: Query Contract1 relationship for External EPG - provider (normal mode) + mso_schema_template_external_epg_contract: + <<: *contract_ext_epg_query + contract: + name: Contract1 + type: provider + register: nm_query_contract1_provider_rel + +- name: Query Contract1 relationship for External EPG - consumer (normal mode) + mso_schema_template_external_epg_contract: + <<: *contract_ext_epg_query + contract: + name: Contract2 + template: Template 2 + type: consumer + register: nm_query_contract2_consumer_rel + +- name: Query Contract1 relationship for External EPG - provider (normal mode) + mso_schema_template_external_epg_contract: + <<: *contract_ext_epg_query + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + external_epg: ansible_test_3 + contract: + name: Contract1 + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + type: provider + register: nm_query_contract3_provider_rel + +- name: Verify query_contractX_YYYYY_rel + assert: + that: + - cm_query_contract1_consumer_rel is not changed + - nm_query_contract1_consumer_rel is not changed + - nm_query_contract1_provider_rel is not changed + - nm_query_contract2_consumer_rel is not changed + - nm_query_contract3_provider_rel is not changed + - cm_query_contract1_consumer_rel == nm_query_contract1_consumer_rel + - cm_query_contract1_consumer_rel.current.contractRef.contractName == nm_query_contract1_consumer_rel.current.contractRef.contractName == nm_query_contract1_provider_rel.current.contractRef.contractName == "Contract1" + - nm_query_contract2_consumer_rel.current.contractRef.contractName == "Contract2" + - nm_query_contract3_provider_rel.current.contractRef.contractName == "Contract1" + - cm_query_contract1_consumer_rel.current.contractRef.templateName == nm_query_contract1_consumer_rel.current.contractRef.templateName == nm_query_contract1_provider_rel.current.contractRef.templateName == "Template1" + - nm_query_contract2_consumer_rel.current.contractRef.templateName == "Template2" + - nm_query_contract3_provider_rel.current.contractRef.templateName == "Template1" + - cm_query_contract1_consumer_rel.current.contractRef.schemaId == nm_query_contract1_consumer_rel.current.contractRef.schemaId == nm_query_contract1_provider_rel.current.contractRef.schemaId == nm_query_contract2_consumer_rel.current.contractRef.schemaId == nm_query_contract3_provider_rel.current.contractRef.schemaId + - cm_query_contract1_consumer_rel.current.relationshipType == nm_query_contract1_consumer_rel.current.relationshipType == nm_query_contract2_consumer_rel.current.relationshipType == "consumer" + - nm_query_contract1_provider_rel.current.relationshipType == nm_query_contract3_provider_rel.current.relationshipType == "provider" + + +# REMOVE Contract to External EPG +- name: Remove Contract to External EPG (check_mode) + mso_schema_template_external_epg_contract: + <<: *contract_ext_epg_present + state: absent + check_mode: yes + register: cm_remove_contract_rel + +- name: Verify cm_remove_contract_rel + assert: + that: + - cm_remove_contract_rel is changed + - cm_remove_contract_rel.current == {} + +- name: Remove Contract to External EPG (normal mode) + mso_schema_template_external_epg_contract: + <<: *contract_ext_epg_present + state: absent + register: nm_remove_contract_rel + +- name: Verify nm_remove_contract_rel + assert: + that: + - nm_remove_contract_rel is changed + - nm_remove_contract_rel.current == {} + +- name: Remove Contract to External EPG again (check_mode) + mso_schema_template_external_epg_contract: + <<: *contract_ext_epg_present + state: absent + check_mode: yes + register: cm_remove_contract_rel_again + +- name: Verify cm_remove_contract_rel_again + assert: + that: + - cm_remove_contract_rel_again is not changed + - cm_remove_contract_rel_again.current == {} + +- name: Remove Contract to External EPG again (normal mode) + mso_schema_template_external_epg_contract: + <<: *contract_ext_epg_present + state: absent + register: nm_remove_contract_rel_again + +- name: Verify nm_remove_contract_rel_again + assert: + that: + - nm_remove_contract_rel_again is not changed + - nm_remove_contract_rel_again.current == {} + + +# QUERY NON-EXISTING Contract to External EPG +- name: Query non-existing contract (check_mode) + mso_schema_template_external_epg_contract: + <<: *contract_ext_epg_query + contract: + name: non_existing_contract + type: provider + check_mode: yes + ignore_errors: yes + register: cm_query_non_contract + +- name: Query non-existing contract (normal mode) + mso_schema_template_external_epg_contract: + <<: *contract_ext_epg_query + contract: + name: non_existing_contract + type: provider + ignore_errors: yes + register: nm_query_non_contract + +- name: Verify query_non_contract + assert: + that: + - cm_query_non_contract is not changed + - nm_query_non_contract is not changed + - cm_query_non_contract == nm_query_non_contract + - cm_query_non_contract.msg is match("Contract '/schemas/[0-9a-zA-Z]*/templates/Template1/contracts/non_existing_contract' not found") + - nm_query_non_contract.msg is match("Contract '/schemas/[0-9a-zA-Z]*/templates/Template1/contracts/non_existing_contract' not found") + +# QUERY NON-EXISTING ExtEPG +- name: Query non-existing ExtEPG (check_mode) + mso_schema_template_external_epg_contract: + <<: *contract_ext_epg_query + external_epg: non_existing_ext_epg + check_mode: yes + ignore_errors: yes + register: cm_query_non_ext_epg + +- name: Query non-existing ExtEPG (normal mode) + mso_schema_template_external_epg_contract: + <<: *contract_ext_epg_query + external_epg: non_existing_ext_epg + ignore_errors: yes + register: nm_query_non_ext_epg + +- name: Verify query_non_ext_epg + assert: + that: + - cm_query_non_ext_epg is not changed + - nm_query_non_ext_epg is not changed + - cm_query_non_ext_epg == nm_query_non_ext_epg + - cm_query_non_ext_epg.msg == nm_query_non_ext_epg.msg == "Provided epg 'non_existing_ext_epg' does not exist. Existing epgs{{':'}} ansible_test_1" + +# USE A NON-EXISTING STATE +- name: Non-existing state for contract relationship (check_mode) + mso_schema_template_external_epg_contract: + <<: *contract_ext_epg_query + state: non-existing-state + check_mode: yes + ignore_errors: yes + register: cm_non_existing_state + +- name: Non-existing state for contract relationship (normal_mode) + mso_schema_template_external_epg_contract: + <<: *contract_ext_epg_query + state: non-existing-state + ignore_errors: yes + register: nm_non_existing_state + +- name: Verify non_existing_state + assert: + that: + - cm_non_existing_state is not changed + - nm_non_existing_state is not changed + - cm_non_existing_state == nm_non_existing_state + - cm_non_existing_state.msg == nm_non_existing_state.msg == "value of state must be one of{{':'}} absent, present, query, got{{':'}} non-existing-state" + +# USE A NON-EXISTING SCHEMA +- name: Non-existing schema for contract relationship (check_mode) + mso_schema_template_external_epg_contract: + <<: *contract_ext_epg_query + schema: non-existing-schema + check_mode: yes + ignore_errors: yes + register: cm_non_existing_schema + +- name: Non-existing schema for contract relationship (normal_mode) + mso_schema_template_external_epg_contract: + <<: *contract_ext_epg_query + schema: non-existing-schema + ignore_errors: yes + register: nm_non_existing_schema + +- name: Verify non_existing_schema + assert: + that: + - cm_non_existing_schema is not changed + - nm_non_existing_schema is not changed + - cm_non_existing_schema == nm_non_existing_schema + - cm_non_existing_schema.msg == nm_non_existing_schema.msg == "Provided schema 'non-existing-schema' does not exist." + +- name: Non-existing contract schema for contract relationship (check_mode) + mso_schema_template_external_epg_contract: + <<: *contract_ext_epg_query + contract: + name: Contract1 + schema: non-existing-schema + template: Template 1 + type: provider + check_mode: yes + ignore_errors: yes + register: cm_non_existing_contract_schema + +- name: Non-existing contract schema for contract relationship (normal_mode) + mso_schema_template_external_epg_contract: + <<: *contract_ext_epg_query + contract: + name: Contract1 + schema: non-existing-schema + template: Template 1 + type: provider + ignore_errors: yes + register: nm_non_existing_contract_schema + +- name: Verify non_existing_contract_schema + assert: + that: + - cm_non_existing_contract_schema is not changed + - nm_non_existing_contract_schema is not changed + - cm_non_existing_contract_schema == nm_non_existing_contract_schema + - cm_non_existing_contract_schema.msg == nm_non_existing_contract_schema.msg == "Provided schema 'non-existing-schema' does not exist." + +# USE A NON-EXISTING TEMPLATE +- name: Non-existing template for contract relationship (check_mode) + mso_schema_template_external_epg_contract: + <<: *contract_ext_epg_query + template: non-existing-template + check_mode: yes + ignore_errors: yes + register: cm_non_existing_template + +- name: Non-existing template for contract relationship (normal_mode) + mso_schema_template_external_epg_contract: + <<: *contract_ext_epg_query + template: non-existing-template + ignore_errors: yes + register: nm_non_existing_template + +- name: Verify non_existing_template + assert: + that: + - cm_non_existing_template is not changed + - nm_non_existing_template is not changed + - cm_non_existing_template == nm_non_existing_template + - cm_non_existing_template.msg == nm_non_existing_template.msg == "Provided template 'non-existing-template' does not exist. Existing templates{{':'}} Template1, Template2" + +- name: Non-existing contract template for contract relationship (check_mode) + mso_schema_template_external_epg_contract: + <<: *contract_ext_epg_query + contract: + name: Contract1 + template: non-existing-template + type: provider + check_mode: yes + ignore_errors: yes + register: cm_non_existing_contract_template + +- name: Non-existing contract template for contract relationship (normal_mode) + mso_schema_template_external_epg_contract: + <<: *contract_ext_epg_query + contract: + name: Contract1 + template: non-existing-template + type: provider + ignore_errors: yes + register: nm_non_existing_contract_template + +- name: Verify non_existing_contract_template + assert: + that: + - cm_non_existing_contract_template is not changed + - nm_non_existing_contract_template is not changed + - cm_non_existing_contract_template == nm_non_existing_contract_template + - cm_non_existing_contract_template.msg is match("Contract '/schemas/[0-9a-zA-Z]*/templates/non-existing-template/contracts/Contract1' not found") + - nm_non_existing_contract_template.msg is match("Contract '/schemas/[0-9a-zA-Z]*/templates/non-existing-template/contracts/Contract1' not found")
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_external_epg_selector/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_external_epg_selector/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_external_epg_selector/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_external_epg_selector/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_external_epg_selector/tasks/main.yml new file mode 100644 index 00000000..c2891e95 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_external_epg_selector/tasks/main.yml @@ -0,0 +1,452 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Lionel Hercot (@lhercot) <lhercot@cisco.com> +# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> (based on mso_site test case) +# Copyright: (c) 2020, Shreyas Srish (@shrsr) <ssrish@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") }}' + +- name: Remove schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Ensure tenant ansible_test exist + mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + # sites: + # - '{{ mso_site | default("ansible_test") }}' + state: present + +- name: Ensure schema 1 with Template 1 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template 1 + state: present + +- name: Ensure schema 1 with Template 2 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template 2 + state: present + +- name: Ensure schema 2 with Template 3 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template 3 + state: present + +- name: Ensure VRF exists + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF + state: present + +- name: Ensure VRF2 exists + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF2 + state: present + +- name: Ensure ANP1 exists + mso_schema_template_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP + state: present + +- name: Ensure ANP2 exists + mso_schema_template_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP2 + state: present + +- name: Ensure L3out exist + mso_schema_template_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + l3out: L3out + vrf: + name: VRF + state: present + +- name: Ensure L3out2 exist + mso_schema_template_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + l3out: L3out2 + vrf: + name: VRF2 + state: present + +# ADD External EPGs +- name: Ensure External EPG1 exists + mso_schema_template_externalepg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + externalepg: extEPG1 + vrf: + name: VRF + template: Template 1 + schema: '{{ mso_schema | default("ansible_test") }}' + l3out: + name: L3out + template: Template 1 + schema: '{{ mso_schema | default("ansible_test") }}' + anp: + name: ANP + template: Template 1 + schema: '{{ mso_schema | default("ansible_test") }}' + state: present + +- name: Ensure External EPG2 exists + mso_schema_template_externalepg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + externalepg: extEPG2 + vrf: + name: VRF2 + template: Template 1 + schema: '{{ mso_schema | default("ansible_test") }}' + l3out: + name: L3out2 + template: Template 1 + schema: '{{ mso_schema | default("ansible_test") }}' + anp: + name: ANP2 + template: Template 1 + schema: '{{ mso_schema | default("ansible_test") }}' + state: present + +# ADD Selector to EPG +- name: Add Selector to extEPG1 (check_mode) + mso_schema_template_external_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: extEPG1 + selector: selector_1 + state: present + check_mode: yes + register: cm_add_selector_1 + +- name: Verify cm_add_selector_1 + assert: + that: + - cm_add_selector_1 is changed + - cm_add_selector_1.previous == {} + - cm_add_selector_1.current.name == "selector_1" + - cm_add_selector_1.current.expressions == [] + +- name: Add Selector 1 to extEPG1 (normal_mode) + mso_schema_template_external_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: extEPG1 + selector: selector_1 + state: present + ignore_errors: yes + register: nm_add_selector_1 + +- name: Verify nm_add_selector_1 + assert: + that: + - nm_add_selector_1 is changed + - nm_add_selector_1.previous == {} + - nm_add_selector_1.current.name == "selector_1" + - nm_add_selector_1.current.expressions == [] + +- name: Add Selector 1 to extEPG1 again(normal_mode) + mso_schema_template_external_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: extEPG1 + selector: selector_1 + state: present + ignore_errors: yes + register: nm_add_selector_1_again + +- name: Verify nm_add_selector_1_again + assert: + that: + - nm_add_selector_1_again is not changed + +- name: Add Selector to extEPG1 again (normal_mode) + mso_schema_template_external_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: extEPG1 + selector: selector_1 + state: present + register: nm_add_selector_1_again + +- name: Verify nm_add_selector_1_again + assert: + that: + - nm_add_selector_1_again is not changed + +- name: Add Selector 2 to extEPG1 (normal_mode) + mso_schema_template_external_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: extEPG1 + selector: selector_2 + expressions: + - type: ip_address + operator: equals + value: 10.0.0.0 + state: present + register: nm_add_selector_2 + +- name: Verify nm_add_selector_2 + assert: + that: + - nm_add_selector_2 is changed + - nm_add_selector_2.previous == {} + - nm_add_selector_2.current.name == "selector_2" + - nm_add_selector_2.current.expressions[0].key == "ipAddress" + - nm_add_selector_2.current.expressions[0].operator == "equals" + - nm_add_selector_2.current.expressions[0].value == "10.0.0.0" + +- name: Add Selector 3 to extEPG1 (normal_mode) + mso_schema_template_external_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: extEPG1 + selector: selector_3 + expressions: + - type: ip_address + operator: equals + value: 10.1.1.1 + state: present + register: nm_add_selector_3 + +- name: Verify nm_add_selector_3 + assert: + that: + - nm_add_selector_3 is changed + - nm_add_selector_3.previous == {} + - nm_add_selector_3.current.name == "selector_3" + - nm_add_selector_3.current.expressions[0].value == "10.1.1.1" + +- name: Remove slector_1 + mso_schema_template_external_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: extEPG1 + selector: selector_1 + state: absent + register: nm_remove_selector_1 + +- name: Verify nm_remove_selector_1 + assert: + that: + - nm_remove_selector_1 is changed + +# QUERY selectors +- name: Query all selectors of extEPG1 + mso_schema_template_external_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: extEPG1 + state: query + register: nm_query_all + +- name: Verify nm_query_all + assert: + that: + - nm_query_all is not changed + +- name: Query a selector of extEPG1 + mso_schema_template_external_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: extEPG1 + selector: selector_2 + state: query + register: nm_query_selector_2 + +- name: Verify nm_query_selector_2 + assert: + that: + - nm_query_selector_2 is not changed + - nm_query_selector_2.current.expressions[0].value == "10.0.0.0" + +- name: Query a removed selector_1 of extEPG1 + mso_schema_template_external_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: extEPG1 + selector: selector_1 + state: query + ignore_errors: yes + register: nm_query_removed + +- name: Verify nm_query_removed + assert: + that: + - nm_query_removed.msg == "Selector 'selector_1' not found" + +# QUERY NON-EXISTING External EPG +- name: Query non-existing EPG (normal mode) + mso_schema_template_external_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: non_extEPG1 + selector: selector_1 + state: query + ignore_errors: yes + register: nm_query_non_epg + +- name: Verify query_non_epg + assert: + that: + - nm_query_non_epg is not changed + - nm_query_non_epg.msg == "Provided external epg 'non_extEPG1' does not exist. Existing epgs{{':'}} extEPG1, extEPG2" + +# USE A NON-EXISTING STATE +- name: Non-existing state (check_mode) + mso_schema_template_external_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: extEPG1 + selector: selector_1 + state: non-existing-state + check_mode: yes + ignore_errors: yes + register: cm_non_existing_state + +- name: Non-existing state (normal_mode) + mso_schema_template_external_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: extEPG1 + selector: selector_1 + state: non-existing-state + ignore_errors: yes + register: nm_non_existing_state + +- name: Verify non_existing_state + assert: + that: + - cm_non_existing_state is not changed + - nm_non_existing_state is not changed + - cm_non_existing_state == nm_non_existing_state + - cm_non_existing_state.msg == nm_non_existing_state.msg == "value of state must be one of{{':'}} absent, present, query, got{{':'}} non-existing-state" + +# USE A NON-EXISTING TEMPLATE +- name: Non-existing template (check_mode) + mso_schema_template_external_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: non-existing-template + external_epg: extEPG1 + selector: selector_1 + state: query + check_mode: yes + ignore_errors: yes + register: cm_non_existing_template + +- name: Non-existing template (normal_mode) + mso_schema_template_external_epg_selector: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: non-existing-template + external_epg: extEPG1 + selector: selector_1 + state: query + ignore_errors: yes + register: nm_non_existing_template + +- name: Verify non_existing_template + assert: + that: + - cm_non_existing_template is not changed + - nm_non_existing_template is not changed + - cm_non_existing_template == nm_non_existing_template + - cm_non_existing_template.msg == nm_non_existing_template.msg == "Provided template 'non-existing-template' does not exist. Existing templates{{':'}} Template1, Template2" + +# USE A NON-EXISTING SCHEMA +- name: Non-existing schema (check_mode) + mso_schema_template_external_epg_selector: + <<: *mso_info + schema: non-existing-schema + template: Template 1 + external_epg: extEPG1 + selector: selector_1 + state: query + check_mode: yes + ignore_errors: yes + register: cm_non_existing_schema + +- name: Non-existing schema (normal_mode) + mso_schema_template_external_epg_selector: + <<: *mso_info + schema: non-existing-schema + template: Template 1 + external_epg: extEPG1 + selector: selector_1 + state: query + ignore_errors: yes + register: nm_non_existing_schema + +- name: Verify non_existing_schema + assert: + that: + - cm_non_existing_schema is not changed + - nm_non_existing_schema is not changed + - cm_non_existing_schema == nm_non_existing_schema + - cm_non_existing_schema.msg == nm_non_existing_schema.msg == "Provided schema 'non-existing-schema' does not exist."
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_external_epg_subnet/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_external_epg_subnet/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_external_epg_subnet/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_external_epg_subnet/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_external_epg_subnet/tasks/main.yml new file mode 100644 index 00000000..291783d9 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_external_epg_subnet/tasks/main.yml @@ -0,0 +1,536 @@ +# Test code for the MSO modules +# Copyright: (c) 2021, Anvitha Jain (@anvitha-jain) <anvjain@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") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Undeploy templates if deployed from previous test case + mso_schema_template_deploy: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: "{{ item }}" + site: '{{ mso_site | default("ansible_test") }}' + state: undeploy + ignore_errors: yes + loop: + - Template 1 + - Template 2 + +- name: Remove schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Ensure ansible_test_1 external EPG does not exist + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_1 + state: absent + ignore_errors: yes + +- name: Ensure tenant ansible_test exist + mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + state: present + +- name: Ensure schema 1 with Template 1 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template 1 + state: present + +- name: Ensure VRF exist + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF + state: present + +- name: Ensure L3out exist + mso_schema_template_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + l3out: L3out + vrf: + name: VRF + state: present + +- name: Ensure ANP exists + mso_schema_template_anp: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + anp: ANP1 + state: present + +- name: Add external EPG + mso_schema_template_external_epg: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_1 + vrf: + name: VRF + state: present + +# ADD external EPG subnet +- name: Add external EPG subnet (check_mode) + mso_schema_template_external_epg_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_1 + subnet: 10.0.0.0/24 + state: present + check_mode: yes + register: cm_add_epg_subnet + +- name: Verify cm_add_epg_subnet + assert: + that: + - cm_add_epg_subnet is changed + - cm_add_epg_subnet.previous == {} + - cm_add_epg_subnet.current.ip == "10.0.0.0/24" + +- name: Add external EPG subnet (normal mode) + mso_schema_template_external_epg_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_1 + subnet: 10.0.0.0/24 + state: present + register: nm_add_epg_subnet + +- name: Verify nm_add_epg_subnet + assert: + that: + - nm_add_epg_subnet is changed + - nm_add_epg_subnet.previous == {} + - nm_add_epg_subnet.current.ip == "10.0.0.0/24" + +- name: Add external EPG subnet again (check_mode) + mso_schema_template_external_epg_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_1 + subnet: 10.0.0.0/24 + state: present + check_mode: yes + register: cm_add_epg_subnet_again + +- name: Verify cm_add_epg_subnet_again + assert: + that: + - cm_add_epg_subnet_again is not changed + - cm_add_epg_subnet_again.previous.ip == "10.0.0.0/24" + - cm_add_epg_subnet_again.current.ip == "10.0.0.0/24" + +- name: Add epg again subnet (normal mode) + mso_schema_template_external_epg_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_1 + subnet: 10.0.0.0/24 + state: present + register: nm_add_epg_subnet_again + +- name: Verify nm_add_epg_subnet_again + assert: + that: + - nm_add_epg_subnet_again is not changed + - nm_add_epg_subnet_again.previous.ip == "10.0.0.0/24" + - nm_add_epg_subnet_again.current.ip == "10.0.0.0/24" + +- name: Add external EPG subnet 2 + mso_schema_template_external_epg_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_1 + subnet: 10.0.0.2/24 + state: present + register: add_epg_subnet_2 + +- name: Verify add_epg_subnet_2 + assert: + that: + - add_epg_subnet_2 is changed + - add_epg_subnet_2.current.ip == "10.0.0.2/24" + +# QUERY ALL EPG Subnets +- name: Query all EPG (check_mode) + mso_schema_template_external_epg_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_1 + state: query + check_mode: yes + register: cm_query_all_epg_subnets + +- name: Query all EPG (normal mode) + mso_schema_template_external_epg_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_1 + state: query + register: nm_query_all_epg_subnets + +- name: Verify query_all_epg_subnets + assert: + that: + - cm_query_all_epg_subnets is not changed + - nm_query_all_epg_subnets is not changed + - cm_query_all_epg_subnets.current | length == nm_query_all_epg_subnets.current | length == 2 + +# QUERY AN EPG subnet +- name: Query epg subnet 1(check_mode) + mso_schema_template_external_epg_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_1 + subnet: 10.0.0.0/24 + state: query + check_mode: yes + register: cm_query_epg_subnet_1 + +- name: Query epg subnet 1(normal_mode) + mso_schema_template_external_epg_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_1 + subnet: 10.0.0.0/24 + state: query + register: nm_query_epg_subnet_1 + +- name: Verify cm_query_epg_subnet_1 and nm_query_epg_subnet_1 + assert: + that: + - cm_query_epg_subnet_1 is not changed + - nm_query_epg_subnet_1 is not changed + - cm_query_epg_subnet_1.current.ip == "10.0.0.0/24" == nm_query_epg_subnet_1.current.ip + +# REMOVE EPG +- name: Remove EPG subnet 1 (check_mode) + mso_schema_template_external_epg_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_1 + subnet: 10.0.0.0/24 + state: absent + check_mode: yes + register: cm_remove_epg_subnet_1 + +- name: Verify cm_remove_epg_subnet_1 + assert: + that: + - cm_remove_epg_subnet_1 is changed + - cm_remove_epg_subnet_1.current == {} + +- name: Remove EPG subnet 1 (normal_mode) + mso_schema_template_external_epg_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_1 + subnet: 10.0.0.0/24 + state: absent + register: nm_remove_epg_subnet_1 + +- name: Verify nm_remove_epg_subnet_1 + assert: + that: + - nm_remove_epg_subnet_1 is changed + - nm_remove_epg_subnet_1.current == {} + +- name: Remove EPG subnet 1 again (normal mode) + mso_schema_template_external_epg_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_1 + subnet: 10.0.0.0/24 + state: absent + register: nm_remove_epg_subnet_1_again + +- name: Verify nm_remove_epg_subnet_1_again + assert: + that: + - nm_remove_epg_subnet_1_again is not changed + - nm_remove_epg_subnet_1_again.previous == nm_remove_epg_subnet_1_again.current == {} + +# Chcek aggregate when scope parameter Shared control is absent and present +- name: Add aggregate without Shared control scope parameter + mso_schema_template_external_epg_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_1 + subnet: 10.0.0.2/24 + scope: import-rtctrl + aggregate: shared-rtctrl + state: present + ignore_errors: yes + register: add_epg_subnet_no_ag + +- name: Verify add_epg_subnet_no_ag + assert: + that: + - add_epg_subnet_no_ag is changed + +- name: Verify add_epg_subnet_no_ag (3.1.1g to 3.1.1n) + assert: + that: + - add_epg_subnet_no_ag.msg == "MSO Error 400{{':'}} Bad Request{{':'}} Patch Failed, Received{{':'}} Aggregate should be enabled only if shared-rtctrl is enabled in Scope exception while trying to update schema" + when: + - version.current.version is version('3.1.1g', '>=') + - version.current.version is version('3.2', '<') + +- name: Verify add_epg_subnet_no_ag (version < 3.1.1g) + assert: + that: + - add_epg_subnet_no_ag.msg == "MSO Error 400{{':'}} Bad Request{{':'}} Aggregate should be enabled only if shared-rtctrl is enabled in Scope" + when: + - version.current.version is version('3.1.1g', '<') + +- name: Verify add_epg_subnet_no_ag (version >= 4.0) + assert: + that: + - add_epg_subnet_no_ag.msg == "MSO Error 400{{':'}} ExternalEPG{{':'}} ansible_test_1 in Schema{{':'}} ansible_test , Template{{':'}} Template1 External EPG validation error{{':'}} aggregate should be enabled only if shared-rtctrl is enabled in Scope for subnet 10.0.0.2/24" + when: + - version.current.version is version('4.0', '>=') + +- name: Execute tasks only for MSO version < 4.0 + # mso_schema_validate not supported after 4.0, validation executed upon request + when: version.current.version is version('4.0', '<') + block: + - name: Get Validation status + mso_schema_validate: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + state: query + ignore_errors: yes + register: query_validate + when: version.current.version is version('3.6', '>=') + + - name: Verify query_validate for a version that's after 3.6 + assert: + that: + - query_validate is not changed + - query_validate.msg is match ("MSO Error 400{{':'}} Bad Request{{':'}} Patch Failed, Received{{':'}} Aggregate should be enabled only if shared-rtctrl is enabled in Scope exception while trying to update schema") + when: + - version.current.version is version('3.6', '>=') + +- name: Add aggregate with Shared control scope parameter + mso_schema_template_external_epg_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_1 + subnet: 10.0.0.2/24 + scope: shared-rtctrl + aggregate: shared-rtctrl + state: present + ignore_errors: yes + register: add_epg_subnet_ag + +- name: Verify add_epg_subnet_ag + assert: + that: + - add_epg_subnet_ag is changed + - add_epg_subnet_ag.current.aggregate[0] == "shared-rtctrl" + +- name: Change EPG subnet 2 by changing Route Controls + mso_schema_template_external_epg_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_1 + subnet: 10.0.0.2/24 + scope: + - import-rtctrl + - shared-security + - export-rtctrl + - shared-security + - import-security + state: present + register: change_epg_subnet + +- name: Verify change_epg_subnet + assert: + that: + - change_epg_subnet is changed + - change_epg_subnet.current.ip == "10.0.0.2/24" + - change_epg_subnet.current.scope | length == 5 + +# QUERY NON-EXISTING EPG subnet +- name: Query non-existing EPG subnet(check_mode) + mso_schema_template_external_epg_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_1 + subnet: 10.0.0.10/24 + state: query + ignore_errors: yes + check_mode: yes + register: cm_query_non_existing_epg_subnet + +- name: Query non-existing EPG subnet(normal_mode) + mso_schema_template_external_epg_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: ansible_test_1 + subnet: 10.0.0.10/24 + state: query + ignore_errors: yes + register: nm_query_non_existing_epg_subnet + +- name: Verify cm_query_non_existing_epg_subnet and nm_query_non_existing_epg_subnet + assert: + that: + - cm_query_non_existing_epg_subnet is not changed + - nm_query_non_existing_epg_subnet is not changed + - cm_query_non_existing_epg_subnet == nm_query_non_existing_epg_subnet + - cm_query_non_existing_epg_subnet.msg == nm_query_non_existing_epg_subnet.msg == "Subnet '10.0.0.10/24' not found" + +# QUERY NON-EXISTING EPG +- name: Query non-existing EPG subnet(check_mode) + mso_schema_template_external_epg_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: non_existing_epg + subnet: 10.0.0.2/24 + state: query + ignore_errors: yes + check_mode: yes + register: cm_query_non_existing_epg + +- name: Query non-existing EPG subnet(normal_mode) + mso_schema_template_external_epg_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + external_epg: non_existing_epg + subnet: 10.0.0.2/24 + state: query + ignore_errors: yes + register: nm_query_non_existing_epg + +- name: Verify cm_query_non_existing_epg and nm_query_non_existing_epg + assert: + that: + - cm_query_non_existing_epg is not changed + - nm_query_non_existing_epg is not changed + - cm_query_non_existing_epg == nm_query_non_existing_epg + - cm_query_non_existing_epg.msg == nm_query_non_existing_epg.msg == "Provided External EPG 'non_existing_epg' does not exist. Existing epgs{{':'}} ansible_test_1" + +# USE A NON-EXISTING SCHEMA +- name: Non-existing schema for epg subnet(check_mode) + mso_schema_template_external_epg_subnet: + <<: *mso_info + schema: non-existing-schema + template: Template 1 + external_epg: ansible_test_1 + subnet: 10.0.0.0/24 + state: query + check_mode: yes + ignore_errors: yes + register: cm_non_existing_schema + +- name: Non-existing schema for epg subnet(normal_mode) + mso_schema_template_external_epg_subnet: + <<: *mso_info + schema: non-existing-schema + template: Template 1 + external_epg: ansible_test_1 + subnet: 10.0.0.0/24 + state: query + ignore_errors: yes + register: nm_non_existing_schema + +- name: Verify non_existing_schema + assert: + that: + - cm_non_existing_schema is not changed + - nm_non_existing_schema is not changed + - cm_non_existing_schema == nm_non_existing_schema + - cm_non_existing_schema.msg == nm_non_existing_schema.msg == "Provided schema 'non-existing-schema' does not exist." + +# USE A NON-EXISTING TEMPLATE +- name: Non-existing template for epg subnet(check_mode) + mso_schema_template_external_epg_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: non-existing-template + external_epg: ansible_test_1 + subnet: 10.0.0.0/24 + state: query + check_mode: yes + ignore_errors: yes + register: cm_non_existing_template + +- name: Non-existing template for epg subnet(normal_mode) + mso_schema_template_external_epg_subnet: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: non-existing-template + external_epg: ansible_test_1 + subnet: 10.0.0.0/24 + state: query + ignore_errors: yes + register: nm_non_existing_template + +- name: Verify non_existing_template + assert: + that: + - cm_non_existing_template is not changed + - nm_non_existing_template is not changed + - cm_non_existing_template == nm_non_existing_template + - cm_non_existing_template.msg == nm_non_existing_template.msg == "Provided template 'non-existing-template' does not exist. Existing templates{{':'}} Template1"
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_filter_entry/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_filter_entry/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_filter_entry/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_filter_entry/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_filter_entry/tasks/main.yml new file mode 100644 index 00000000..f9039ef3 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_filter_entry/tasks/main.yml @@ -0,0 +1,326 @@ +# Test code for the MSO modules +# Copyright: (c) 2021, Anvitha Jain (@anvitha-jain) <anvjain@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") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Ensure site exist + mso_site: &site_present + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + apic_username: '{{ apic_username }}' + apic_password: '{{ apic_password }}' + apic_site_id: '{{ apic_site_id | default(101) }}' + urls: + - https://{{ apic_hostname }} + state: present + +- name: Remove schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Ensure tenant ansible_test exist + mso_tenant: &tenant_present + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + sites: + - '{{ mso_site | default("ansible_test") }}' + state: present + +- name: Ensure schema 1 with Template1 exist + mso_schema_template: &schema_present + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template1 + state: present + +- name: Create filter with filter entry (check_model) + cisco.mso.mso_schema_template_filter_entry: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + filter: filter1 + filter_display_name: filter1 + entry: filter_entry1 + state: present + check_mode: yes + register: cm_add_filter + +- name: Create filter with filter entry (normal mode) + cisco.mso.mso_schema_template_filter_entry: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + filter: filter1 + entry: filter_entry1 + state: present + register: nm_add_filter + +- name: Create filter with filter entry again + cisco.mso.mso_schema_template_filter_entry: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + filter: filter1 + entry: filter_entry1 + state: present + register: add_filter_again + +- name: Verify add_filter + assert: + that: + - cm_add_filter is changed + - cm_add_filter.previous == {} + - cm_add_filter.current.name == "filter_entry1" + - nm_add_filter is changed + - nm_add_filter.previous == {} + - nm_add_filter.current.name == "filter_entry1" + - add_filter_again is not changed + - add_filter_again.previous.name == "filter_entry1" + - nm_add_filter.current == add_filter_again.current + +- name: Add description to filter and filter entry for version greater than 3.3 + cisco.mso.mso_schema_template_filter_entry: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + filter: filter1 + filter_description: "filter description" + entry: filter_entry1 + filter_entry_description: "filter entry description" + state: present + register: add_filter_descr + when: version.current.version is version('3.3', '>=') + +- name: Verify add_filter_only + assert: + that: + - add_filter_descr is changed + - add_filter_descr.current.description == "filter entry description" + when: version.current.version is version('3.3', '>=') + + +- name: Create filter without filter entry + cisco.mso.mso_schema_template_filter_entry: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + filter: filter1 + state: present + ignore_errors: yes + register: add_filter_only + +- name: Verify add_filter_only + assert: + that: + - add_filter_only is not changed + - add_filter_only.msg == "state is present but all of the following are missing{{':'}} entry" + +- name: Create filter with multiple filter entries + cisco.mso.mso_schema_template_filter_entry: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + filter: filter1 + filter_display_name: filter1 + display_name: '{{ item }}' + ethertype: ip + ip_protocol: tcp + tcp_session_rules: + - acknowledgement + - established + source_from: 22 + source_to: 22 + destination_from: 22 + destination_to: 22 + arp_flag: request + stateful: true + fragments_only: false + entry: '{{ item }}' + state: present + register: add_multiple_entries + loop: + - 'filter_entry2' + - 'filter_entry3' + +# QUERY the filters +- name: Query a particular filter entry 1 + cisco.mso.mso_schema_template_filter_entry: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + filter: filter1 + entry: filter_entry1 + state: query + register: query_filter + +- name: Query all filter entries + cisco.mso.mso_schema_template_filter_entry: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + filter: filter1 + state: query + register: query_all + +- name: Verify query + assert: + that: + - query_filter is not changed + - query_all is not changed + +# QUERY cases +- name: Query existing filter and filter entry + cisco.mso.mso_schema_template_filter_entry: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + filter: non_existing_filter + entry: non_existing_filter_entry + state: query + ignore_errors: yes + register: query_non_existing_filter + +- name: Query non-existing filter entry + cisco.mso.mso_schema_template_filter_entry: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + filter: filter1 + entry: non_existing_filter_entry + state: query + ignore_errors: yes + register: query_non_existing_entry + +- name: Verify query cases + assert: + that: + - query_non_existing_filter is not changed + - query_non_existing_entry is not changed + - query_non_existing_entry.msg == "Entry 'non_existing_filter_entry' not found" + +# Delete filter entries +- name: Delete filter entry 3 + cisco.mso.mso_schema_template_filter_entry: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + filter: filter1 + entry: filter_entry3 + state: absent + register: remove_filter + +- name: Verify delete filter_entry3 + assert: + that: + - remove_filter is changed + - remove_filter.current == {} + +# USE A NON_EXISTING_TEMPLATE +- name: non_existing_template (normal_mode) + cisco.mso.mso_schema_template_filter_entry: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: non_existing_template + filter: filter1 + entry: filter_entry1 + state: present + ignore_errors: yes + register: nm_non_existing_template + +- name: Verify nm_non_existing_template + assert: + that: + - nm_non_existing_template is not changed + - nm_non_existing_template.msg == "Provided template 'non_existing_template' does not exist. Existing templates{{':'}} Template1" + +- name: Query non_existing_filter + cisco.mso.mso_schema_template_filter_entry: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + filter: non_existing_filter + state: query + ignore_errors: yes + register: query_non_existing_filter + +- name: Delete non_existing_filter + cisco.mso.mso_schema_template_filter_entry: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + filter: non_existing_filter + entry: filter_entry1 + state: absent + ignore_errors: yes + register: remove_non_existing_filter + +- name: Delete non_existing_filter_entry + cisco.mso.mso_schema_template_filter_entry: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + filter: filter1 + entry: non_existing_filter_entry + state: absent + ignore_errors: yes + register: remove_non_existing_entry + +- name: Verify non_existing + assert: + that: + - query_non_existing_filter is not changed + - query_non_existing_filter.msg == "Filter 'non_existing_filter' not found" + - remove_non_existing_filter is not changed + - remove_non_existing_entry is not changed + - nm_non_existing_template.msg == "Provided template 'non_existing_template' does not exist. Existing templates{{':'}} Template1" + + +# Delete filter entries +- name: Delete filter entry 3 + cisco.mso.mso_schema_template_filter_entry: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + filter: filter1 + entry: '{{ item }}' + state: absent + register: remove_multiple_entries + loop: + - 'filter_entry1' + - 'filter_entry2' + +- name: Verify remove_multiple_entries + assert: + that: + - remove_multiple_entries is changed
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_l3out/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_l3out/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_l3out/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_l3out/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_l3out/tasks/main.yml new file mode 100644 index 00000000..494b1328 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_l3out/tasks/main.yml @@ -0,0 +1,265 @@ +# Test code for the MSO modules +# Copyright: (c) 2021, Anvitha Jain (@anvitha-jain) <anvjain@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") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Remove schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Ensure tenant ansible_test exists + mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + sites: + - '{{ mso_site | default("ansible_test") }}' + state: present + +- name: Ensure schema 1 with Template1, and Template2 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: '{{item.template}}' + state: present + loop: + - { template: Template1} + - { template: Template2} + +- name: Ensure VRF1 exists + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + vrf: VRF1 + state: present + +- name: Verify L3Out doesn't exist + mso_schema_template_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + l3out: L3out1 + state: absent + +- name: Add new L3Out (check_mode) + mso_schema_template_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + l3out: L3out1 + vrf: + name: VRF1 + state: present + check_mode: yes + register: cm_add_l3out + +- name: Add new L3Out (normal mode) + mso_schema_template_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + l3out: L3out1 + vrf: + name: VRF1 + state: present + register: nm_add_l3out + +- name: Add L3Out again + mso_schema_template_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + l3out: L3out1 + vrf: + name: VRF1 + state: present + register: add_l3out_again + +- name: Verify add + assert: + that: + - cm_add_l3out is changed + - cm_add_l3out.previous == {} + - cm_add_l3out.current.name == "L3out1" + - cm_add_l3out.current.vrfRef.templateName == "Template1" + - cm_add_l3out.current.vrfRef.vrfName == "VRF1" + - nm_add_l3out is changed + - nm_add_l3out.previous == {} + - nm_add_l3out.current.name == "L3out1" + - nm_add_l3out.current.vrfRef.templateName == "Template1" + - nm_add_l3out.current.vrfRef.vrfName == "VRF1" + - add_l3out_again is not changed + - add_l3out_again.previous.name == "L3out1" + - nm_add_l3out.current.vrfRef.schemaId == add_l3out_again.current.vrfRef.schemaId + +- name: Add new L3Outs + mso_schema_template_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + l3out: '{{item.l3out}}' + vrf: + name: VRF1 + state: present + register: new_l3outs + loop: + - { l3out: L3out2} + - { l3out: L3out3} + +- name: Verify add + assert: + that: + - new_l3outs is changed + +- name: Query a specific L3Out + mso_schema_template_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + l3out: L3out1 + state: query + register: query_l3out + +- name: Query all L3outs + mso_schema_template_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + state: query + register: query_all + +- name: Verify query + assert: + that: + - query_l3out is not changed + - query_all is not changed + +- name: Remove an L3Out + mso_schema_template_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + l3out: L3out1 + state: absent + register: delete_l3out + +- name: Verify delete + assert: + that: + - delete_l3out is changed + - delete_l3out.previous.name == "L3out1" + - delete_l3out.current == {} + +# USE A NON_EXISTING_TEMPLATE +- name: non_existing_template (check_mode) + mso_schema_template_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: non_existing_template + l3out: L3out2 + vrf: + name: VRF1 + state: query + check_mode: yes + ignore_errors: yes + register: cm_non_existing_template + +- name: non_existing_template (normal_mode) + mso_schema_template_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: non_existing_template + l3out: L3out2 + vrf: + name: VRF1 + state: query + ignore_errors: yes + register: nm_non_existing_template + +- name: Verify cm_non_existing_template and nm_non_existing_template + assert: + that: + - cm_non_existing_template is not changed + - nm_non_existing_template is not changed + - cm_non_existing_template.msg == nm_non_existing_template.msg == "Provided template 'non_existing_template' does not exist. Existing templates{{':'}} Template1, Template2" + +# QUERY NON-EXISTING L3Out +- name: Query non-existing L3Out (check_mode) + mso_schema_template_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + l3out: non_existing_l3out + state: query + check_mode: yes + ignore_errors: yes + register: cm_query_non_l3out + +- name: Query non-existing L3Out (normal_mode) + mso_schema_template_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + l3out: non_existing_l3out + state: query + ignore_errors: yes + register: nm_query_non_l3out + +- name: Verify cm_query_non_l3out and nm_query_non_l3out + assert: + that: + - cm_query_non_l3out is not changed + - nm_query_non_l3out is not changed + - cm_query_non_l3out.msg == nm_query_non_l3out.msg == "L3out 'non_existing_l3out' not found" + +# Add description for version >= 3.3 + +- name: Add new L3Out + mso_schema_template_l3out: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + l3out: L3out1 + description: "A L3out description" + vrf: + name: VRF1 + state: present + register: add_desc + when: version.current.version is version('3.3', '>=') + +- name: Verify add description + assert: + that: + - add_desc is changed + when: version.current.version is version('3.3', '>=')
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_migrate/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_migrate/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_migrate/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_migrate/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_migrate/tasks/main.yml new file mode 100644 index 00000000..36329e08 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_migrate/tasks/main.yml @@ -0,0 +1,383 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Anvitha Jain (@anvitha-jain) <anvjain@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 + +- 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") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +# CLEAN ENVIRONMENT +- name: Ensure site exist + mso_site: &site_present + 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") }}' + site: '{{ mso_site | default("ansible_test") }}' + apic_username: '{{ apic_username }}' + apic_password: '{{ apic_password }}' + apic_site_id: '{{ apic_site_id | default(102) }}' + urls: + - https://{{ apic_hostname }} + state: present + +- name: Undeploy a schema 2 template 2 + mso_schema_template_deploy: + <<: *mso_info + template: Template 2 + schema: '{{ mso_schema | default("ansible_test") }}_2' + site: '{{ mso_site | default("ansible_test") }}' + state: undeploy + ignore_errors: yes + register: undeploy_template2 + +- name: Undeploy a schema 1 template 1 + mso_schema_template_deploy: + <<: *mso_info + template: Template 1 + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + state: undeploy + ignore_errors: yes + register: undeploy_template1 + +- name: Remove a site from a schema 1 with Template 1 + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + state: absent + ignore_errors: yes + register: rm_site_temp1 + +- name: Remove a site from a schema 2 with Template 2 + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 2 + state: absent + ignore_errors: yes + register: rm_site_temp2 + +- name: Remove schemas + mso_schema: + 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") }}' + schema: '{{ item }}' + state: absent + ignore_errors: yes + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Ensure tenant ansible_test exist + mso_tenant: &tenant_present + 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") }}' + tenant: ansible_test + users: + - '{{ mso_username }}' + sites: + - '{{ mso_site | default("ansible_test") }}' + state: present + +- name: Ensure schemas with Template 1 exist + mso_schema_template: &schema_present + 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") }}' + schema: '{{ item }}' + tenant: ansible_test + template: Template 1 + state: present + loop: + - '{{ mso_schema | default("ansible_test") }}' + - '{{ mso_schema | default("ansible_test") }}_2' + +- name: Ensure schema 2 with Template 2 exist + mso_schema_template: + <<: *schema_present + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template 2 + state: present + register: schema2_template2 + +- name: Add a new site to a schema 1 with Template 1 in normal mode + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + state: present + register: add_site_nm1 + +- name: Add a new site to a schema 2 with Template 2 in normal mode + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 2 + state: present + register: add_site_nm2 + +- name: Ensure VRF exist + mso_schema_template_vrf: &vrf_present + 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") }}' + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF + layer3_multicast: true + state: present + +- name: Ensure ANP exist + mso_schema_template_anp: + 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") }}' + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 1 + anp: ANP + state: present + +- name: Ensure ANP2 exist + mso_schema_template_anp: + 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") }}' + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 1 + anp: ANP2 + state: present + +- name: Ensure ansible_test_1 BD exist + mso_schema_template_bd: + <<: *vrf_present + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 1 + bd: '{{ item }}' + vrf: + name: VRF + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + state: present + when: version.current.version is version('2.2.4e', '!=') + loop: + - '{{ BD_1 | default("ansible_test") }}_1' + - '{{ BD_2 | default("ansible_test") }}_2' + +- name: Ensure EPG exist + mso_schema_template_anp_epg: &epg_present + 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") }}' + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 1 + anp: ANP + epg: ansible_test_1 + bd: + name: ansible_test_1 + vrf: + name: VRF + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + state: present + register: cm_add_epg + +- name: Add EPG 2 (normal mode) + mso_schema_template_anp_epg: + <<: *epg_present + anp: ANP2 + epg: '{{ item }}' + loop: + - '{{ EPG_2 | default("ansible_test") }}_2' + - '{{ EPG_3 | default("ansible_test") }}_3' + - '{{ EPG_4 | default("ansible_test") }}_4' + +- name: Migration of objects between templates + mso_schema_template_migrate: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 1 + target_schema: '{{ mso_schema | default("ansible_test") }}' + target_template: Template 1 + bds: + - ansible_test_1 + epgs: + - epg: ansible_test_1 + anp: ANP + - epg: ansible_test_2 + anp: ANP2 + state: present + when: version.current.version is version('2.2.4e', '!=') + register: object_migrate + +- name: Deploy a schema 1 template 1 after version 4.0 + ndo_schema_template_deploy: + <<: *mso_info + template: Template 1 + schema: '{{ mso_schema | default("ansible_test") }}' + sites: + - '{{ mso_site | default("ansible_test") }}' + state: deploy + when: version.current.version is version('4.0', '>=') + +- name: Migration of BD objects between templates + mso_schema_template_migrate: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 1 + target_schema: '{{ mso_schema | default("ansible_test") }}_2' + target_template: Template 2 + bds: + - ansible_test_2 + state: present + when: version.current.version is version('2.2.4e', '!=') + register: bd_migrate + +- name: Deploy a schema 2 template 2 after version 4.0 + ndo_schema_template_deploy: + <<: *mso_info + template: Template 2 + schema: '{{ mso_schema | default("ansible_test") }}_2' + sites: + - '{{ mso_site | default("ansible_test") }}' + state: deploy + when: version.current.version is version('4.0', '>=') + +- name: Migration of EPG objects between templates + mso_schema_template_migrate: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 1 + target_schema: '{{ mso_schema | default("ansible_test") }}_2' + target_template: Template 2 + epgs: + - epg: ansible_test_3 + anp: ANP2 + - epg: ansible_test_4 + anp: ANP2 + state: present + when: version.current.version is version('2.2.4e', '!=') + register: epg_migrate + +- name: Undeploy before 4.0 + when: + - version.current.version is version('4.0', '<') + block: + - name: Undeploy a schema 2 template 2 + mso_schema_template_deploy: + <<: *mso_info + template: Template 2 + schema: '{{ mso_schema | default("ansible_test") }}_2' + site: '{{ mso_site | default("ansible_test") }}' + state: undeploy + ignore_errors: yes + register: undeploy_template2 + + - name: Undeploy a schema 1 template 1 + mso_schema_template_deploy: + <<: *mso_info + template: Template 1 + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + state: undeploy + ignore_errors: yes + register: undeploy_template1 + +- name: Undeploy after 4.0 + when: + - version.current.version is version('4.0', '>=') + block: + - name: Undeploy a schema 2 template 2 + ndo_schema_template_deploy: + <<: *mso_info + template: Template 2 + schema: '{{ mso_schema | default("ansible_test") }}_2' + sites: + - '{{ mso_site | default("ansible_test") }}' + state: undeploy + + - name: Undeploy a schema 1 template 1 + ndo_schema_template_deploy: + <<: *mso_info + template: Template 1 + schema: '{{ mso_schema | default("ansible_test") }}' + sites: + - '{{ mso_site | default("ansible_test") }}' + state: undeploy + +- name: Remove a site from a schema 2 with Template 2 + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 2 + state: absent + register: rm_site_temp2 + +- name: Remove a site from a schema 1 with Template 1 + mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + state: absent + register: rm_site_temp1 diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_service_graph/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_service_graph/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_service_graph/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_service_graph/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_service_graph/tasks/main.yml new file mode 100644 index 00000000..f26090e9 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_service_graph/tasks/main.yml @@ -0,0 +1,396 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Shreyas Srish (@shrsr) <ssrish@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(false) }}' + output_level: '{{ mso_output_level | default("info") }}' + +- name: Remove schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Ensure tenant ansible_test exist + mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + state: present + +- name: Ensure schema 1 with Template 1 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template1 + state: present + +- name: Create a service graph (check mode) + cisco.mso.mso_schema_template_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG1 + display_name: sg + service_nodes: + - type: firewall + - type: load-balancer + - type: other + filter_after_first_node: allow_all + state: present + register: sg1_cm + check_mode: yes + +- name: Verify sg1_cm + assert: + that: + - sg1_cm is changed + - sg1_cm.current.name == "SG1" + - sg1_cm.current.displayName == "sg" + - sg1_cm.current.nodeFilter == "allow-all" + - sg1_cm.current.serviceGraphRef.templateName == "Template1" + - sg1_cm.current.serviceNodes | length == 3 + - sg1_cm.current.serviceNodes.0.name == "firewall" + - sg1_cm.current.serviceNodes.1.name == "load-balancer" + - sg1_cm.current.serviceNodes.2.name == "other" + +- name: Create a service graph (normal mode) + cisco.mso.mso_schema_template_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG1 + display_name: sg + service_nodes: + - type: firewall + - type: load-balancer + - type: other + filter_after_first_node: allow_all + state: present + register: sg1 + +- name: Create service graph again + cisco.mso.mso_schema_template_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG1 + display_name: sg + service_nodes: + - type: firewall + - type: load-balancer + - type: other + filter_after_first_node: allow_all + state: present + register: sg1_again + +- name: Verify sg1 and sg1_again + assert: + that: + - sg1 is changed + - sg1_again is not changed + - sg1.current.name == "SG1" + - sg1.current.displayName == "sg" + - sg1.current.nodeFilter == "allow-all" + - sg1.current.serviceGraphRef.templateName == "Template1" + - sg1.current.serviceNodes | length == 3 + - sg1.current.serviceNodes.0.name == "firewall" + - sg1.current.serviceNodes.1.name == "load-balancer" + - sg1.current.serviceNodes.2.name == "other" + - sg1_again.current.name == "SG1" + - sg1_again.current.displayName == "sg" + - sg1_again.current.nodeFilter == "allow-all" + - sg1_again.current.serviceGraphRef.templateName == "Template1" + - sg1_again.current.serviceNodes | length == 3 + - sg1_again.current.serviceNodes.0.name == "firewall" + - sg1_again.current.serviceNodes.1.name == "load-balancer" + - sg1_again.current.serviceNodes.2.name == "other" + +- name: Create another service graph SG2 + cisco.mso.mso_schema_template_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG2 + display_name: Service_Graph2 + service_nodes: + - type: firewall + - type: load-balancer + filter_after_first_node: filters_from_contract + state: present + register: sg2 + +- name: Verify sg2 + assert: + that: + - sg2 is changed + - sg2.current.name == "SG2" + - sg2.current.displayName == "Service_Graph2" + - sg2.current.nodeFilter == "filters-from-contract" + - sg2.current.serviceGraphRef.templateName == "Template1" + - sg2.current.serviceNodes | length == 2 + - sg2.current.serviceNodes.0.name == "firewall" + - sg2.current.serviceNodes.1.name == "load-balancer" + +- name: Change Service Graph SG2 + cisco.mso.mso_schema_template_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG2 + display_name: Service_Graph_changed + service_nodes: + - type: firewall + - type: load-balancer + filter_after_first_node: filters_from_contract + state: present + register: sg2_change + +- name: Verify sg2_change + assert: + that: + - sg2_change is changed + - sg2_change.current.name == "SG2" + - sg2_change.current.displayName == "Service_Graph_changed" + - sg2_change.current.nodeFilter == "filters-from-contract" + - sg2_change.current.serviceGraphRef.templateName == "Template1" + - sg2_change.current.serviceNodes | length == 2 + - sg2_change.current.serviceNodes.0.name == "firewall" + - sg2_change.current.serviceNodes.1.name == "load-balancer" + +- name: Create another service graph with no display name + cisco.mso.mso_schema_template_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG3 + service_nodes: + - type: firewall + filter_after_first_node: filters_from_contract + state: present + register: sg3 + +- name: Verify sg3 + assert: + that: + - sg3 is changed + - sg3.current.name == "SG3" + - sg3.current.displayName == "SG3" + - sg3.current.nodeFilter == "filters-from-contract" + - sg3.current.serviceGraphRef.templateName == "Template1" + - sg3.current.serviceNodes.0.name == "firewall" + - sg3.current.serviceNodes | length == 1 + +- name: Create service graph SG3 with addition of new service node type + cisco.mso.mso_schema_template_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG3 + service_nodes: + - type: firewall + - type: other + filter_after_first_node: filters_from_contract + state: present + register: sg3_other + +- name: Verify sg3_other + assert: + that: + - sg3_other is changed + - sg3_other.current.name == "SG3" + - sg3_other.current.displayName == "SG3" + - sg3_other.current.nodeFilter == "filters-from-contract" + - sg3_other.current.serviceGraphRef.templateName == "Template1" + - sg3_other.current.serviceNodes.0.name == "firewall" + - sg3_other.current.serviceNodes.1.name == "other" + - sg3_other.current.serviceNodes | length == 2 + +- name: Create service graph SG3 interchanging the index of service node types + cisco.mso.mso_schema_template_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG3 + service_nodes: + - type: other + - type: firewall + filter_after_first_node: filters_from_contract + state: present + register: sg3_interchange + +- name: Verify sg3_interchange + assert: + that: + - sg3_interchange is changed + - sg3_interchange.current.name == "SG3" + - sg3_interchange.current.displayName == "SG3" + - sg3_interchange.current.nodeFilter == "filters-from-contract" + - sg3_interchange.current.serviceGraphRef.templateName == "Template1" + - sg3_interchange.current.serviceNodes.1.name == "firewall" + - sg3_interchange.current.serviceNodes.0.name == "other" + - sg3_interchange.current.serviceNodes | length == 2 + +- name: Create another service graph with non existing node type + cisco.mso.mso_schema_template_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG4 + service_nodes: + - type: non_existing_type + filter_after_first_node: filters_from_contract + state: present + register: sg4 + ignore_errors: yes + +- name: Verify sg4 + assert: + that: + - sg4.msg == "Provided service node type 'non_existing_type' does not exist. Existing node types include{{':'}} firewall, load-balancer, other", + +- name: Query service graph SG + cisco.mso.mso_schema_template_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG1 + state: query + register: query_sg + +- name: Verify query_sg + assert: + that: + - query_sg is not changed + - query_sg.current.name == "SG1" + - query_sg.current.displayName == "sg" + - query_sg.current.nodeFilter == "allow-all" + - query_sg.current.serviceNodes | length == 3 + - query_sg.current.serviceNodes.0.name == "firewall" + - query_sg.current.serviceNodes.1.name == "load-balancer" + - query_sg.current.serviceNodes.2.name == "other" + +- name: Query all service graphs + cisco.mso.mso_schema_template_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + state: query + register: query_all + +- name: Verify query_all + assert: + that: + - query_all is not changed + - query_all.current | length == 3 + +- name: Query non_existing service graph + cisco.mso.mso_schema_template_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + service_graph: non_existent + state: query + ignore_errors: yes + register: query_non_existing_sg + +- name: Verify query_non_existing_sg + assert: + that: + - query_non_existing_sg.msg == "Service Graph 'non_existent' not found" + +- name: Use non_existing schema + cisco.mso.mso_schema_template_service_graph: + <<: *mso_info + schema: non_existing_schema + template: Template1 + service_graph: SG + state: query + ignore_errors: yes + register: query_non_existing_schema + +- name: Use non_existing template + cisco.mso.mso_schema_template_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: non_existing_template + service_graph: SG + state: query + ignore_errors: yes + register: query_non_existing_template + +- name: Verify query_non_existing_schema and query_non_existing_template + assert: + that: + - query_non_existing_schema.msg == "Provided schema 'non_existing_schema' does not exist." + - query_non_existing_template.msg == "Provided template 'non_existing_template' does not exist. Existing templates{{':'}} Template1" + +- name: Remove service graph (check mode) + cisco.mso.mso_schema_template_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG1 + state: absent + register: rm_sg_cm + check_mode: yes + +- name: Verify rm_sg_cm + assert: + that: + - rm_sg_cm is changed + - rm_sg_cm.current == {} + - rm_sg_cm.previous.name == "SG1" + +- name: Remove service graph (normal mode) + cisco.mso.mso_schema_template_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG1 + state: absent + register: rm_sg + +- name: Verify rm_sg + assert: + that: + - rm_sg is changed + - rm_sg.current == {} + - rm_sg.previous.name == "SG1" + +- name: Remove service graph again + cisco.mso.mso_schema_template_service_graph: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + service_graph: SG1 + state: absent + register: rm_sg_again + +- name: Verify rm_sg_again + assert: + that: + - rm_sg_again is not changed + - rm_sg_again.current == {} + - rm_sg_again.previous == {} diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_vrf/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_vrf/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_vrf/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_vrf/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_vrf/tasks/main.yml new file mode 100644 index 00000000..80db663d --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_vrf/tasks/main.yml @@ -0,0 +1,518 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Cindy Zhao (@cizhao) <cizhao@cisco.com> +# Copyright: (c) 2020, Lionel Hercot (@lhercot) <lhercot@cisco.com> +# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> (based on mso_site test case) +# + +# 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") }}' + +# - name: Ensure site exist +# mso_site: &site_present +# 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") }}' +# site: '{{ mso_site | default("ansible_test") }}' +# apic_username: '{{ apic_username }}' +# apic_password: '{{ apic_password }}' +# apic_site_id: '{{ apic_site_id | default(101) }}' +# urls: +# - https://{{ apic_hostname }} +# state: present + +- name: Remove schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Ensure tenant ansible_test exist + mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + # sites: + # - '{{ mso_site | default("ansible_test") }}' + state: present + +- name: Ensure schema 1 with Template 1 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template 1 + state: present + +- name: Ensure schema 1 with Template 2 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template 2 + state: present + +- name: Ensure schema 2 with Template 3 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template 3 + state: present + +- name: Ensure Filter 1 exist + mso_schema_template_filter_entry: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + filter: Filter1 + entry: Filter1-Entry + state: present + +- name: Ensure Contract1 exist + mso_schema_template_contract_filter: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract1 + filter: Filter1 + filter_schema: '{{ mso_schema | default("ansible_test") }}' + filter_template: Template 1 + state: present + +# ADD VRF1 +- name: Add a new VRF1 (check mode) + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF1 + state: present + check_mode: yes + register: vrf1_cm + +- name: Verify vrf1_cm + assert: + that: + - vrf1_cm is changed + - vrf1_cm.current.name == 'VRF1' + - vrf1_cm.current.displayName == 'VRF1' + +- name: Add VRF1 (normal mode) + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF1 + state: present + register: vrf1_nm + +- name: Verify vrf1_nm + assert: + that: + - vrf1_nm is changed + - vrf1_nm.current.name == 'VRF1' + - vrf1_nm.current.displayName == 'VRF1' + +- name: Add VRF2 (normal mode) + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + vrf: VRF2 + layer3_multicast: true + vzany: true + state: present + register: vrf2_nm + +- name: Verify vrf2_nm + assert: + that: + - vrf2_nm is changed + - vrf2_nm.current.name == 'VRF2' + - vrf2_nm.current.displayName == 'VRF2' + - vrf2_nm.current.vzAnyEnabled == True + - vrf2_nm.current.l3MCast == True + +- name: Add VRF3 (normal mode) + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + vrf: VRF3 + state: present + register: vrf3_nm + +- name: Verify vrf3_nm + assert: + that: + - vrf3_nm is changed + - vrf3_nm.current.name == 'VRF3' + - vrf3_nm.current.displayName == 'VRF3' + +# ADD EXISTING VRF +- name: Add VRF2 again (normal mode) + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + vrf: VRF2 + layer3_multicast: true + vzany: true + state: present + register: vrf2_nm_again + +- name: Verify vrf2_nm_again + assert: + that: + - vrf2_nm_again is not changed + +# ADD VRF4 WITH NO STATE +- name: Add VRF4 (normal mode) + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + vrf: VRF4 + ignore_errors: yes + register: vrf4_nm_stateless + +- name: Verify vrf4_nm_stateless + assert: + that: + - vrf4_nm_stateless is changed + +# CHANGE VRF SETTINGS +- name: Change VRF1 settings (check mode) + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF1 + layer3_multicast: true + vzany: true + state: present + check_mode: yes + register: vrf1_change_cm + +- name: Change VRF1 settings (normal mode) + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF1 + layer3_multicast: true + vzany: true + state: present + register: vrf1_change_nm + +- name: Change VRF2 settings (check mode) + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + vrf: VRF2 + layer3_multicast: false + vzany: false + state: present + check_mode: yes + register: vrf2_change_cm + +- name: Change VRF2 settings (normal mode) + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + vrf: VRF2 + layer3_multicast: false + vzany: false + state: present + register: vrf2_change_nm + +- name: Verify vrf2_nm + assert: + that: + - vrf1_change_cm is changed + - vrf1_change_nm is changed + - vrf2_change_cm is changed + - vrf2_change_nm is changed + - vrf1_change_cm.current.name == vrf1_change_nm.current.name == 'VRF1' + - vrf2_change_cm.current.name == vrf2_change_nm.current.name == 'VRF2' + - vrf1_change_cm.current.vzAnyEnabled == vrf1_change_nm.current.vzAnyEnabled == True + - vrf1_change_cm.current.vzAnyEnabled == vrf1_change_nm.current.l3MCast == True + - vrf2_change_cm.current.vzAnyEnabled == vrf2_change_nm.current.vzAnyEnabled == False + - vrf2_change_cm.current.vzAnyEnabled == vrf2_change_nm.current.l3MCast == False + +# QUERY A VRF +- name: Query VRF2 (normal mode) + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + vrf: VRF2 + state: query + register: vrf2_query + +- name: Verify vrf2_query + assert: + that: + - vrf2_query is not changed + +# QUERY ALL VRFs +- name: Query all (normal mode) + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + state: query + register: vrfs_query + +- name: Verify vrfs_query + assert: + that: + - vrfs_query is not changed + +# REMOVE A VRF +- name: Remove VRF3 (normal mode) + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + vrf: VRF3 + state: absent + register: vrf3_remove + +- name: Verify vrf3_remove + assert: + that: + - vrf3_remove is changed + - vrf3_remove.previous.name == 'VRF3' + - vrf3_remove.previous.displayName == 'VRF3' + +# REMOVE A VRF +- name: Remove VRF3 again (normal mode) + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + vrf: VRF3 + state: absent + register: vrf3_remove_again + +- name: Verify vrf3_remove_again + assert: + that: + - vrf3_remove_again is not changed + +# QUERY REMOVED VRF +- name: Query VRF3 (normal mode) + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + vrf: VRF3 + state: query + ignore_errors: yes + register: vrf3_query_removed + +- name: Verify vrf3_query_removed + assert: + that: + - vrf3_query_removed.msg == "VRF 'VRF3' not found" + +# Enable vzAny on VRF +- name: Ensure VRF exist + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF + vzany: true + state: present + +- name: Add Contract1 to VRF with type consumer (normal_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF + contract: + name: Contract1 + type: consumer + state: present + register: nm_add_contract1_consumer + +- name: Verify nm_add_contract1_consumer + assert: + that: + - nm_add_contract1_consumer is changed + - nm_add_contract1_consumer.previous == {} + - nm_add_contract1_consumer.current.contractRef.templateName == "Template1" + - nm_add_contract1_consumer.current.contractRef.contractName == "Contract1" + - nm_add_contract1_consumer.current.relationshipType == "consumer" + +- name: Add Contract1 to VRF with type provider (normal_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF + contract: + name: Contract1 + type: provider + state: present + register: nm_add_contract1_provider + +- name: Verify nm_add_contract1_provider + assert: + that: + - nm_add_contract1_provider is changed + - nm_add_contract1_provider.previous == {} + - nm_add_contract1_provider.current.contractRef.templateName == "Template1" + - nm_add_contract1_provider.current.contractRef.contractName == "Contract1" + - nm_add_contract1_provider.current.relationshipType == "provider" + +# USE A NON-EXISTING SCHEMA +- name: Non-existing schema for VRF (check_mode) + mso_schema_template_vrf: + <<: *mso_info + schema: non_existing_schema + template: Template 1 + vrf: VRF5 + check_mode: yes + ignore_errors: yes + register: cm_non_existing_schema + +- name: Non-existing schema for VRF (normal_mode) + mso_schema_template_vrf: + <<: *mso_info + schema: non_existing_schema + template: Template 1 + vrf: VRF5 + ignore_errors: yes + register: nm_non_existing_schema + +- name: Verify nm_non_existing_schema + assert: + that: + - cm_non_existing_schema is not changed + - nm_non_existing_schema is not changed + - cm_non_existing_schema == nm_non_existing_schema + - cm_non_existing_schema.msg == nm_non_existing_schema.msg == "Provided schema 'non_existing_schema' does not exist." + +# USE A NON-EXISTING TEMPLATE +- name: Non-existing template for vrf (check_mode) + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: non_existing_template + vrf: VRF5 + check_mode: yes + ignore_errors: yes + register: cm_non_existing_template + +- name: Non-existing template for vrf (normal_mode) + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: non_existing_template + vrf: VRF5 + ignore_errors: yes + register: nm_non_existing_template + +- name: Verify non_existing_template + assert: + that: + - cm_non_existing_template is not changed + - nm_non_existing_template is not changed + - cm_non_existing_template == nm_non_existing_template + - cm_non_existing_template.msg == nm_non_existing_template.msg == "Provided template 'non_existing_template' does not exist. Existing templates{{':'}} Template1, Template2" + +# Checking if contract are removed after re-applying an VRF. +- name: Add VRF again (normal_mode) + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF + vzany: true + state: present + register: nm_add_VRF_again + +- name: Verify that VRF didn't changed + assert: + that: + - nm_add_VRF_again is not changed + +- name: Verify contract VRF again + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF + state: query + register: nm_query_vrf_contract_again + +- name: Verify 2 contracts are in VRF + assert: + that: + - nm_query_vrf_contract_again is not changed + - nm_query_vrf_contract_again.current | length == 2 + +# Checking if modifying VRF with existing contracts throw an MSO error. (#82) +- name: Change VRF (normal_mode) + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF + vzany: true + layer3_multicast: true + state: present + register: nm_change_vrf + +- name: Verify that VRF did change + assert: + that: + - nm_change_vrf is changed + - nm_change_vrf.current.name == "VRF" + - nm_change_vrf.current.l3MCast == True + +- name: Verify contract VRF again + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF + state: query + register: nm_query_change_vrf_contract_again + +- name: Verify 2 contracts are in VRF + assert: + that: + - nm_query_change_vrf_contract_again is not changed + - nm_query_change_vrf_contract_again.current | length == 2
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_vrf_contract/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_vrf_contract/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_vrf_contract/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_vrf_contract/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_vrf_contract/tasks/main.yml new file mode 100644 index 00000000..e57fedd5 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_template_vrf_contract/tasks/main.yml @@ -0,0 +1,859 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Cindy Zhao (@cizhao) <cizhao@cisco.com> +# Copyright: (c) 2020, Lionel Hercot (@lhercot) <lhercot@cisco.com> +# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> (based on mso_site test case) +# + +# 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") }}' + +# - name: Ensure site exist +# mso_site: &site_present +# 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") }}' +# site: '{{ mso_site | default("ansible_test") }}' +# apic_username: '{{ apic_username }}' +# apic_password: '{{ apic_password }}' +# apic_site_id: '{{ apic_site_id | default(101) }}' +# urls: +# - https://{{ apic_hostname }} +# state: present + +- name: Remove schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Ensure tenant ansible_test exist + mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + # sites: + # - '{{ mso_site | default("ansible_test") }}' + state: present + +- name: Ensure schema 1 with Template 1 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template 1 + state: present + +- name: Ensure schema 1 with Template 2 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template 2 + state: present + +- name: Ensure schema 2 with Template 3 exist + mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template 3 + state: present + +- name: Ensure VRF exist + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF + state: present + +- name: Ensure VRF2 exist + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF2 + vzany: true + state: present + +- name: Ensure VRF3 exist + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + vrf: VRF3 + vzany: true + state: present + +- name: Ensure VRF4 exist + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + vrf: VRF4 + vzany: true + state: present + +- name: Ensure Filter 1 exist + mso_schema_template_filter_entry: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + filter: Filter1 + entry: Filter1-Entry + state: present + +- name: Ensure Contract1 exist + mso_schema_template_contract_filter: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract1 + filter: Filter1 + filter_schema: '{{ mso_schema | default("ansible_test") }}' + filter_template: Template 1 + state: present + +- name: Ensure Contract4 exist + mso_schema_template_contract_filter: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract4 + filter: Filter1 + filter_schema: '{{ mso_schema | default("ansible_test") }}' + filter_template: Template 1 + state: present + +- name: Ensure Contract2 exist + mso_schema_template_contract_filter: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract2 + filter: Filter1 + filter_schema: '{{ mso_schema | default("ansible_test") }}' + filter_template: Template 1 + state: present + +- name: Ensure Contract3 exist + mso_schema_template_contract_filter: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + contract: Contract3 + filter: Filter1 + filter_schema: '{{ mso_schema | default("ansible_test") }}' + filter_template: Template 1 + state: present + +# ADD Contract to VRF +- name: Add Contract1 to VRF with vzany disabled + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF + contract: + name: Contract1 + type: consumer + state: present + ignore_errors: yes + register: add_contract1_vrf_vzany_disabled + +- name: Verify add_contract1_vrf_vzany_disabled + assert: + that: + - add_contract1_vrf_vzany_disabled.msg == "vzAny attribute on vrf 'VRF' is disabled." + +# Enable vzAny on VRF +- name: Ensure VRF exist + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF + vzany: true + state: present + +- name: Add Contract1 to VRF with type consumer (check_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF + contract: + name: Contract1 + type: consumer + state: present + check_mode: yes + register: cm_add_contract1_consumer + +- name: Verify cm_add_contract1_consumer + assert: + that: + - cm_add_contract1_consumer is changed + - cm_add_contract1_consumer.previous == {} + - cm_add_contract1_consumer.current.contractRef.templateName == "Template1" + - cm_add_contract1_consumer.current.contractRef.contractName == "Contract1" + - cm_add_contract1_consumer.current.relationshipType == "consumer" + +- name: Add Contract1 to VRF with type consumer (normal_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF + contract: + name: Contract1 + type: consumer + state: present + register: nm_add_contract1_consumer + +- name: Verify nm_add_contract1_consumer + assert: + that: + - nm_add_contract1_consumer is changed + - nm_add_contract1_consumer.previous == {} + - nm_add_contract1_consumer.current.contractRef.templateName == "Template1" + - nm_add_contract1_consumer.current.contractRef.contractName == "Contract1" + - nm_add_contract1_consumer.current.relationshipType == "consumer" + - cm_add_contract1_consumer.current.contractRef.schemaId == nm_add_contract1_consumer.current.contractRef.schemaId + +- name: Add Contract1 to VRF with type provider (normal_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF + contract: + name: Contract1 + type: provider + state: present + register: nm_add_contract1_provider + +- name: Verify nm_add_contract1_provider + assert: + that: + - nm_add_contract1_provider is changed + - nm_add_contract1_provider.previous == {} + - nm_add_contract1_provider.current.contractRef.templateName == "Template1" + - nm_add_contract1_provider.current.contractRef.contractName == "Contract1" + - nm_add_contract1_provider.current.relationshipType == "provider" + +- name: Add Contract1 to VRF with type consumer again(normal_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF + contract: + name: Contract1 + type: consumer + state: present + register: nm_add_contract1_consumer_again + +- name: Verify nm_add_contract1_consumer_again + assert: + that: + - nm_add_contract1_consumer_again is not changed + - nm_add_contract1_consumer_again.current.contractRef.templateName == "Template1" == nm_add_contract1_consumer_again.previous.contractRef.templateName + - nm_add_contract1_consumer_again.current.contractRef.contractName == "Contract1" == nm_add_contract1_consumer_again.previous.contractRef.contractName + - nm_add_contract1_consumer_again.current.relationshipType == "consumer" == nm_add_contract1_consumer_again.previous.relationshipType + +- name: Add Contract1 to VRF with type provider again(normal_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF + contract: + name: Contract1 + type: provider + state: present + register: nm_add_contract1_provider_again + +- name: Verify nm_add_contract1_provider_again + assert: + that: + - nm_add_contract1_provider_again is not changed + - nm_add_contract1_provider_again.current.contractRef.templateName == "Template1" == nm_add_contract1_provider_again.previous.contractRef.templateName + - nm_add_contract1_provider_again.current.contractRef.contractName == "Contract1" == nm_add_contract1_provider_again.previous.contractRef.contractName + - nm_add_contract1_provider_again.current.relationshipType == "provider" == nm_add_contract1_provider_again.previous.relationshipType + +- name: Add Contract4 to VRF2 with type consumer (normal_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF2 + contract: + name: Contract4 + type: consumer + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + state: present + register: nm_add_vrf2_consumer + +- name: Add Contract4 to VRF2 with type provider (normal_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF2 + contract: + name: Contract4 + type: provider + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + state: present + register: nm_add_vrf2_provider + +- name: nm_add_vrf2_consumer and nm_add_vrf2_provider + assert: + that: + - nm_add_vrf2_consumer is changed + - nm_add_vrf2_provider is changed + - nm_add_vrf2_consumer.previous == {} == nm_add_vrf2_provider.previous + - nm_add_vrf2_consumer.current.contractRef.templateName == "Template1" == nm_add_vrf2_provider.current.contractRef.templateName + - nm_add_vrf2_consumer.current.contractRef.contractName == "Contract4" == nm_add_vrf2_provider.current.contractRef.contractName + - nm_add_vrf2_consumer.current.relationshipType == "consumer" + - nm_add_vrf2_provider.current.relationshipType == "provider" + +- name: Add Contract3 to VRF3 with type consumer (normal_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + vrf: VRF3 + contract: + name: Contract3 + type: consumer + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + state: present + register: nm_add_vrf3_consumer + +- name: Add Contract3 to VRF3 with type provider (normal_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + vrf: VRF3 + contract: + name: Contract3 + type: provider + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + state: present + register: nm_add_vrf3_provider + +- name: nm_add_vrf3_consumer and nm_add_vrf3_provider + assert: + that: + - nm_add_vrf3_consumer is changed + - nm_add_vrf3_provider is changed + - nm_add_vrf3_consumer.previous == {} == nm_add_vrf3_provider.previous + - nm_add_vrf3_consumer.current.contractRef.templateName == "Template1" == nm_add_vrf3_provider.current.contractRef.templateName + - nm_add_vrf3_consumer.current.contractRef.contractName == "Contract3" == nm_add_vrf3_provider.current.contractRef.contractName + - nm_add_vrf3_consumer.current.relationshipType == "consumer" + - nm_add_vrf3_provider.current.relationshipType == "provider" + +- name: Add Contract2 to VRF4 with type consumer (normal_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + vrf: VRF4 + contract: + name: Contract2 + type: consumer + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + state: present + register: nm_add_vrf4_consumer + +- name: Add Contract2 to VRF4 with type provider (normal_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 3 + vrf: VRF4 + contract: + name: Contract2 + type: provider + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + state: present + register: nm_add_vrf4_provider + +- name: nm_add_vrf4_consumer and nm_add_vrf4_provider + assert: + that: + - nm_add_vrf4_consumer is changed + - nm_add_vrf4_provider is changed + - nm_add_vrf4_consumer.previous == {} == nm_add_vrf4_provider.previous + - nm_add_vrf4_consumer.current.contractRef.templateName == "Template1" == nm_add_vrf4_provider.current.contractRef.templateName + - nm_add_vrf4_consumer.current.contractRef.contractName == "Contract2" == nm_add_vrf4_provider.current.contractRef.contractName + - nm_add_vrf4_consumer.current.relationshipType == "consumer" + - nm_add_vrf4_provider.current.relationshipType == "provider" + +# REMOVE A Contract to VRF +- name: Remove contract4 to VRF2 - provider (check_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF2 + contract: + name: Contract4 + type: provider + state: absent + check_mode: yes + register: cm_remove_contract4_vrf2_provider + +- name: Remove contract4 to VRF2 - provider (normal_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF2 + contract: + name: Contract4 + type: provider + state: absent + register: nm_remove_contract4_vrf2_provider + +- name: Remove contract4 to VRF2 - consumer (normal_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF2 + contract: + name: Contract4 + type: consumer + state: absent + register: nm_remove_contract4_vrf2_consumer + +- name: Verify cm_remove_contract4_vrf2_provider and cm_remove_contract4_vrf2_provider and nm_remove_contract4_vrf2_consumer + assert: + that: + - cm_remove_contract4_vrf2_provider is changed + - nm_remove_contract4_vrf2_provider is changed + - cm_remove_contract4_vrf2_provider.current == {} + - nm_remove_contract4_vrf2_provider.current == {} + - nm_remove_contract4_vrf2_consumer.current == {} + - cm_remove_contract4_vrf2_provider.previous.contractRef.contractName == nm_remove_contract4_vrf2_provider.previous.contractRef.contractName == nm_remove_contract4_vrf2_consumer.previous.contractRef.contractName == "Contract4" + - cm_remove_contract4_vrf2_provider.previous.contractRef.templateName == nm_remove_contract4_vrf2_provider.previous.contractRef.templateName == nm_remove_contract4_vrf2_consumer.previous.contractRef.templateName == "Template1" + - cm_remove_contract4_vrf2_provider.previous.contractRef.schemaId == nm_remove_contract4_vrf2_provider.previous.contractRef.schemaId == nm_remove_contract4_vrf2_consumer.previous.contractRef.schemaId + - cm_remove_contract4_vrf2_provider.previous.relationshipType == "provider" + - nm_remove_contract4_vrf2_provider.previous.relationshipType == "provider" + - nm_remove_contract4_vrf2_consumer is changed + - nm_remove_contract4_vrf2_consumer.previous.relationshipType == "consumer" + +- name: Remove contract4 to VRF2 - provider again (normal_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF2 + contract: + name: Contract4 + type: provider + state: absent + register: nm_remove_contract4_vrf2_provider_again + +- name: Verify nm_remove_contract4_vrf2_provider_again + assert: + that: + - nm_remove_contract4_vrf2_provider_again is not changed + - nm_remove_contract4_vrf2_provider_again.previous == {} + - nm_remove_contract4_vrf2_provider_again.current == {} + +# QUERY A Contract to VRF +- name: Query Contract1 relationship for VRF - consumer (check_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF + contract: + name: Contract1 + type: consumer + state: query + check_mode: yes + register: cm_query_VRF_contract1_consumer + +- name: Query Contract1 relationship for VRF - consumer (normal_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF + contract: + name: Contract1 + type: consumer + state: query + check_mode: yes + register: nm_query_VRF_contract1_consumer + +- name: Verify cm_query_VRF_contract1_consumer and nm_query_VRF_contract1_consumer + assert: + that: + - cm_query_VRF_contract1_consumer is not changed + - nm_query_VRF_contract1_consumer is not changed + - cm_query_VRF_contract1_consumer.current.relationshipType == nm_query_VRF_contract1_consumer.current.relationshipType == "consumer" + - cm_query_VRF_contract1_consumer.current.contractRef.contractName == nm_query_VRF_contract1_consumer.current.contractRef.contractName == "Contract1" + - cm_query_VRF_contract1_consumer.current.contractRef.schemaId == nm_query_VRF_contract1_consumer.current.contractRef.schemaId + - cm_query_VRF_contract1_consumer.current.contractRef.templateName == nm_query_VRF_contract1_consumer.current.contractRef.templateName == "Template1" + +- name: Query Contract1 relationship for VRF - provider (check_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF + contract: + name: Contract1 + type: provider + state: query + check_mode: yes + register: cm_query_VRF_contract1_provider + +- name: Query Contract1 relationship for VRF - provider (normal_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF + contract: + name: Contract1 + type: provider + state: query + check_mode: yes + register: nm_query_VRF_contract1_provider + +- name: Verify cm_query_VRF_contract1_provider and nm_query_VRF_contract1_provider + assert: + that: + - cm_query_VRF_contract1_provider is not changed + - nm_query_VRF_contract1_provider is not changed + - cm_query_VRF_contract1_provider.current.relationshipType == nm_query_VRF_contract1_provider.current.relationshipType == "provider" + - cm_query_VRF_contract1_provider.current.contractRef.contractName == nm_query_VRF_contract1_provider.current.contractRef.contractName == "Contract1" + - cm_query_VRF_contract1_provider.current.contractRef.schemaId == nm_query_VRF_contract1_provider.current.contractRef.schemaId + - cm_query_VRF_contract1_provider.current.contractRef.templateName == nm_query_VRF_contract1_provider.current.contractRef.templateName == "Template1" + +# QUERY ALL Contract to VRF +- name: Query all contracts relationship for VRF (check_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF + state: query + check_mode: yes + register: cm_query_all_contract_vrf + +- name: Query all contracts relationship for VRF (normal_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF + state: query + register: nm_query_all_contract_vrf + +- name: Verify cm_query_all_contract_vrf and nm_query_all_contract_vrf + assert: + that: + - nm_query_all_contract_vrf is not changed + - cm_query_all_contract_vrf is not changed + - cm_query_all_contract_vrf.current | length == nm_query_all_contract_vrf.current | length == 2 + +# QUERY ALL Contracts to VRF2 +- name: Query all contracts relationship for VRF2 (check_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF2 + state: query + check_mode: yes + register: cm_query_all_contract_vrf2 + +- name: Query all contracts relationship for VRF2 (normal_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF2 + state: query + register: nm_query_all_contract_vrf2 + +- name: Verify cm_query_all_contract_vrf2 and nm_query_all_contract_vrf2 + assert: + that: + - nm_query_all_contract_vrf2 is not changed + - cm_query_all_contract_vrf2 is not changed + - cm_query_all_contract_vrf2.current == nm_query_all_contract_vrf2.current == [] + +# QUERY NON-EXISTING Contract to VRF +- name: Query non-existing contract (check_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF + contract: + name: non_existing_contract + type: provider + state: query + check_mode: yes + ignore_errors: yes + register: cm_query_non_existing_contract + +- name: Query non-existing contract (normal_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF + contract: + name: non_existing_contract + type: provider + state: query + ignore_errors: yes + register: nm_query_non_existing_contract + +- name: Verify cm_query_non_existing_contract and nm_query_non_existing_contract + assert: + that: + - cm_query_non_existing_contract is not changed + - nm_query_non_existing_contract is not changed + - cm_query_non_existing_contract == nm_query_non_existing_contract + - cm_query_non_existing_contract.msg == "Contract 'non_existing_contract' not found" + - nm_query_non_existing_contract.msg == "Contract 'non_existing_contract' not found" + +# QUERY NON-EXISTING VRF +- name: Query non-existing VRF (check_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: non_existing_vrf + state: query + check_mode: yes + ignore_errors: yes + register: cm_query_non_existing_vrf + +- name: Query non-existing VRF (normal_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: non_existing_vrf + state: query + ignore_errors: yes + register: nm_query_non_existing_vrf + +- name: Verify cm_query_non_existing_vrf and nm_query_non_existing_vrf + assert: + that: + - cm_query_non_existing_vrf is not changed + - nm_query_non_existing_vrf is not changed + - cm_query_non_existing_vrf == nm_query_non_existing_vrf + - cm_query_non_existing_vrf.msg == "Provided vrf 'non_existing_vrf' does not exist. Existing vrfs{{':'}} VRF, VRF2" + - nm_query_non_existing_vrf.msg == "Provided vrf 'non_existing_vrf' does not exist. Existing vrfs{{':'}} VRF, VRF2" + +# USE A NON-EXISTING SCHEMA +- name: Non-existing schema for contract relationship (check_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: non_existing_schema + template: Template 1 + vrf: VRF + state: query + check_mode: yes + ignore_errors: yes + register: cm_query_non_existing_schema + +- name: Non-existing schema for contract relationship (normal_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: non_existing_schema + template: Template 1 + vrf: VRF + state: query + ignore_errors: yes + register: nm_query_non_existing_schema + +- name: Verify cm_query_non_existing_schema and nm_query_non_existing_schema + assert: + that: + - cm_query_non_existing_schema is not changed + - nm_query_non_existing_schema is not changed + - cm_query_non_existing_schema.msg == "Provided schema 'non_existing_schema' does not exist." + - nm_query_non_existing_schema.msg == "Provided schema 'non_existing_schema' does not exist." + +- name: Non-existing contract schema for contract relationship (check_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF + contract: + name: Contract1 + type: provider + schema: non_existing_schema + state: query + check_mode: yes + ignore_errors: yes + register: cm_query_non_existing_contract_schema + +- name: Non-existing schema for contract relationship (normal_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF + contract: + name: Contract1 + type: provider + schema: non_existing_schema + state: query + ignore_errors: yes + register: nm_query_non_existing_contract_schema + +- name: Verify cm_query_non_existing_contract_schema and nm_query_non_existing_contract_schema + assert: + that: + - cm_query_non_existing_contract_schema is not changed + - nm_query_non_existing_contract_schema is not changed + - cm_query_non_existing_contract_schema.msg == "Provided schema 'non_existing_schema' does not exist." + - nm_query_non_existing_contract_schema.msg == "Provided schema 'non_existing_schema' does not exist." + +# USE A NON-EXISTING TEMPLATE +- name: Non-existing templateName for contract relationship (check_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: non_existing_template + vrf: VRF + state: query + check_mode: yes + ignore_errors: yes + register: cm_query_non_existing_template + +- name: Non-existing templateName for contract relationship (normal_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: non_existing_template + vrf: VRF + state: query + ignore_errors: yes + register: nm_query_non_existing_template + +- name: Verify cm_query_non_existing_template and nm_query_non_existing_template + assert: + that: + - cm_query_non_existing_template is not changed + - nm_query_non_existing_template is not changed + - cm_query_non_existing_template.msg == "Provided template 'non_existing_template' does not exist. Existing templates{{':'}} Template1, Template2" + - nm_query_non_existing_template.msg == "Provided template 'non_existing_template' does not exist. Existing templates{{':'}} Template1, Template2" + +- name: Non-existing contract templateName for contract relationship (check_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF + contract: + name: Contract1 + type: provider + schema: '{{ mso_schema | default("ansible_test") }}' + template: non_existing_template + state: query + check_mode: yes + ignore_errors: yes + register: cm_query_non_existing_contract_template + +- name: Non-existing contract templateName for contract relationship (normal_mode) + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF + contract: + name: Contract1 + type: provider + schema: '{{ mso_schema | default("ansible_test") }}' + template: non_existing_template + state: query + ignore_errors: yes + register: nm_query_non_existing_contract_template + +- name: Verify cm_query_non_existing_contract_template and nm_query_non_existing_contract_template + assert: + that: + - cm_query_non_existing_contract_template is not changed + - nm_query_non_existing_contract_template is not changed + - cm_query_non_existing_contract_template.msg == "Contract 'Contract1' not found" + - nm_query_non_existing_contract_template.msg == "Contract 'Contract1' not found" + +# Checking if contract are removed after re-applying an VRF. +- name: Add VRF again (normal_mode) + mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF + vzany: true + state: present + register: nm_add_VRF_again + +- name: Verify that VRF didn't changed + assert: + that: + - nm_add_VRF_again is not changed + +- name: Verify contract VRF again + mso_schema_template_vrf_contract: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF + state: query + register: nm_query_vrf_contract_again + +- name: Verify 2 contracts are in VRF + assert: + that: + - nm_query_vrf_contract_again is not changed + - nm_query_vrf_contract_again.current | length == 2
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_validate/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_validate/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_validate/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_validate/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_validate/tasks/main.yml new file mode 100644 index 00000000..73feea20 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_schema_validate/tasks/main.yml @@ -0,0 +1,251 @@ +# Test code for the MSO modules +# Copyright: (c) 2021, Anvitha Jain (@anvitha-jain) <anvjain@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 + ansible.builtin.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") }}' + +- name: Query MSO version + cisco.mso.mso_version: + <<: *mso_info + state: query + register: version + +- name: Ensure site exist + cisco.mso.mso_site: + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + apic_username: '{{ apic_username }}' + apic_password: '{{ apic_password }}' + apic_site_id: '{{ apic_site_id | default(101) }}' + urls: + - https://{{ apic_hostname }} + state: present + +- name: Undeploy template from Schema 1 + cisco.mso.mso_schema_template_deploy: + <<: *mso_info + schema: ansible_test + template: Template 1 + site: '{{ mso_site | default("ansible_test") }}' + state: undeploy + ignore_errors: yes + +- name: Undeploy template from Schema 1 + cisco.mso.ndo_schema_template_deploy: + <<: *mso_info + schema: ansible_test + template: Template 1 + sites: + - '{{ mso_site | default("ansible_test") }}' + state: undeploy + ignore_errors: yes + +- name: Remove schemas + cisco.mso.mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Ensure tenant ansible_test exists + cisco.mso.mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + sites: + - '{{ mso_site | default("ansible_test") }}' + state: present + +# Validate schema when MSO version >= 3.3 +- name: Execute tasks only for MSO version >= 3.3 + when: version.current.version is version('3.3', '>=') + block: + - name: Ensure schema 1 with Template 1 exist + cisco.mso.mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: Template 1 + state: present + + - name: Ensure VRF exist + cisco.mso.mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + vrf: VRF_1 + state: present + + - name: Add bd + cisco.mso.mso_schema_template_bd: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template1 + bd: BD_1 + vrf: + name: VRF_1 + state: present + + - name: Get Validation status + cisco.mso.mso_schema_validate: + <<: *mso_info + schema: ansible_test + state: query + register: query_validate + + - name: Verify query_validate for NDO 4.1 and higher + ansible.builtin.assert: + that: + - query_validate is not changed + - query_validate.current.result == true + when: version.current.version is version('4.0', '>=') + + - name: Verify query_validate + ansible.builtin.assert: + that: + - query_validate is not changed + - query_validate.current.result == "true" + when: version.current.version is version('4.0', '<') + + - name: Add physical site to a schema + cisco.mso.mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: Template 1 + state: present + + - name: Get Validation status + cisco.mso.mso_schema_validate: + <<: *mso_info + schema: ansible_test + state: query + register: query_validate_again + + - name: Verify query_validate_again for NDO 4.1 and higher + ansible.builtin.assert: + that: + - query_validate_again is not changed + - query_validate_again.current.result == true + when: version.current.version is version('4.0', '>=') + + - name: Verify query_validate_again for NDO 3.7 and lower + ansible.builtin.assert: + that: + - query_validate_again is not changed + - query_validate_again.current.result == "true" + when: version.current.version is version('4.0', '<') + + - name: Deploy templates for NDO 3.7 and lower (normal_mode) + cisco.mso.mso_schema_template_deploy: + <<: *mso_info + schema: ansible_test + template: Template 1 + site: '{{ mso_site | default("ansible_test") }}' + state: deploy + register: nm_deploy_template_37 + when: version.current.version is version('4.0', '<') + + - name: Deploy templates for NDO 4.1 and higher (normal_mode) + cisco.mso.ndo_schema_template_deploy: + <<: *mso_info + schema: ansible_test + template: Template 1 + sites: + - '{{ mso_site | default("ansible_test") }}' + state: deploy + register: nm_deploy_template_40 + when: version.current.version is version('4.0', '>=') + + - name: Verify nm_deploy_template for NDO 3.7 and lower + ansible.builtin.assert: + that: + - nm_deploy_template_37 is not changed + - nm_deploy_template_37.msg == "Successfully deployed" + when: version.current.version is version('4.0', '<') + + - name: Verify nm_deploy_template for NDO 4.1 and higher + ansible.builtin.assert: + that: + - '"deploy" in nm_deploy_template_40.current.reqDetails' + when: version.current.version is version('4.0', '>=') + + - name: Ensure schema 2 with Template 2 exist + cisco.mso.mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + tenant: ansible_test + template: Template 2 + state: present + + - name: Ensure VRF exist + cisco.mso.mso_schema_template_vrf: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}_2' + template: Template 2 + vrf: VRF_2 + layer3_multicast: true + vzany: true + state: present + + - name: Get Validation status + cisco.mso.mso_schema_validate: + <<: *mso_info + schema: ansible_test_2 + state: query + ignore_errors: yes + register: query_validate_2 + + - name: Verify query_validate_2 for NDO 4.1 and higher + ansible.builtin.assert: + that: + - query_validate_2 is not changed + - query_validate_2.msg == "MSO Error 400{{':'}} VRF{{':'}} VRF_2 in Schema{{':'}} ansible_test_2 , Template{{':'}} Template2 has VzAnyEnabled flag enabled but is not consuming or providing contracts" + when: version.current.version is version('4.0', '>=') + + - name: Verify query_validate_2 for NDO 3.7 and lower + ansible.builtin.assert: + that: + - query_validate_2 is not changed + - query_validate_2.msg == "MSO Error 400{{':'}} Bad Request{{':'}} Patch Failed, Received{{':'}} vzAny contract must be configured if vzAny flag is set. VRF(s) {{':'}} VRF_2 exception while trying to update schema" + when: version.current.version is version('4.0', '<') + + always: + - name: Undeploy template from Schema 1 + cisco.mso.mso_schema_template_deploy: + <<: *mso_info + schema: ansible_test + template: Template 1 + site: '{{ mso_site | default("ansible_test") }}' + state: undeploy + ignore_errors: yes + + - name: Undeploy template from Schema 1 + cisco.mso.ndo_schema_template_deploy: + <<: *mso_info + schema: ansible_test + template: Template 1 + sites: + - '{{ mso_site | default("ansible_test") }}' + state: undeploy + ignore_errors: yes diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_service_node_type/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_service_node_type/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_service_node_type/aliases @@ -0,0 +1,2 @@ +# No ACI MultiSite infrastructure, so not enabled +# unsupported diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_service_node_type/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_service_node_type/tasks/main.yml new file mode 100644 index 00000000..a5d906bf --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_service_node_type/tasks/main.yml @@ -0,0 +1,199 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Shreyas Srish (@shrsr) <ssrish@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(false) }}' + output_level: '{{ mso_output_level | default("info") }}' + +- name: Remove existing nodes added during test + cisco.mso.mso_service_node_type: + <<: *mso_info + name: '{{ item }}' + state: absent + loop: + - TEST1 + - TEST2 + +- name: Add a new node type (check_mode) + cisco.mso.mso_service_node_type: + <<: *mso_info + name: TEST1 + display_name: test + state: present + register: node_cm + check_mode: yes + +- name: Verify node_cm + assert: + that: + - node_cm is changed + - node_cm.current.displayName == "test" + - node_cm.current.name == "TEST1" + +- name: Add a new node type (normal mode) + cisco.mso.mso_service_node_type: + <<: *mso_info + name: TEST1 + display_name: test + state: present + register: node1 + +- name: Verify node1 + assert: + that: + - node1 is changed + - node1.current.displayName == "test" + - node1.current.name == "TEST1" + +- name: Add another node type + cisco.mso.mso_service_node_type: + <<: *mso_info + name: TEST2 + state: present + register: node2 + +- name: Verify node2 + assert: + that: + - node2 is changed + - node2.current.displayName == "TEST2" + - node2.current.name == "TEST2" + +- name: Add node type TEST2 again + cisco.mso.mso_service_node_type: + <<: *mso_info + name: TEST2 + state: present + register: node2_again + +- name: Verify node2_again + assert: + that: + - node2_again is not changed + - node2_again.current.displayName == "TEST2" + - node2_again.current.name == "TEST2" + +- name: Add TEST1 again with a different display name + cisco.mso.mso_service_node_type: + <<: *mso_info + name: TEST1 + display_name: change_test + state: present + register: node2_different_display_name + ignore_errors: yes + +- name: Verify node2_different_display_name + assert: + that: + - node2_different_display_name.msg == "Service Node Type 'TEST1' already exists with display name 'test' which is different from provided display name 'change_test'." + +- name: Query a node type + cisco.mso.mso_service_node_type: + <<: *mso_info + name: TEST1 + state: query + register: query_node1 + +- name: Verify query_node1 + assert: + that: + - query_node1 is not changed + - query_node1.current.displayName == "test" + - query_node1.current.name == "TEST1" + +- name: Query all node types + cisco.mso.mso_service_node_type: + <<: *mso_info + state: query + register: query_all + +- name: Verify query_all + assert: + that: + - query_all is not changed + - query_all.current | length >= 4 + +- name: Remove a node type (check_mode) + cisco.mso.mso_service_node_type: + <<: *mso_info + name: TEST1 + state: absent + check_mode: yes + register: cm_rm + +- name: Verify cm_rm + assert: + that: + - cm_rm is changed + - cm_rm.previous.name == "TEST1" + +- name: Remove a node type (normal_mode) + cisco.mso.mso_service_node_type: + <<: *mso_info + name: TEST1 + state: absent + register: rm_node1 + +- name: Verify rm_node1 + assert: + that: + - rm_node1 is changed + - rm_node1.current == {} + - rm_node1.previous.name == "TEST1" + +- name: Query absent node type + cisco.mso.mso_service_node_type: + <<: *mso_info + name: TEST1 + state: query + register: query_absent + ignore_errors: yes + +- name: Verify query_absent + assert: + that: + - query_absent.msg == "Service Node Type 'TEST1' not found" + +- name: Remove another node type + cisco.mso.mso_service_node_type: + <<: *mso_info + name: TEST2 + state: absent + register: rm_node2 + +- name: Verify rm_node2 + assert: + that: + - rm_node2 is changed + - rm_node2.current == {} + - rm_node2.previous.name == "TEST2" + +- name: Remove node type again + cisco.mso.mso_service_node_type: + <<: *mso_info + name: TEST2 + state: absent + register: rm_node2_again + +- name: Verify rm_node2_again + assert: + that: + - rm_node2_again is not changed + - rm_node2_again.current == {} + - rm_node2_again.previous == {} diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_site/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_site/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_site/aliases @@ -0,0 +1,2 @@ +# No ACI MultiSite infrastructure, so not enabled +# unsupported diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_site/tasks/connectivity.j2 b/ansible_collections/cisco/mso/tests/integration/targets/mso_site/tasks/connectivity.j2 new file mode 100644 index 00000000..bb880432 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_site/tasks/connectivity.j2 @@ -0,0 +1,489 @@ +{ + "siteGroup": { + "name": "default", + "common": { + "peeringType": "full-mesh", + "ttl": 16, + "keepAliveInterval": 60, + "holdInterval": 180, + "staleInterval": 300, + "gracefulRestartEnabled": true, + "maxAsLimit": 0, + "externalSubnetPools": [ + "169.254.0.0/16", + "10.104.0.0/16", + "20.253.0.0/16" + ] + }, + "dcnm": { + "l2VniRange": "130000-149000", + "l3VniRange": "150000-159000", + "msiteAnycastTepPool": "10.10.0.0/24", + "msiteAnycastMac": "2020.0000.00aa", + "routeTargetPrefix": 23456, + "peeringType": "" + }, + "apic": { + "gracefulRestartEnabled": false, + "ipns": [ + { + "name": "test", + "ip": "2.2.2.2" + } + ], + "cloudsecUdpPortCtrl": false + }, + "capic": { + "ospfAreaID": "0.0.0.0" + }, + "externalDevices": {} + }, + "sites": [ + { + "id": "{{ site_dict.azure_ansible_test.id }}", + "siteId": "{{ azure_site_id }}", + "siteGroupId": "{{ site_dict.azure_ansible_test.site_group_id }}", + "siteType": "CloudApic", + "bgpAsn": 64701, + "msiteEnabled": true, + "health": {}, + "apic": { + "srgbRange": {} + }, + "dcnm": { + "fabricType": "" + }, + "capic": { + "regions": [ + { + "name": "westus", + "cloudRouters": [ + { + "name": "ct_routerp_westus_1", + "routerType": "CSR", + "msiteControlPlaneTep": "10.253.254.116/28", + "bgpPeeringEnabled": true, + "routeReflectorEnabled": false + }, + { + "name": "ct_routerp_westus_0", + "routerType": "CSR", + "bgpPeeringEnabled": true, + "routeReflectorEnabled": false + } + ], + "cApicDeployed": true + }, + { + "name": "westus2", + "cloudRouters": [ + { + "name": "ct_routerp_westus2_0", + "routerType": "CSR", + "bgpPeeringEnabled": true, + "routeReflectorEnabled": false + }, + { + "name": "ct_routerp_westus2_1", + "routerType": "CSR", + "bgpPeeringEnabled": true, + "routeReflectorEnabled": false + } + ] + } + ] + }, + "status": { + "state": "success" + }, + "deployed": true + }, + { + "id": "{{ site_dict.aws_ansible_test.id }}", + "siteId": "{{ aws_site_id }}", + "siteGroupId": "{{ site_dict.aws_ansible_test.site_group_id }}", + "siteType": "CloudApic", + "bgpAsn": 200, + "msiteEnabled": true, + "health": {}, + "apic": { + "srgbRange": {} + }, + "dcnm": { + "fabricType": "" + }, + "capic": { + "regions": [ + { + "name": "us-west-1", + "cloudRouters": [], + "cApicDeployed": true + }, + { + "name": "us-east-1", + "cloudRouters": [] + }, + { + "name": "us-east-2", + "cloudRouters": [] + }, + { + "name": "us-west-2", + "cloudRouters": [] + } + ] + }, + "status": { + "state": "success" + }, + "deployed": true + }, + { + "id": "{{ site_dict.ansible_test.id }}", + "siteId": "{{ apic_site_id }}", + "siteGroupId": "{{ site_dict.ansible_test.site_group_id }}", + "siteType": "Apic", + "bgpAsn": 100, + "msiteEnabled": true, + "ospfAreaID": "0.0.0.1", + "ospfAreaType": "nssa", + "ospfPolicies": [ + { + "name": "default", + "networkType": "broadcast", + "priority": 1, + "interfaceCost": 0, + "interfaceControls": [], + "helloInterval": 10, + "deadInterval": 40, + "retransmitInterval": 5, + "transmitDelay": 1 + }, + { + "name": "msc-ospf-policy-default", + "networkType": "point-to-point", + "priority": 1, + "interfaceCost": 0, + "interfaceControls": [], + "helloInterval": 10, + "deadInterval": 40, + "retransmitInterval": 5, + "transmitDelay": 1 + }, + { + "name": "common/default", + "networkType": "unspecified", + "priority": 1, + "interfaceCost": 0, + "interfaceControls": [], + "helloInterval": 10, + "deadInterval": 40, + "retransmitInterval": 5, + "transmitDelay": 1 + } + ], + "health": {}, + "apic": { + "fabricID": 1, + "dpMcTep": "1.1.1.2", + "extRoutedDom": "uni/l3dom-L3out_Dom", + "srgbRange": {}, + "pods": [ + { + "podId": 1, + "name": "pod-1", + "msiteDataPlaneUnicastTep": "1.1.1.1", + "spines": [ + { + "nodeId": 201, + "name": "lh-dmz1-spine201", + "ports": [ + { + "portId": "1/5", + "ipAddress": "10.1.0.202/12", + "mtu": "inherit", + "routingPolicy": "default", + "ospfAuthType": "none", + "ospfAuthKeyId": 1, + "bgpPeer": { + "ttl": 1, + "adminStateEnabled": false + } + } + ], + "bgpPeeringEnabled": true, + "msiteControlPlaneTep": "1.2.2.2", + "routeReflectorEnabled": false, + "health": {} + } + ], + "msiteDataPlaneRoutableTEPPools": [ + { + "pool": "192.168.1.0/24", + "reserveAddressCount": 2 + } + ], + "health": {}, + "podFabricTepPools": [ + { + "pool": "10.0.0.0/16" + } + ] + } + ] + }, + "dcnm": { + "fabricType": "" + }, + "capic": {}, + "status": { + "state": "success" + }, + "deployed": true + } + ], + "sitesUc": [ + { + "id": "{{ site_dict.azure_ansible_test.id }}", + "siteId": "{{ azure_site_id }}", + "siteType": "CloudApic", + "apic": {}, + "capic": { + "provider": "Azure", + "accountID": "85ca999d-c9c7-484b-82b8-6854bc1e2af5", + "regions": [ + { + "regionName": "westus", + "cloudProviderID": "/subscriptions/85ca999d-c9c7-484b-82b8-6854bc1e2af5/resourceGroups/cAPIC-02/providers/Microsoft.Network/virtualNetworks/overlay-1", + "cidrs": [ + "10.253.253.128/25", + "10.253.253.0/25", + "10.253.254.0/25" + ] + }, + { + "regionName": "westus2", + "cloudProviderID": "/subscriptions/85ca999d-c9c7-484b-82b8-6854bc1e2af5/resourceGroups/CAPIC_infra_overlay-1_westus2/providers/Microsoft.Network/virtualNetworks/overlay-1", + "cidrs": [ + "10.253.255.0/25", + "10.253.255.128/25", + "10.253.254.128/25" + ] + } + ] + }, + "dcnm": {}, + "remoteSites": [ + { + "remoteType": "", + "id": "{{ site_dict.aws_ansible_test.id }}", + "siteId": "{{ aws_site_id }}", + "siteType": "CloudApic", + "connections": [ + { + "priority": 0, + "connectionType": "Public", + "ipsec": true, + "ikev": "ikev2", + "protocol": "BgpEvpn", + "nonEvpnConfig": {}, + "bfdConfig": { + "name": "default" + }, + "tunnels": [ + { + "ikev": "ikev2", + "bgpPeer": { + "asn": "" + } + } + ] + } + ] + }, + { + "remoteType": "", + "id": "{{ site_dict.ansible_test.id }}", + "siteId": "{{ apic_site_id }}", + "siteType": "Apic", + "connections": [ + { + "priority": 0, + "connectionType": "Public", + "ipsec": true, + "ikev": "ikev2", + "protocol": "BgpEvpn", + "nonEvpnConfig": {}, + "bfdConfig": { + "name": "default" + }, + "tunnels": [ + { + "ikev": "ikev2", + "bgpPeer": { + "asn": "" + } + } + ] + } + ] + } + ], + "status": { + "state": "success" + }, + "ecStatus": { + "state": "success" + } + }, + { + "id": "{{ site_dict.aws_ansible_test.id }}", + "siteId": "{{ aws_site_id }}", + "siteType": "CloudApic", + "apic": {}, + "capic": { + "provider": "Aws", + "accountID": "787820171958", + "regions": [ + { + "regionName": "us-west-1", + "cloudProviderID": "vpc-01d3ce3ef88c18087", + "cloudDirectoryID": "787820171958", + "cidrs": [ + "10.10.0.0/25" + ] + } + ] + }, + "dcnm": {}, + "remoteSites": [ + { + "remoteType": "", + "id": "{{ site_dict.azure_ansible_test.id }}", + "siteId": "{{ azure_site_id }}", + "siteType": "CloudApic", + "connections": [ + { + "priority": 0, + "connectionType": "Public", + "ipsec": true, + "ikev": "ikev2", + "protocol": "BgpEvpn", + "nonEvpnConfig": {}, + "bfdConfig": { + "name": "default" + }, + "tunnels": [ + { + "ikev": "ikev2", + "bgpPeer": { + "asn": "" + } + } + ] + } + ] + }, + { + "remoteType": "", + "id": "{{ site_dict.ansible_test.id }}", + "siteId": "{{ apic_site_id }}", + "siteType": "Apic", + "connections": [ + { + "priority": 0, + "connectionType": "Public", + "ipsec": true, + "ikev": "ikev2", + "protocol": "BgpEvpn", + "nonEvpnConfig": {}, + "bfdConfig": { + "name": "default" + }, + "tunnels": [ + { + "ikev": "ikev2", + "bgpPeer": { + "asn": "" + } + } + ] + } + ] + } + ], + "status": { + "state": "success" + }, + "ecStatus": { + "state": "success" + } + }, + { + "id": "{{ site_dict.ansible_test.id }}", + "siteId": "{{ apic_site_id }}", + "siteType": "Apic", + "apic": {}, + "capic": {}, + "dcnm": {}, + "remoteSites": [ + { + "remoteType": "", + "id": "{{ site_dict.azure_ansible_test.id }}", + "siteId": "{{ azure_site_id }}", + "siteType": "CloudApic", + "connections": [ + { + "priority": 0, + "connectionType": "Public", + "ipsec": true, + "ikev": "ikev2", + "protocol": "BgpEvpn", + "nonEvpnConfig": {}, + "bfdConfig": { + "name": "default" + }, + "tunnels": [ + { + "ikev": "ikev2", + "bgpPeer": { + "asn": "" + } + } + ] + } + ] + }, + { + "remoteType": "", + "id": "{{ site_dict.aws_ansible_test.id }}", + "siteId": "{{ aws_site_id }}", + "siteType": "CloudApic", + "connections": [ + { + "priority": 0, + "connectionType": "Public", + "ipsec": true, + "ikev": "ikev2", + "protocol": "BgpEvpn", + "nonEvpnConfig": {}, + "bfdConfig": { + "name": "default" + }, + "tunnels": [ + { + "ikev": "ikev2", + "bgpPeer": { + "asn": "" + } + } + ] + } + ] + } + ], + "status": {}, + "ecStatus": {} + } + ] +}
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_site/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_site/tasks/main.yml new file mode 100644 index 00000000..d0c1dc11 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_site/tasks/main.yml @@ -0,0 +1,565 @@ +# Test code for the MSO modules +# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.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: + site_dict: {} + 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") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Undeploy a schema 1 template 1 + mso_schema_template_deploy: &schema_undeploy + <<: *mso_info + schema: ansible_test + template: Template 1 + site: '{{ item }}' + state: undeploy + ignore_errors: yes + loop: + - '{{ mso_site | default("ansible_test") }}' + - '{{ mso_site | default("ansible_test") }}_2' + +- name: Undeploy a schema 1 template 2 + mso_schema_template_deploy: + <<: *schema_undeploy + template: Template 2 + site: '{{ item }}' + state: undeploy + ignore_errors: yes + loop: + - '{{ mso_site | default("ansible_test") }}' + - '{{ mso_site | default("ansible_test") }}_2' + +- name: Undeploy a schema 2 template 3 + mso_schema_template_deploy: + <<: *schema_undeploy + schema: ansible_test_2 + template: Template 3 + site: '{{ item }}' + state: undeploy + ignore_errors: yes + loop: + - '{{ mso_site | default("ansible_test") }}' + - '{{ mso_site | default("ansible_test") }}_2' + +- name: Remove schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + - 'Schema1' + - 'Schema2' + +- name: Remove tenant ansible_test + mso_tenant: &tenant_absent + <<: *mso_info + tenant: ansible_test + state: absent + +- name: Remove tenant ansible_test2 + mso_tenant: + <<: *tenant_absent + tenant: ansible_test2 + register: cm_remove_tenant + +- name: Remove site + mso_site: &site_absent + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + state: absent + +- name: Remove site 2 + mso_site: + <<: *site_absent + site: '{{ mso_site | default("ansible_test") }}_2' + register: cm_remove_site + + +# ADD SITE +- name: Add site (check_mode) + mso_site: &site_present + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + apic_username: '{{ apic_username }}' + apic_password: '{{ apic_password }}' + apic_site_id: '{{ apic_site_id | default(101) }}' + urls: + - https://{{ apic_hostname }} + location: + latitude: 50.887318 + longitude: 4.447084 + labels: + - Diegem + - EMEA + - POD51 + state: present + check_mode: yes + register: cm_add_site + +- name: Verify cm_add_site + assert: + that: + - cm_add_site is changed + - cm_add_site.previous == {} + +- name: Verify cm_add_site (MSO) + assert: + that: + - cm_add_site.current.id is not defined + - cm_add_site.current.name == mso_site|default("ansible_test") + when: version.current.version is version('3.2', '<') + +- name: Verify cm_add_site (ND) + assert: + that: + - cm_add_site.current.id == "" + - cm_add_site.current.common.name == mso_site|default("ansible_test") + when: version.current.version is version('3.2', '>=') + +- name: Add site (normal mode) + mso_site: *site_present + register: nm_add_site + +- name: Verify nm_add_site + assert: + that: + - nm_add_site is changed + - nm_add_site.previous == {} + +- name: Verify nm_add_site (MSO) + assert: + that: + - nm_add_site.current.id is defined + - nm_add_site.current.name == mso_site|default("ansible_test") + when: version.current.version is version('3.2', '<') + +- name: Verify nm_add_site (ND) + assert: + that: + - nm_add_site.current.common.name == mso_site|default("ansible_test") + when: version.current.version is version('3.2', '>=') + +- name: Add site again (check_mode) + mso_site: *site_present + check_mode: yes + register: cm_add_site_again + +- name: Verify cm_add_site_again + assert: + that: + - cm_add_site_again is not changed + - cm_add_site_again.current.id == nm_add_site.current.id + +- name: Verify cm_add_site_again (MSO) + assert: + that: + - cm_add_site_again.previous.name == mso_site|default("ansible_test") + - cm_add_site_again.current.name == mso_site|default("ansible_test") + when: version.current.version is version('3.2', '<') + +- name: Verify cm_add_site_again (ND) + assert: + that: + - cm_add_site_again.previous.common.name == mso_site|default("ansible_test") + - cm_add_site_again.current.common.name == mso_site|default("ansible_test") + when: version.current.version is version('3.2', '>=') + +- name: Add site again (normal mode) + mso_site: *site_present + register: nm_add_site_again + +- name: Verify nm_add_site_again + assert: + that: + - nm_add_site_again is not changed + - nm_add_site_again.current.id == nm_add_site.current.id + +- name: Verify nm_add_site_again (MSO) + assert: + that: + - nm_add_site_again.previous.name == mso_site|default("ansible_test") + - nm_add_site_again.current.name == mso_site|default("ansible_test") + when: version.current.version is version('3.2', '<') + +- name: Verify nm_add_site_again (ND) + assert: + that: + - nm_add_site_again.previous.common.name == mso_site|default("ansible_test") + - nm_add_site_again.current.common.name == mso_site|default("ansible_test") + when: version.current.version is version('3.2', '>=') + + +# CHANGE SITE +- name: Change site (check_mode) + mso_site: + <<: *site_present + site: '{{ mso_site | default("ansible_test") }}' + apic_login_domain: '{{ apic_login_domain | default("test") }}' + location: + latitude: 51.887318 + longitude: 5.447084 + labels: + - Charleroi + - EMEA + check_mode: yes + register: cm_change_site + +- name: Verify cm_change_site + assert: + that: + - cm_change_site.current.id == nm_add_site.current.id + +- name: Verify cm_change_site (MSO) + assert: + that: + - cm_change_site is changed + - cm_change_site.current.location.lat == 51.887318 + - cm_change_site.current.location.long == 5.447084 + - cm_change_site.current.labels[0] != nm_add_site.current.labels[0] + - cm_change_site.current.labels[1] == nm_add_site.current.labels[1] + - cm_change_site.current.name == mso_site|default("ansible_test") + when: version.current.version is version('3.2', '<') + +- name: Verify cm_change_site (ND) + assert: + that: + - cm_change_site.current.common.name == mso_site|default("ansible_test") + when: version.current.version is version('3.2', '>=') + +- name: Change site (normal mode) + mso_site: + <<: *site_present + site: '{{ mso_site | default("ansible_test") }}' + apic_login_domain: '{{ apic_login_domain | default("test") }}' + location: + latitude: 51.887318 + longitude: 5.447084 + labels: + - Charleroi + - EMEA + output_level: debug + register: nm_change_site + +- name: Verify nm_change_site + assert: + that: + - nm_change_site.current.id == nm_add_site.current.id + +- name: Verify nm_change_site (MSO) + assert: + that: + - nm_change_site is changed + - nm_change_site.current.location.lat == 51.887318 + - nm_change_site.current.location.long == 5.447084 + - nm_change_site.current.labels[0] != nm_add_site.current.labels[0] + - nm_change_site.current.labels[1] == nm_add_site.current.labels[1] + - nm_change_site.current.name == mso_site|default("ansible_test") + when: version.current.version is version('3.2', '<') + +- name: Verify nm_change_site (ND) + assert: + that: + - nm_change_site.current.common.name == mso_site|default("ansible_test") + when: version.current.version is version('3.2', '>=') + +- name: Change site again (check_mode) + mso_site: + <<: *site_present + site: '{{ mso_site | default("ansible_test") }}' + apic_login_domain: '{{ apic_login_domain | default("test") }}' + location: + latitude: 51.887318 + longitude: 5.447084 + labels: + - Charleroi + - EMEA + check_mode: yes + register: cm_change_site_again + +- name: Verify cm_change_site_again + assert: + that: + - cm_change_site_again is not changed + - cm_change_site_again.current.id == nm_add_site.current.id + +- name: Verify cm_change_site_again (MSO) + assert: + that: + - cm_change_site_again.current.location.lat == 51.887318 + - cm_change_site_again.current.location.long == 5.447084 + - cm_change_site_again.current.labels[0] == nm_change_site.current.labels[0] + - cm_change_site_again.current.labels[1] == nm_change_site.current.labels[1] + - cm_change_site_again.current.name == mso_site|default("ansible_test") + when: version.current.version is version('3.2', '<') + +- name: Verify cm_change_site_again (ND) + assert: + that: + - cm_change_site_again.current.common.name == mso_site|default("ansible_test") + when: version.current.version is version('3.2', '>=') + +- name: Change site again (normal mode) + mso_site: + <<: *site_present + site: '{{ mso_site | default("ansible_test") }}' + apic_login_domain: '{{ apic_login_domain | default("test") }}' + location: + latitude: 51.887318 + longitude: 5.447084 + labels: + - Charleroi + - EMEA + output_level: debug + register: nm_change_site_again + +- name: Verify nm_change_site_again + assert: + that: + - nm_change_site_again is not changed + - nm_change_site_again.current.id == nm_add_site.current.id + +- name: Verify nm_change_site_again (MSO) + assert: + that: + - nm_change_site_again.current.location.lat == 51.887318 + - nm_change_site_again.current.location.long == 5.447084 + - nm_change_site_again.current.labels[0] == nm_change_site.current.labels[0] + - nm_change_site_again.current.labels[1] == nm_change_site.current.labels[1] + - nm_change_site_again.current.name == mso_site|default("ansible_test") + when: version.current.version is version('3.2', '<') + +- name: Verify nm_change_site_again (ND) + assert: + that: + - nm_change_site_again.current.common.name == mso_site|default("ansible_test") + when: version.current.version is version('3.2', '>=') + +# QUERY ALL SITES +- name: Query all sites (check_mode) + mso_site: &site_query + <<: *mso_info + state: query + check_mode: yes + register: cm_query_all_sites + +- name: Query all sites (normal mode) + mso_site: *site_query + register: nm_query_all_sites + +- name: Verify query_all_sites + assert: + that: + - cm_query_all_sites is not changed + - nm_query_all_sites is not changed + # NOTE: Order of sites is not stable between calls + #- cm_query_all_sites == nm_query_all_sites + + +# QUERY A SITE +- name: Query our site + mso_site: + <<: *site_query + site: '{{ mso_site | default("ansible_test") }}' + check_mode: yes + register: cm_query_site + +- name: Query our site + mso_site: + <<: *site_query + site: '{{ mso_site | default("ansible_test") }}' + register: nm_query_site + +- name: Verify query_site + assert: + that: + - cm_query_site is not changed + - cm_query_site.current.id == nm_add_site.current.id + - nm_query_site is not changed + - nm_query_site.current.id == nm_add_site.current.id + - cm_query_site == nm_query_site + +- name: Verify query_site (MSO) + assert: + that: + - cm_query_site.current.name == mso_site|default("ansible_test") + - nm_query_site.current.name == mso_site|default("ansible_test") + when: version.current.version is version('3.2', '<') + +- name: Verify query_site (ND) + assert: + that: + - cm_query_site.current.common.name == mso_site|default("ansible_test") + - nm_query_site.current.common.name == mso_site|default("ansible_test") + when: version.current.version is version('3.2', '>=') + +# REMOVE SITE +- name: Remove site (check_mode) + mso_site: *site_absent + check_mode: yes + register: cm_remove_site + +- name: Verify cm_remove_site + assert: + that: + - cm_remove_site is changed + - cm_remove_site.current == {} + +- name: Remove site (normal mode) + mso_site: *site_absent + register: nm_remove_site + +- name: Verify nm_remove_site + assert: + that: + - nm_remove_site is changed + - nm_remove_site.current == {} + +- name: Remove site again (check_mode) + mso_site: *site_absent + check_mode: yes + register: cm_remove_site_again + +- name: Verify cm_remove_site_again + assert: + that: + - cm_remove_site_again is not changed + - cm_remove_site_again.current == {} + +- name: Remove site again (normal mode) + mso_site: *site_absent + register: nm_remove_site_again + +- name: Verify nm_remove_site_again + assert: + that: + - nm_remove_site_again is not changed + - nm_remove_site_again.current == {} + + +# QUERY NON-EXISTING SITE +- name: Query non-existing site (check_mode) + mso_site: + <<: *site_query + site: '{{ mso_site | default("ansible_test") }}' + check_mode: yes + register: cm_query_non_site + +- name: Query non-existing site (normal mode) + mso_site: + <<: *site_query + site: '{{ mso_site | default("ansible_test") }}' + register: nm_query_non_site + +# TODO: Implement more tests +- name: Verify query_non_site + assert: + that: + - cm_query_non_site is not changed + - nm_query_non_site is not changed + - cm_query_non_site == nm_query_non_site + +# USE A NON-EXISTING STATE +- name: Non-existing state for site (check_mode) + mso_site: + <<: *site_query + state: non-existing-state + check_mode: yes + ignore_errors: yes + register: cm_non_existing_state + +- name: Non-existing state for bd (normal_mode) + mso_site: + <<: *site_query + state: non-existing-state + ignore_errors: yes + register: nm_non_existing_state + +- name: Verify non_existing_state + assert: + that: + - cm_non_existing_state is not changed + - nm_non_existing_state is not changed + - cm_non_existing_state == nm_non_existing_state + - cm_non_existing_state.msg == nm_non_existing_state.msg == "value of state must be one of{{':'}} absent, present, query, got{{':'}} non-existing-state" + +# ADD SITE +- name: Add site (normal_mode) + mso_site: + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + apic_username: '{{ apic_username }}' + apic_password: '{{ apic_password }}' + apic_site_id: '{{ apic_site_id | default(101) }}' + apic_login_domain: '{{ apic_login_domain | default("test") }}' + urls: + - https://{{ apic_hostname }} + state: present + register: nm_add_site_no_location + +- name: Verify nm_add_site_no_location + assert: + that: + - nm_add_site_no_location is changed + - nm_add_site_no_location.previous == {} + - nm_add_site_no_location.current.id is defined + +- name: Verify nm_add_site_no_location (MSO) + assert: + that: + - nm_add_site_no_location.current.name == mso_site|default("ansible_test") + when: version.current.version is version('3.2', '<') + +- name: Verify nm_add_site_no_location (ND) + assert: + that: + - nm_add_site_no_location.current.common.name == mso_site|default("ansible_test") + when: version.current.version is version('3.2', '>=') + +- name: Execute tasks only for MSO version >= 4.0 to reset site connectivity + when: version.current.version is version('4.0', '>=') + block: + - name: Query all sites (check_mode) + mso_site: + <<: *mso_info + state: query + register: sites + + - name: Add sites to dict + set_fact: + site_dict: "{{ site_dict | combine( { item.common.name : { 'id' : item.id, 'site_group_id' : item.common.siteGroup } } ) }}" + loop: "{{ sites.current }}" + + - name: Render a connectivity jinja2 template + set_fact: + site_payload: "{{ lookup('template', 'connectivity.j2') }}" + + - name: Configure site connectivity + cisco.mso.mso_rest: + <<: *mso_info + path: /mso/api/v2/sites/fabric-connectivity + method: put + content: "{{ site_payload }}"
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_tenant/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_tenant/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_tenant/aliases @@ -0,0 +1,2 @@ +# No ACI MultiSite infrastructure, so not enabled +# unsupported diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_tenant/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_tenant/tasks/main.yml new file mode 100644 index 00000000..580a34f5 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_tenant/tasks/main.yml @@ -0,0 +1,758 @@ +# Test code for the MSO modules +# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> +# Copyright: (c) 2020, Cindy Zhao (@cizhao) <cizhao@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") }}' + +- name: Ensure sites exists + mso_site: + <<: *mso_info + site: '{{ item.site }}' + apic_username: '{{ item.username }}' + apic_password: '{{ item.password }}' + apic_site_id: '{{ item.id }}' + urls: + - https://{{ item.urls }} + state: present + loop: + - { site: '{{ mso_site | default("ansible_test") }}', username: '{{ apic_username }}', password: '{{ apic_password }}', id: '{{ apic_site_id | default(101) }}', urls: '{{ apic_hostname }}' } + - { site: 'aws_{{ mso_site | default("ansible_test") }}', username: '{{ aws_apic_username }}', password: '{{ aws_apic_password }}', id: '{{ aws_site_id | default(102) }}', urls: '{{ aws_apic_hostname }}' } + +- name: Undeploy a schema 1 template 1 + mso_schema_template_deploy: &schema_undeploy + <<: *mso_info + schema: ansible_test + template: Template 1 + site: '{{ item }}' + state: undeploy + ignore_errors: yes + loop: + - '{{ mso_site | default("ansible_test") }}' + - 'aws_{{ mso_site | default("ansible_test") }}' + +- name: Undeploy a schema 1 template 2 + mso_schema_template_deploy: + <<: *schema_undeploy + template: Template 2 + site: '{{ item }}' + state: undeploy + ignore_errors: yes + loop: + - '{{ mso_site | default("ansible_test") }}' + - 'aws_{{ mso_site | default("ansible_test") }}' + +- name: Undeploy a schema 2 template 3 + mso_schema_template_deploy: + <<: *schema_undeploy + schema: ansible_test_2 + template: Template 3 + site: '{{ item }}' + state: undeploy + ignore_errors: yes + loop: + - '{{ mso_site | default("ansible_test") }}' + - 'aws_{{ mso_site | default("ansible_test") }}' + +- name: Remove schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Remove tenants + mso_tenant: &tenant_absent + <<: *mso_info + tenant: '{{ item }}' + state: absent + loop: + - ansible_test + - ansible_test2 + - ansible_test3 + - tenant_with_site + +# ADD TENANT +- name: Add tenant (check_mode) + mso_tenant: &tenant_present + <<: *mso_info + tenant: ansible_test + display_name: Ansible test title + description: Ansible test tenant + state: present + check_mode: yes + register: cm_add_tenant + +- name: Verify cm_add_tenant + assert: + that: + - cm_add_tenant is changed + - cm_add_tenant.previous == {} + - cm_add_tenant.current.id is not defined + - cm_add_tenant.current.name == 'ansible_test' + - cm_add_tenant.current.description == 'Ansible test tenant' + - cm_add_tenant.current.userAssociations | length == 1 + +- name: Add tenant (normal mode) + mso_tenant: *tenant_present + register: nm_add_tenant + +- name: Verify nm_add_tenant + assert: + that: + - nm_add_tenant is changed + - nm_add_tenant.previous == {} + - nm_add_tenant.current.id is defined + - nm_add_tenant.current.name == 'ansible_test' + - nm_add_tenant.current.description == 'Ansible test tenant' + - nm_add_tenant.current.userAssociations | length == 1 + +- name: Add tenant again (check_mode) + mso_tenant: *tenant_present + check_mode: yes + register: cm_add_tenant_again + +- name: Verify cm_add_tenant_again + assert: + that: + - cm_add_tenant_again is not changed + - cm_add_tenant_again.previous.name == 'ansible_test' + - cm_add_tenant_again.previous.description == 'Ansible test tenant' + - cm_add_tenant_again.current.id == nm_add_tenant.current.id + - cm_add_tenant_again.current.name == 'ansible_test' + - cm_add_tenant_again.current.description == 'Ansible test tenant' + - cm_add_tenant_again.current.userAssociations == cm_add_tenant_again.previous.userAssociations + +- name: Add tenant again (normal mode) + mso_tenant: *tenant_present + register: nm_add_tenant_again + +- name: Verify nm_add_tenant_again + assert: + that: + - nm_add_tenant_again is not changed + - nm_add_tenant_again.previous.name == 'ansible_test' + - nm_add_tenant_again.previous.description == 'Ansible test tenant' + - nm_add_tenant_again.current.id == nm_add_tenant.current.id + - nm_add_tenant_again.current.name == 'ansible_test' + - nm_add_tenant_again.current.description == 'Ansible test tenant' + - nm_add_tenant_again.current.userAssociations == nm_add_tenant_again.previous.userAssociations + +# ADD TENANT WITH USERS +- name: Add tenant 2 (normal mode) + mso_tenant: + <<: *tenant_present + tenant: ansible_test2 + users: + - '{{ mso_username }}' + display_name: null + state: present + register: nm_add_tenant2 + +- name: Verify nm_add_tenant2 + assert: + that: + - nm_add_tenant2 is changed + +- name: Verify nm_add_tenant2 (when mso_username != admin) + assert: + that: + - nm_add_tenant2.current.userAssociations | length == 2 + when: mso_username != 'admin' + +- name: Verify nm_add_tenant2 (when mso_username == admin) + assert: + that: + - nm_add_tenant2.current.userAssociations | length == 1 + when: mso_username == 'admin' + +- name: Add tenant 2 again (normal mode) + mso_tenant: + <<: *tenant_present + tenant: ansible_test2 + users: + - '{{ mso_username }}' + display_name: null + state: present + register: nm_add_tenant2_again + +- name: Verify nm_add_tenant2_again + assert: + that: + - nm_add_tenant2_again is not changed + +- name: Verify nm_add_tenant2_again (when mso_username != admin) + assert: + that: + - nm_add_tenant2_again.current.userAssociations | length == 2 + when: mso_username != 'admin' + +- name: Verify nm_add_tenant2_again (when mso_username == admin) + assert: + that: + - nm_add_tenant2_again.current.userAssociations | length == 1 + when: mso_username == 'admin' + +- name: Add tenant 3 with duplicate admin user (normal mode) + mso_tenant: + <<: *tenant_present + tenant: ansible_test3 + users: + - admin + - admin + display_name: null + state: present + ignore_errors: yes + register: nm_add_tenant3_with_duplicate_admin + +- name: Verify nm_add_tenant3_with_duplicate_admin + assert: + that: + - nm_add_tenant3_with_duplicate_admin is not changed + - nm_add_tenant3_with_duplicate_admin.msg == "User 'admin' is duplicate." + +- name: Add tenant 3 with invalid user (normal mode) + mso_tenant: + <<: *tenant_present + tenant: ansible_test3 + users: + - invalid user + display_name: null + state: present + ignore_errors: yes + register: nm_add_tenant3_with_invalid_user + +- name: nm_add_tenant3_with_invalid_user + assert: + that: + - nm_add_tenant3_with_invalid_user is not changed + - nm_add_tenant3_with_invalid_user.msg == "User 'invalid user' is not a valid user name." + +- name: Add tenant 3 (normal mode) + mso_tenant: + <<: *tenant_present + tenant: ansible_test3 + users: + - '{{ mso_username }}' + display_name: null + state: present + register: nm_add_tenant3 + +- name: Verify nm_add_tenant3 + assert: + that: + - nm_add_tenant3 is changed + +- name: Verify nm_add_tenant3 (when mso_username != admin) + assert: + that: + - nm_add_tenant3.current.userAssociations | length == 2 + when: mso_username != 'admin' + +- name: Verify nm_add_tenant3 (when mso_username == admin) + assert: + that: + - nm_add_tenant3.current.userAssociations | length == 1 + when: mso_username == 'admin' + +# CHANGE TENANT +- name: Change tenant (check_mode) + mso_tenant: + <<: *tenant_present + tenant: ansible_test + description: Ansible test tenant 2 + check_mode: yes + register: cm_change_tenant + +- name: Verify cm_change_tenant + assert: + that: + - cm_change_tenant is changed + - cm_change_tenant.current.id == nm_add_tenant.current.id + - cm_change_tenant.current.name == 'ansible_test' + - cm_change_tenant.current.description == 'Ansible test tenant 2' + +- name: Change tenant (normal mode) + mso_tenant: + <<: *tenant_present + tenant: ansible_test + description: Ansible test tenant 2 + output_level: debug + register: nm_change_tenant + +- name: Verify nm_change_tenant + assert: + that: + - nm_change_tenant is changed + - nm_change_tenant.current.id == nm_add_tenant.current.id + - nm_change_tenant.current.name == 'ansible_test' + - nm_change_tenant.current.description == 'Ansible test tenant 2' + +- name: Change tenant again (check_mode) + mso_tenant: + <<: *tenant_present + tenant: ansible_test + description: Ansible test tenant 2 + check_mode: yes + register: cm_change_tenant_again + +- name: Verify cm_change_tenant_again + assert: + that: + - cm_change_tenant_again is not changed + - cm_change_tenant_again.current.id == nm_add_tenant.current.id + - cm_change_tenant_again.current.name == 'ansible_test' + - cm_change_tenant_again.current.description == 'Ansible test tenant 2' + +- name: Change tenant again (normal mode) + mso_tenant: + <<: *tenant_present + tenant: ansible_test + description: Ansible test tenant 2 + register: nm_change_tenant_again + +- name: Verify nm_change_tenant_again + assert: + that: + - nm_change_tenant_again is not changed + - nm_change_tenant_again.current.id == nm_add_tenant.current.id + - nm_change_tenant_again.current.name == 'ansible_test' + - nm_change_tenant_again.current.description == 'Ansible test tenant 2' + + +# QUERY ALL TENANTS +- name: Query all tenants (check_mode) + mso_tenant: &tenant_query + <<: *mso_info + state: query + check_mode: yes + register: cm_query_all_tenants + +- name: Query all tenants (normal mode) + mso_tenant: *tenant_query + register: nm_query_all_tenants + +- name: Verify query_all_tenants + assert: + that: + - cm_query_all_tenants is not changed + - nm_query_all_tenants is not changed + # NOTE: Order of tenants is not stable between calls + #- cm_query_all_tenants == nm_query_all_tenants + + +# QUERY A TENANT +- name: Query our tenant + mso_tenant: + <<: *tenant_query + tenant: ansible_test + check_mode: yes + register: cm_query_tenant + +- name: Query our tenant + mso_tenant: + <<: *tenant_query + tenant: ansible_test + register: nm_query_tenant + +- name: Verify query_tenant + assert: + that: + - cm_query_tenant is not changed + - cm_query_tenant.current.id == nm_add_tenant.current.id + - cm_query_tenant.current.name == 'ansible_test' + - cm_query_tenant.current.description == 'Ansible test tenant 2' + - nm_query_tenant is not changed + - nm_query_tenant.current.id == nm_add_tenant.current.id + - nm_query_tenant.current.name == 'ansible_test' + - nm_query_tenant.current.description == 'Ansible test tenant 2' + - cm_query_tenant.current == nm_query_tenant.current + + +# REMOVE TENANT +- name: Remove tenant (check_mode) + mso_tenant: + <<: *tenant_absent + tenant: ansible_test + check_mode: yes + register: cm_remove_tenant + +- name: Verify cm_remove_tenant + assert: + that: + - cm_remove_tenant is changed + - cm_remove_tenant.current == {} + +- name: Remove tenant (normal mode) + mso_tenant: + <<: *tenant_absent + tenant: ansible_test + register: nm_remove_tenant + +- name: Verify nm_remove_tenant + assert: + that: + - nm_remove_tenant is changed + - nm_remove_tenant.current == {} + +- name: Remove tenant again (check_mode) + mso_tenant: + <<: *tenant_absent + tenant: ansible_test + check_mode: yes + register: cm_remove_tenant_again + +- name: Verify cm_remove_tenant_again + assert: + that: + - cm_remove_tenant_again is not changed + - cm_remove_tenant_again.current == {} + +- name: Remove tenant again (normal mode) + mso_tenant: + <<: *tenant_absent + tenant: ansible_test + register: nm_remove_tenant_again + +- name: Verify nm_remove_tenant_again + assert: + that: + - nm_remove_tenant_again is not changed + - nm_remove_tenant_again.current == {} + + +# QUERY NON-EXISTING TENANT +- name: Query non-existing tenant (check_mode) + mso_tenant: + <<: *tenant_query + tenant: ansible_test + check_mode: yes + register: cm_query_non_tenant + +- name: Query non-existing tenant (normal mode) + mso_tenant: + <<: *tenant_query + tenant: ansible_test + register: nm_query_non_tenant + +# TODO: Implement more tests +- name: Verify query_non_tenant + assert: + that: + - cm_query_non_tenant is not changed + - nm_query_non_tenant is not changed + - cm_query_non_tenant.current == nm_query_non_tenant.current + +- name: Add common tenant + mso_tenant: + <<: *tenant_present + tenant: common + display_name: common + sites: ['{{ mso_site | default("ansible_test") }}', 'aws_{{ mso_site | default("ansible_test") }}'] + register: nm_add_common_tenant + +- name: Verify nm_add_common_tenant + assert: + that: + - nm_add_common_tenant is changed + - nm_add_common_tenant.current.name == "common" + +- name: Add tenant with site + mso_tenant: + <<: *tenant_present + tenant: tenant_with_site + display_name: tenant_with_site + sites: '{{ mso_site | default("ansible_test") }}' + register: nm_add_tenant_with_site + +- name: Verify nm_add_tenant_with_site + assert: + that: + - nm_add_tenant_with_site is changed + - nm_add_tenant_with_site.current.name == "tenant_with_site" + +- name: Remove common tenant + mso_tenant: + <<: *tenant_absent + tenant: common + ignore_errors: yes + register: rm_common + +- name: Verify rm_common + assert: + that: + - rm_common.msg is search("Common [Tt]enant cannot be deleted") + +- name: Remove tenant_with_site + mso_tenant: + <<: *tenant_absent + tenant: tenant_with_site + register: rm_tenant_with_site + +- name: Verify rm_tenant_with_site + assert: + that: + - rm_tenant_with_site is changed + - rm_tenant_with_site.current == {} + +- name: Remove "anstest_imp_tenant" to the MSO if exists + mso_tenant: + <<: *mso_info + tenant: anstest_imp_tenant + display_name: anstest_imp_tenant_display_name + description: anstest_imp_tenant_description + sites: '{{ mso_site | default("ansible_test") }}' + state: absent + register: pre_test_anstest_imp_tenant_absent + +- name: Import "anstest_imp_tenant" to the MSO with check mode + mso_tenant: &cm_import_anstest_imp_tenant_present + <<: *mso_info + tenant: anstest_imp_tenant + display_name: anstest_imp_tenant_display_name + description: anstest_imp_tenant_description + sites: '{{ mso_site | default("ansible_test") }}' + state: present + check_mode: yes + register: cm_import_anstest_imp_tenant_present + +- name: Assertions check for import "anstest_imp_tenant" to the MSO with check mode + assert: + that: + - cm_import_anstest_imp_tenant_present is changed + - cm_import_anstest_imp_tenant_present.current != {} + - cm_import_anstest_imp_tenant_present.previous == {} + - cm_import_anstest_imp_tenant_present.current.name == "anstest_imp_tenant" + - cm_import_anstest_imp_tenant_present.current.displayName == "anstest_imp_tenant_display_name" + - cm_import_anstest_imp_tenant_present.current.description == "anstest_imp_tenant_description" + +- name: Import "anstest_imp_tenant" to the MSO with normal mode + mso_tenant: &nm_import_anstest_imp_tenant_present + <<: *cm_import_anstest_imp_tenant_present + register: nm_import_anstest_imp_tenant_present + +- name: Assertions check for import "anstest_imp_tenant" to the MSO with normal mode + assert: + that: + - nm_import_anstest_imp_tenant_present is changed + - nm_import_anstest_imp_tenant_present.current != {} + - nm_import_anstest_imp_tenant_present.previous == {} + - nm_import_anstest_imp_tenant_present.current.name == "anstest_imp_tenant" + - nm_import_anstest_imp_tenant_present.current.displayName == "anstest_imp_tenant_display_name" + - nm_import_anstest_imp_tenant_present.current.description == "anstest_imp_tenant_description" + +- name: Import "anstest_imp_tenant" to the MSO with normal mode - idempotency works + mso_tenant: + <<: *nm_import_anstest_imp_tenant_present + register: idempotency_nm_import_anstest_imp_tenant_present + +- name: Idempotency assertions check for import "anstest_imp_tenant" to the MSO with normal mode + assert: + that: + - idempotency_nm_import_anstest_imp_tenant_present is not changed + - idempotency_nm_import_anstest_imp_tenant_present.current != {} + - idempotency_nm_import_anstest_imp_tenant_present.previous != {} + - idempotency_nm_import_anstest_imp_tenant_present.current.name == "anstest_imp_tenant" + - idempotency_nm_import_anstest_imp_tenant_present.current.displayName == "anstest_imp_tenant_display_name" + - idempotency_nm_import_anstest_imp_tenant_present.current.description == "anstest_imp_tenant_description" + - idempotency_nm_import_anstest_imp_tenant_present.previous.name == "anstest_imp_tenant" + - idempotency_nm_import_anstest_imp_tenant_present.previous.displayName == "anstest_imp_tenant_display_name" + - idempotency_nm_import_anstest_imp_tenant_present.previous.description == "anstest_imp_tenant_description" + +- name: Query a tenant with name "anstest_imp_tenant" when it is imported to the MSO + mso_tenant: + <<: *mso_info + tenant: anstest_imp_tenant + state: query + register: query_anstest_imp_tenant + +- name: Assertions check for query a tenant with name "anstest_imp_tenant" when it is imported to the MSO + assert: + that: + - query_anstest_imp_tenant is not changed + - query_anstest_imp_tenant.current != {} + - query_anstest_imp_tenant.current.name == "anstest_imp_tenant" + - query_anstest_imp_tenant.current.displayName == "anstest_imp_tenant_display_name" + - query_anstest_imp_tenant.current.description == "anstest_imp_tenant_description" + +- name: Remove "anstest_imp_tenant" tenant from MSO and APIC using orchestrator_only flag value yes with check mode + mso_tenant: &cm_anstest_imp_tenant_absent_orchestrator_only_yes + <<: *mso_info + tenant: anstest_imp_tenant + orchestrator_only: yes + state: absent + check_mode: yes + register: cm_anstest_imp_tenant_absent_orchestrator_only_yes + +- name: Assertions check for remove "anstest_imp_tenant" tenant from MSO and APIC using orchestrator_only flag value yes with check mode + assert: + that: + - cm_anstest_imp_tenant_absent_orchestrator_only_yes is changed + - cm_anstest_imp_tenant_absent_orchestrator_only_yes.current == {} + - cm_anstest_imp_tenant_absent_orchestrator_only_yes.previous != {} + - cm_anstest_imp_tenant_absent_orchestrator_only_yes.previous.name == "anstest_imp_tenant" + - cm_anstest_imp_tenant_absent_orchestrator_only_yes.previous.displayName == "anstest_imp_tenant_display_name" + - cm_anstest_imp_tenant_absent_orchestrator_only_yes.previous.description == "anstest_imp_tenant_description" + +- name: Remove "anstest_imp_tenant" tenant from MSO and APIC using orchestrator_only flag value yes with normal mode + mso_tenant: &nm_anstest_imp_tenant_absent_orchestrator_only_yes + <<: *cm_anstest_imp_tenant_absent_orchestrator_only_yes + register: nm_anstest_imp_tenant_absent_orchestrator_only_yes + +- name: Assertions check for remove "anstest_imp_tenant" tenant from MSO and APIC using orchestrator_only flag value yes with normal mode + assert: + that: + - nm_anstest_imp_tenant_absent_orchestrator_only_yes is changed + - nm_anstest_imp_tenant_absent_orchestrator_only_yes.current == {} + - nm_anstest_imp_tenant_absent_orchestrator_only_yes.previous != {} + - nm_anstest_imp_tenant_absent_orchestrator_only_yes.previous.name == "anstest_imp_tenant" + - nm_anstest_imp_tenant_absent_orchestrator_only_yes.previous.displayName == "anstest_imp_tenant_display_name" + - nm_anstest_imp_tenant_absent_orchestrator_only_yes.previous.description == "anstest_imp_tenant_description" + +- name: Remove "anstest_imp_tenant" tenant from MSO and APIC using orchestrator_only flag value yes with normal mode - idempotency works + mso_tenant: + <<: *nm_anstest_imp_tenant_absent_orchestrator_only_yes + register: idempotency_nm_anstest_imp_tenant_absent_orchestrator_only_yes + +- name: Idempotency assertions check for remove "anstest_imp_tenant" tenant from MSO and APIC using orchestrator_only flag value yes with normal mode + assert: + that: + - idempotency_nm_anstest_imp_tenant_absent_orchestrator_only_yes is not changed + - idempotency_nm_anstest_imp_tenant_absent_orchestrator_only_yes.current == {} + - idempotency_nm_anstest_imp_tenant_absent_orchestrator_only_yes.previous == {} + +- name: Import "anstest_imp_tenant" to the MSO with normal mode once again + mso_tenant: + <<: *nm_import_anstest_imp_tenant_present + register: nm_import_tenant_once_again + +- name: Assertions check for import "anstest_imp_tenant" to the MSO with normal mode once again + assert: + that: + - nm_import_tenant_once_again is changed + - nm_import_tenant_once_again.current != {} + - nm_import_tenant_once_again.previous == {} + - nm_import_tenant_once_again.current.name == "anstest_imp_tenant" + - nm_import_tenant_once_again.current.displayName == "anstest_imp_tenant_display_name" + - nm_import_tenant_once_again.current.description == "anstest_imp_tenant_description" + +- name: Update "anstest_imp_tenant" tenant description with check mode + mso_tenant: &cm_update_anstest_imp_tenant + <<: *nm_import_anstest_imp_tenant_present + description: "updated_anstest_imp_tenant_description" + check_mode: yes + register: cm_update_anstest_imp_tenant + +- name: Assertions check for update "anstest_imp_tenant" tenant description with check mode + assert: + that: + - cm_update_anstest_imp_tenant is changed + - cm_update_anstest_imp_tenant.current != {} + - cm_update_anstest_imp_tenant.previous != {} + - cm_update_anstest_imp_tenant.current.name == "anstest_imp_tenant" + - cm_update_anstest_imp_tenant.current.displayName == "anstest_imp_tenant_display_name" + - cm_update_anstest_imp_tenant.current.description == "updated_anstest_imp_tenant_description" + - cm_update_anstest_imp_tenant.previous.name == "anstest_imp_tenant" + - cm_update_anstest_imp_tenant.previous.displayName == "anstest_imp_tenant_display_name" + - cm_update_anstest_imp_tenant.previous.description == "anstest_imp_tenant_description" + +- name: Update "anstest_imp_tenant" tenant description with normal mode + mso_tenant: &nm_update_anstest_imp_tenant + <<: *cm_update_anstest_imp_tenant + register: nm_update_anstest_imp_tenant + +- name: Assertions check for update "anstest_imp_tenant" tenant description with normal mode + assert: + that: + - nm_update_anstest_imp_tenant is changed + - nm_update_anstest_imp_tenant.current != {} + - nm_update_anstest_imp_tenant.previous != {} + - nm_update_anstest_imp_tenant.current.name == "anstest_imp_tenant" + - nm_update_anstest_imp_tenant.current.displayName == "anstest_imp_tenant_display_name" + - nm_update_anstest_imp_tenant.current.description == "updated_anstest_imp_tenant_description" + - nm_update_anstest_imp_tenant.previous.name == "anstest_imp_tenant" + - nm_update_anstest_imp_tenant.previous.displayName == "anstest_imp_tenant_display_name" + - nm_update_anstest_imp_tenant.previous.description == "anstest_imp_tenant_description" + +- name: Update "anstest_imp_tenant" tenant description with normal mode - idempotency works + mso_tenant: + <<: *nm_update_anstest_imp_tenant + register: nm_idempotency_update_anstest_imp_tenant + +- name: Idempotency assertions check for update "anstest_imp_tenant" tenant description with normal mode + assert: + that: + - nm_idempotency_update_anstest_imp_tenant is not changed + - nm_idempotency_update_anstest_imp_tenant.current != {} + - nm_idempotency_update_anstest_imp_tenant.previous != {} + - nm_idempotency_update_anstest_imp_tenant.current.name == "anstest_imp_tenant" + - nm_idempotency_update_anstest_imp_tenant.current.displayName == "anstest_imp_tenant_display_name" + - nm_idempotency_update_anstest_imp_tenant.current.description == "updated_anstest_imp_tenant_description" + - nm_idempotency_update_anstest_imp_tenant.previous.name == "anstest_imp_tenant" + - nm_idempotency_update_anstest_imp_tenant.previous.displayName == "anstest_imp_tenant_display_name" + - nm_idempotency_update_anstest_imp_tenant.previous.description == "updated_anstest_imp_tenant_description" + +# Orchestrator Only no will remove the tenant from MSO and APIC +- name: Remove "anstest_imp_tenant" tenant from MSO and APIC using orchestrator_only flag value no with check mode + mso_tenant: &cm_anstest_imp_tenant_absent_orchestrator_only_no + <<: *mso_info + tenant: anstest_imp_tenant + orchestrator_only: no + state: absent + check_mode: yes + register: cm_anstest_imp_tenant_absent_orchestrator_only_no + +- name: Assertions check for remove "anstest_imp_tenant" tenant from MSO and APIC using orchestrator_only flag value no with check mode + assert: + that: + - cm_anstest_imp_tenant_absent_orchestrator_only_no is changed + - cm_anstest_imp_tenant_absent_orchestrator_only_no.current == {} + - cm_anstest_imp_tenant_absent_orchestrator_only_no.previous != {} + - cm_anstest_imp_tenant_absent_orchestrator_only_no.previous.name == "anstest_imp_tenant" + - cm_anstest_imp_tenant_absent_orchestrator_only_no.previous.displayName == "anstest_imp_tenant_display_name" + - cm_anstest_imp_tenant_absent_orchestrator_only_no.previous.description == "updated_anstest_imp_tenant_description" + +- name: Remove "anstest_imp_tenant" tenant from MSO and APIC using orchestrator_only flag value no with normal mode + mso_tenant: &nm_anstest_imp_tenant_absent_orchestrator_only_no + <<: *cm_anstest_imp_tenant_absent_orchestrator_only_no + register: nm_anstest_imp_tenant_absent_orchestrator_only_no + +- name: Assertions check for remove "anstest_imp_tenant" tenant from MSO and APIC using orchestrator_only flag value no with normal mode + assert: + that: + - nm_anstest_imp_tenant_absent_orchestrator_only_no is changed + - nm_anstest_imp_tenant_absent_orchestrator_only_no.current == {} + - nm_anstest_imp_tenant_absent_orchestrator_only_no.previous != {} + - nm_anstest_imp_tenant_absent_orchestrator_only_no.previous.name == "anstest_imp_tenant" + - nm_anstest_imp_tenant_absent_orchestrator_only_no.previous.displayName == "anstest_imp_tenant_display_name" + - nm_anstest_imp_tenant_absent_orchestrator_only_no.previous.description == "updated_anstest_imp_tenant_description" + +- name: Remove "anstest_imp_tenant" tenant from MSO and APIC using orchestrator_only flag value no with normal mode - idempotency works + mso_tenant: + <<: *nm_anstest_imp_tenant_absent_orchestrator_only_no + register: idempotency_nm_anstest_imp_tenant_absent_orchestrator_only_no + +- name: Idempotency assertions check for remove "anstest_imp_tenant" tenant from MSO and APIC using orchestrator_only flag value no with normal mode + assert: + that: + - idempotency_nm_anstest_imp_tenant_absent_orchestrator_only_no is not changed + - idempotency_nm_anstest_imp_tenant_absent_orchestrator_only_no.current == {} + - idempotency_nm_anstest_imp_tenant_absent_orchestrator_only_no.previous == {} diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_tenant_site/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_tenant_site/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_tenant_site/aliases @@ -0,0 +1,2 @@ +# No ACI MultiSite infrastructure, so not enabled +# unsupported 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 new file mode 100644 index 00000000..c1f75569 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_tenant_site/tasks/main.yml @@ -0,0 +1,679 @@ +# Test code for the MSO modules +# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com> (based on mso_site test case) +# Copyright: (c) 2020, Lionel Hercot (@lhercot) <lhercot@cisco.com> +# Copyright: (c) 2020, Shreyas Srish (@shrsr) <ssrish@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") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Remove schemas + mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Dissociate clouds that are associated with ansible_tenant + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: '{{ item }}' + state: absent + loop: + - '{{ mso_site | default("ansible_test") }}' + - 'aws_{{ mso_site | default("ansible_test") }}' + - 'azure_{{ mso_site | default("ansible_test") }}' + ignore_errors: yes + +- name: Remove tenant ansible_test + mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + state: absent + +- name: Ensure non-cloud site exists + mso_site: + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + apic_username: '{{ apic_username }}' + apic_password: '{{ apic_password }}' + apic_site_id: '{{ apic_site_id }}' + urls: + - https://{{ apic_hostname }} + state: present + +- name: Ensure azure site exists + mso_site: + <<: *mso_info + site: 'azure_{{ mso_site | default("ansible_test") }}' + apic_username: '{{ azure_apic_username }}' + apic_password: '{{ azure_apic_password }}' + apic_site_id: '{{ azure_site_id | default(103) }}' + urls: + - https://{{ azure_apic_hostname }} + state: present + +- name: Ensure aws site exists + mso_site: + <<: *mso_info + site: 'aws_{{ mso_site | default("ansible_test") }}' + apic_username: '{{ aws_apic_username }}' + apic_password: '{{ aws_apic_password }}' + apic_site_id: '{{ aws_site_id | default(102) }}' + urls: + - https://{{ aws_apic_hostname }} + state: present + +- name: Ensure tenant ansible_test exists + mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + state: present + +- name: Associate non-cloud site with ansible_test in check mode + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: '{{ mso_site | default("ansible_test") }}' + state: present + check_mode: yes + register: ncs_cm + +- name: Verify ncs_cm + assert: + that: + - ncs_cm is changed + +- name: Associate non-cloud site with ansible_test in normal mode + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: '{{ mso_site | default("ansible_test") }}' + state: present + register: ncs_nm + +- name: Verify ncs_nm + assert: + that: + - ncs_nm is changed + +- name: Associate non-cloud site with ansible_test again in normal mode + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: '{{ mso_site | default("ansible_test") }}' + state: present + register: ncs_nm_again + +- name: Verify ncs_nm_again + assert: + that: + - ncs_nm_again is not changed + +- name: Associate aws site with ansible_test in check mode + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'aws_{{ mso_site | default("ansible_test") }}' + cloud_account: "000000000000" + aws_trusted: false + aws_access_key: "1" + secret_key: "0" + state: present + check_mode: yes + register: aaws_cm + +- name: Verify aaws_cm + assert: + that: + - aaws_cm is changed + - aaws_cm.current.awsAccount != 'null' + - aaws_cm.current.awsAccount[0].isAccountInOrg == false + - aaws_cm.current.awsAccount[0].isTrusted == false + +- name: Associate aws site with ansible_test in normal mode + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'aws_{{ mso_site | default("ansible_test") }}' + cloud_account: "000000000000" + aws_trusted: false + aws_access_key: "1" + secret_key: "0" + state: present + register: aaws_nm + +- name: Verify aaws_nm + assert: + that: + - aaws_nm is changed + - aaws_nm.current.awsAccount != 'null' + - aaws_nm.current.awsAccount[0].isAccountInOrg == false + - aaws_nm.current.awsAccount[0].isTrusted == false + +- name: Associate aws site with ansible_test again in normal mode + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'aws_{{ mso_site | default("ansible_test") }}' + cloud_account: "000000000000" + aws_trusted: false + aws_access_key: "1" + secret_key: "0" + state: present + register: aaws_nm_again + +- name: Verify aaws_nm_again + assert: + that: + - aaws_nm_again is not changed + +- name: Associate aws site with ansible_test in normal mode when aws_trusted is false and aws_access_key is missing + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'aws_{{ mso_site | default("ansible_test") }}' + cloud_account: "000000000000" + aws_trusted: false + secret_key: "0" + state: present + ignore_errors: yes + register: aaws_nm_ak + +- name: Verify aaws_nm_ak + assert: + that: + - aaws_nm_ak.msg is match ("aws_access_key is a required field in untrusted mode.") + +- name: Associate aws site with ansible_test in normal mode when aws_trusted is true + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'aws_{{ mso_site | default("ansible_test") }}' + cloud_account: "000000000000" + aws_trusted: true + state: present + register: aws_nm_trusted + +- name: Verify aws_nm_trusted + assert: + that: + - aws_nm_trusted is changed + +- name: Associate aws site with ansible_test in normal mode when aws_trusted is false and secret_key is missing + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'aws_{{ mso_site | default("ansible_test") }}' + cloud_account: "000000000000" + aws_trusted: false + aws_access_key: "1" + state: present + ignore_errors: yes + register: aaws_nm_sk + +- name: Verify aaws_nm_sk + assert: + that: + - aaws_nm_sk.msg is match ("secret_key is a required field in untrusted mode.") + +- name: Associate aws site with ansible_test, with organization mode true + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'aws_{{ mso_site | default("ansible_test") }}' + aws_account_org: true + cloud_account: "000000000000" + secret_key: "0" + aws_access_key: "1" + state: present + ignore_errors: yes + register: aaws_nm_om + +- name: Verify aaws_nm_om + assert: + that: + - aaws_nm_om.current.awsAccount[0].isAccountInOrg == true + +- name: Associate azure site with access_type not present, with ansible_test in normal mode + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'azure_{{ mso_site | default("ansible_test") }}' + cloud_account: uni/tn-ansible_test/act-[100]-vendor-azure + state: present + register: aazure_shared_nm + +- name: Verify aazure_shared_nm + assert: + that: + - aazure_shared_nm is changed + +- name: Associate azure site in shared mode with ansible_test in normal mode + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'azure_{{ mso_site | default("ansible_test") }}' + cloud_account: uni/tn-ansible_test/act-[100]-vendor-azure + azure_access_type: shared + state: present + register: aazure_shared_nm + +- name: Verify aazure_shared_nm + assert: + that: + - aazure_shared_nm is not changed + +- name: Associate azure site with managed mode, with ansible_test in normal mode having no application_id + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'azure_{{ mso_site | default("ansible_test") }}' + azure_subscription_id: "9" + cloud_account: uni/tn-ansible_test/act-[9]-vendor-azure + azure_access_type: managed + state: present + ignore_errors: yes + register: aazure_managed_nm_app + +- name: Verify aazure_managed_nm_app + assert: + that: + - aazure_managed_nm_app.msg is match ("azure_application_id is required when in managed mode.") + +- name: Associate azure site with managed mode, with ansible_test in normal mode having no subscription_id + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'azure_{{ mso_site | default("ansible_test") }}' + azure_application_id: "100" + cloud_account: uni/tn-ansible_test/act-[9]-vendor-azure + azure_access_type: managed + state: present + ignore_errors: yes + register: aazure_managed_nm_si + +- name: Verify aazure_managed_nm_si + assert: + that: + - aazure_managed_nm_si.msg is match ("azure_susbscription_id is required when in managed mode.") + +- name: Associate azure site with managed mode, with ansible_test in normal mode + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'azure_{{ mso_site | default("ansible_test") }}' + azure_subscription_id: "9" + azure_application_id: "100" + cloud_account: uni/tn-ansible_test/act-[9]-vendor-azure + azure_access_type: managed + state: present + ignore_errors: yes + register: aazure_managed_nm + +- name: Verify aazure_managed_nm + assert: + that: + - aazure_managed_nm is changed + - aazure_managed_nm.current.azureAccount != 'null' + - aazure_managed_nm.current.azureAccount[0].cloudSubscription.cloudApplicationId == '100' + - aazure_managed_nm.current.azureAccount[0].cloudSubscription.cloudSubscriptionId == '9' + - aazure_managed_nm.current.azureAccount[0].cloudApplication == [] + - aazure_managed_nm.current.azureAccount[0].cloudActiveDirectory == [] + +- name: Associate azure site with credentials mode, with ansible_test in normal mode having no azure_subscription_id + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'azure_{{ mso_site | default("ansible_test") }}' + azure_application_id: "100" + azure_credential_name: cApicApp + secret_key: iins + azure_active_directory_id: "32" + azure_active_directory_name: CiscoINSBUAd + cloud_account: uni/tn-ansible_test/act-[9]-vendor-azure + azure_access_type: unmanaged + state: present + ignore_errors: yes + register: aazure_credentials_nm_si + +- name: Verify aazure_credentials_nm_si + assert: + that: + - aazure_credentials_nm_si.msg is match ("azure_subscription_id is required when in unmanaged mode.") + +- name: Associate azure site with credentials mode, with ansible_test in normal mode having no azure_application_id + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'azure_{{ mso_site | default("ansible_test") }}' + azure_subscription_id: "9" + azure_credential_name: cApicApp + secret_key: iins + azure_active_directory_id: "32" + azure_active_directory_name: CiscoINSBUAd + cloud_account: uni/tn-ansible_test/act-[9]-vendor-azure + azure_access_type: unmanaged + state: present + ignore_errors: yes + register: aazure_credentials_nm_app + +- name: Verify aazure_credentials_nm_app + assert: + that: + - aazure_credentials_nm_app.msg is match ("azure_application_id is required when in unmanaged mode.") + +- name: Associate azure site with credentials mode, with ansible_test in normal mode having no secret_key + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'azure_{{ mso_site | default("ansible_test") }}' + azure_subscription_id: "9" + azure_credential_name: cApicApp + azure_active_directory_id: "32" + azure_active_directory_name: CiscoINSBUAd + azure_application_id: "100" + cloud_account: uni/tn-ansible_test/act-[9]-vendor-azure + azure_access_type: unmanaged + state: present + ignore_errors: yes + register: aazure_credentials_nm_secret + +- name: Verify aazure_credentials_nm_secret + assert: + that: + - aazure_credentials_nm_secret.msg is match ("secret_key is required when in unmanaged mode.") + +- name: Associate azure site with credentials mode, with ansible_test in normal mode having no azure_active_directory_id + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'azure_{{ mso_site | default("ansible_test") }}' + azure_subscription_id: "9" + azure_credential_name: cApicApp + azure_active_directory_name: CiscoINSBUAd + azure_application_id: "100" + secret_key: iins + cloud_account: uni/tn-ansible_test/act-[9]-vendor-azure + azure_access_type: unmanaged + state: present + ignore_errors: yes + register: aazure_credentials_nm_ad + +- name: Verify aazure_credentials_nm_ad + assert: + that: + - aazure_credentials_nm_ad.msg is match ("azure_active_directory_id is required when in unmanaged mode.") + +- name: Associate azure site with credentials mode, with ansible_test in normal mode having no azure_active_directory_name + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'azure_{{ mso_site | default("ansible_test") }}' + azure_subscription_id: "9" + azure_credential_name: cApicApp + secret_key: iins + azure_active_directory_id: "32" + azure_application_id: "100" + cloud_account: uni/tn-ansible_test/act-[9]-vendor-azure + azure_access_type: unmanaged + state: present + ignore_errors: yes + register: aazure_credentials_nm_adn + +- name: Verify aazure_credentials_nm_adn + assert: + that: + - aazure_credentials_nm_adn.msg is match ("azure_active_directory_name is required when in unmanaged mode.") + +- name: Associate azure site with credentials mode, with ansible_test in normal mode having no azure_credential_name + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'azure_{{ mso_site | default("ansible_test") }}' + azure_subscription_id: "9" + secret_key: iins + azure_active_directory_name: CiscoINSBUAd + azure_active_directory_id: "32" + azure_application_id: "100" + cloud_account: uni/tn-ansible_test/act-[9]-vendor-azure + azure_access_type: unmanaged + state: present + ignore_errors: yes + register: aazure_credentials_nm_cdn + +- name: Verify aazure_credentials_nm_cdn + assert: + that: + - aazure_credentials_nm_cdn.msg is match ("azure_credential_name is required when in unmanaged mode.") + +- name: Associate azure site with credentials mode, with ansible_test in normal mode + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'azure_{{ mso_site | default("ansible_test") }}' + azure_subscription_id: "9" + azure_application_id: "100" + azure_credential_name: cApicApp + secret_key: iins + azure_active_directory_id: "32" + azure_active_directory_name: CiscoINSBUAd + cloud_account: uni/tn-ansible_test/act-[9]-vendor-azure + azure_access_type: unmanaged + state: present + register: aazure_credentials_nm + +- name: Verify aazure_credentials_nm + assert: + that: + - aazure_credentials_nm is changed + - aazure_credentials_nm.current.azureAccount[0].cloudSubscription.cloudApplicationId == '100' + - aazure_credentials_nm.current.azureAccount[0].cloudSubscription.cloudSubscriptionId == '9' + - aazure_credentials_nm.current.azureAccount[0].cloudActiveDirectory[0].cloudActiveDirectoryId == '32' + - aazure_credentials_nm.current.azureAccount[0].cloudActiveDirectory[0].cloudActiveDirectoryName == 'CiscoINSBUAd' + - aazure_credentials_nm.current.azureAccount[0].cloudApplication[0].cloudApplicationId == '100' + - aazure_credentials_nm.current.azureAccount[0].cloudApplication[0].cloudActiveDirectoryId == '32' + - aazure_credentials_nm.current.azureAccount[0].cloudApplication[0].cloudCredentialName == 'cApicApp' + +- name: Associate azure site with credentials mode, with ansible_test again in normal mode + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'azure_{{ mso_site | default("ansible_test") }}' + azure_subscription_id: "9" + azure_application_id: "100" + azure_credential_name: cApicApp + secret_key: iins + azure_active_directory_id: "32" + azure_active_directory_name: CiscoINSBUAd + cloud_account: uni/tn-ansible_test/act-[9]-vendor-azure + azure_access_type: unmanaged + state: present + register: aazure_credentials_nm_again + +- name: Verify aazure_credentials_nm_again + assert: + that: + - aazure_credentials_nm_again is not changed + +- name: Query associated non-cloud site of a tenant + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: '{{ mso_site | default("ansible_test") }}' + state: query + register: anc_query + +- name: Verify anc_query + assert: + that: + - anc_query is not changed + +- name: Query associated azure site of a tenant + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'azure_{{ mso_site | default("ansible_test") }}' + azure_subscription_id: "9" + azure_application_id: "100" + azure_credential_name: cApicApp + secret_key: iins + azure_active_directory_id: "32" + azure_active_directory_name: CiscoINSBUAd + cloud_account: uni/tn-ansible_test/act-[9]-vendor-azure + azure_access_type: unmanaged + state: query + register: aazure_query + +- name: Verify aazure_query + assert: + that: + - aazure_query is not changed + +- name: Query associated aws site of a tenant + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'aws_{{ mso_site | default("ansible_test") }}' + state: query + register: aaws_query + +- name: Verify aaws_query + assert: + that: + - aaws_query is not changed + +- name: Query all associated sites of a tenant + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + state: query + register: all_sites_query + +- name: Verify all_sites_query + assert: + that: + - all_sites_query is not changed + +- name: Dissociate non-cloud site with ansible_test + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: '{{ mso_site | default("ansible_test") }}' + state: absent + register: dnc + +- name: Verify dnc + assert: + that: + - dnc is changed + +- name: Query dissociated non-cloud site of a tenant + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: '{{ mso_site | default("ansible_test") }}' + state: query + ignore_errors: yes + register: dnc_query + +- name: Verify dnc_query + assert: + that: + - dnc_query.msg is match ("Site Id [0-9a-zA-Z]* not associated with tenant Id [0-9a-zA-Z]*") + +- name: Dissociate azure site with ansible_test + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'azure_{{ mso_site | default("ansible_test") }}' + state: absent + register: dazure + +- name: Verify dazure + assert: + that: + - dazure is changed + +- name: Query dissociated azure site of a tenant + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'azure_{{ mso_site | default("ansible_test") }}' + state: query + ignore_errors: yes + register: dazure_query + +- name: Verify dnc_query + assert: + that: + - dazure_query.msg is match ("Site Id [0-9a-zA-Z]* not associated with tenant Id [0-9a-zA-Z]*") + +- name: Dissociate aws site with ansible_test + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'aws_{{ mso_site | default("ansible_test") }}' + state: absent + register: daaws + +- name: Verify daaws + assert: + that: + - daaws is changed + +- name: Query dissociated aws site of a tenant + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'aws_{{ mso_site | default("ansible_test") }}' + state: query + ignore_errors: yes + register: daaws_query + +- name: Verify daaws_query + assert: + that: + - daaws_query.msg is match ("No site associated with tenant Id [0-9a-zA-Z]*") + +- name: Query all + mso_tenant_site: + <<: *mso_info + tenant: ansible_test + state: query + ignore_errors: yes + register: query_all + +- name: Verify query_all + assert: + that: + - query_all.msg is match ("No site associated with tenant Id [0-9a-zA-Z]*")
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_user/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_user/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_user/aliases @@ -0,0 +1,2 @@ +# No ACI MultiSite infrastructure, so not enabled +# unsupported diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_user/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/mso_user/tasks/main.yml new file mode 100644 index 00000000..2876732e --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_user/tasks/main.yml @@ -0,0 +1,511 @@ +# Test code for the MSO modules +# Copyright: (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.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 + +- 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") }}' + +- name: Query MSO version + mso_version: + <<: *mso_info + state: query + register: version + +- name: Execute tasks only for MSO version < 3.2 + when: version.current.version is version('3.2', '<') + block: + # CLEAN ENVIRONMENT + - name: Remove user ansible_test + mso_user: &user_absent + <<: *mso_info + user: '{{ item }}' + state: absent + loop: + - ansible_test + - ansible_test2 + - ansible_test_read + - ansible_test_read_2 + + # ADD USER + - name: Add user (check_mode) + mso_user: &user_present + <<: *mso_info + user: ansible_test + user_password: 'S0m3!1n1t14l!p455w0rd' + # NOTE: First name, last name, phone and email are mandatory on creation + first_name: Ansible + last_name: Test + email: mso@cisco.com + phone: +32 478 436 299 + account_status: active + roles: + - name: powerUser + access_type: write + domain: Local + state: present + check_mode: yes + register: cm_add_user + + - name: Verify cm_add_user + assert: + that: + - cm_add_user is changed + - cm_add_user.previous == {} + - cm_add_user.current.id is not defined + - cm_add_user.current.username == 'ansible_test' + - cm_add_user.current.lastName == 'Test' + - cm_add_user.current.firstName == 'Ansible' + - cm_add_user.current.emailAddress == 'mso@cisco.com' + - cm_add_user.current.phoneNumber == '+32 478 436 299' + - cm_add_user.current.accountStatus == 'active' + - cm_add_user.current.roles[0].accessType == 'readWrite' + + - name: Add user (normal mode) + mso_user: *user_present + register: nm_add_user + + - name: Verify nm_add_user + assert: + that: + - nm_add_user is changed + - nm_add_user.previous == {} + - nm_add_user.current.id is defined + - nm_add_user.current.username == 'ansible_test' + - nm_add_user.current.lastName == 'Test' + - nm_add_user.current.firstName == 'Ansible' + - nm_add_user.current.emailAddress == 'mso@cisco.com' + - nm_add_user.current.phoneNumber == '+32 478 436 299' + - nm_add_user.current.accountStatus == 'active' + - nm_add_user.current.roles[0].accessType == 'readWrite' + + - name: Add user again (check_mode) + mso_user: + <<: *user_present + # NOTE: We need to modify the password for a new user + user_password: 'S0m3!n3w!p455w0rd' + check_mode: yes + register: cm_add_user_again + + - name: Verify cm_add_user_again + assert: + that: + - cm_add_user_again is changed + - cm_add_user_again.previous.username == 'ansible_test' + - cm_add_user_again.current.id == nm_add_user.current.id + - cm_add_user_again.current.username == 'ansible_test' + + - name: Add user again (normal mode) + mso_user: + <<: *user_present + # NOTE: We need to modify the password for a new user + user_password: 'S0m3!n3w!p455w0rd' + register: nm_add_user_again + + - name: Verify nm_add_user_again + assert: + that: + - nm_add_user_again is changed + - nm_add_user_again.previous.username == 'ansible_test' + - nm_add_user_again.current.id == nm_add_user.current.id + - nm_add_user_again.current.username == 'ansible_test' + + - name: Add user with read only role (check_mode) + mso_user: &user_present2 + <<: *mso_info + user: ansible_test_read + user_password: '#123455#123455Aa' + # NOTE: First name, last name, phone and email are mandatory on creation + first_name: Ansible2 + last_name: Test2 + email: mso3@cisco.com + phone: +32 478 436 299 + account_status: active + roles: + - name: powerUser + access_type: read + domain: Local + state: present + check_mode: yes + register: cm_add_user2 + + - name: Verify cm_add_user2 + assert: + that: + - cm_add_user2 is changed + - cm_add_user2.previous == {} + - cm_add_user2.current.id is not defined + - cm_add_user2.current.username == 'ansible_test_read' + - cm_add_user2.current.lastName == 'Test2' + - cm_add_user2.current.firstName == 'Ansible2' + - cm_add_user2.current.emailAddress == 'mso3@cisco.com' + - cm_add_user2.current.phoneNumber == '+32 478 436 299' + - cm_add_user2.current.accountStatus == 'active' + - cm_add_user2.current.roles[0].accessType == 'readOnly' + + - name: Add user with read only role (normal mode) + mso_user: *user_present2 + register: nm_add_user2 + + - name: Verify nm_add_user2 + assert: + that: + - nm_add_user2 is changed + - nm_add_user2.current.id is defined + - nm_add_user2.current.username == 'ansible_test_read' + - nm_add_user2.current.lastName == 'Test2' + - nm_add_user2.current.firstName == 'Ansible2' + - nm_add_user2.current.emailAddress == 'mso3@cisco.com' + - nm_add_user2.current.phoneNumber == '+32 478 436 299' + - nm_add_user2.current.accountStatus == 'active' + - nm_add_user2.current.roles[0].accessType == 'readOnly' + + - name: Add user with read only role again (check mode) + mso_user: + <<: *user_present2 + user_password: '#123455#123455Aa' + check_mode: yes + register: cm_add_user2_again + + - name: Add user with read only role again (normal mode) + mso_user: *user_present2 + register: nm_add_user2 + + - name: Add user3 with read only role and no password (check_mode) + mso_user: &user_present3 + <<: *mso_info + user: ansible_test_read_2 + # NOTE: First name, last name, phone and email are mandatory on creation + first_name: Ansible3 + #user_password: '#123455#123455Aa' + last_name: Test3 + email: mso4@cisco.com + phone: +32 478 436 299 + account_status: active + roles: + - name: powerUser + access_type: read + domain: Local + state: present + ignore_errors: yes + register: nm_add_user3 + + - name: Verify nm_add_user2 + assert: + that: + - nm_add_user3.msg == "The user ansible_test_read_2 does not exist. The 'user_password' attribute is required to create a new user." + + - name: Add user3 with read only role and with password (normal mode) + mso_user: + <<: *user_present3 + user_password: '#123455#123455Aa' + register: nm_add_user3_again + + - name: Verify nm_add_user3_again + assert: + that: + - nm_add_user3_again is changed + - nm_add_user3_again.current.id is defined + - nm_add_user3_again.current.username == 'ansible_test_read_2' + - nm_add_user3_again.current.lastName == 'Test3' + - nm_add_user3_again.current.firstName == 'Ansible3' + - nm_add_user3_again.current.emailAddress == 'mso4@cisco.com' + - nm_add_user3_again.current.phoneNumber == '+32 478 436 299' + - nm_add_user3_again.current.accountStatus == 'active' + - nm_add_user3_again.current.roles[0].accessType == 'readOnly' + + # CHANGE USER + - name: Change user (check_mode) + mso_user: &user_change + <<: *mso_info + user: ansible_test + roles: + - name: powerUser + access_type: write + domain: Local + state: present + # FIXME: Add support for name change + email: mso2@cisco.com + phone: +32 478 436 300 + check_mode: yes + register: cm_change_user + + - name: Verify cm_change_user + assert: + that: + - cm_change_user is changed + - cm_change_user.current.id == nm_add_user.current.id + - cm_change_user.current.username == 'ansible_test' + - cm_change_user.current.emailAddress == 'mso2@cisco.com' + - cm_change_user.current.phoneNumber == '+32 478 436 300' + + - name: Change user (normal mode) + mso_user: + <<: *user_change + output_level: debug + register: nm_change_user + + - name: Verify nm_change_user + assert: + that: + - nm_change_user is changed + - nm_change_user.current.id == nm_add_user.current.id + - nm_change_user.current.username == 'ansible_test' + - nm_change_user.current.emailAddress == 'mso2@cisco.com' + - nm_change_user.current.phoneNumber == '+32 478 436 300' + + - name: Change user again (check_mode) + mso_user: + <<: *user_change + check_mode: yes + register: cm_change_user_again + + - name: Verify cm_change_user_again + assert: + that: + - cm_change_user_again is not changed + - cm_change_user_again.current.id == nm_add_user.current.id + - cm_change_user_again.current.username == 'ansible_test' + - cm_change_user_again.current.emailAddress == 'mso2@cisco.com' + - cm_change_user_again.current.phoneNumber == '+32 478 436 300' + + - name: Change user again (normal mode) + mso_user: + <<: *user_change + register: nm_change_user_again + + - name: Verify nm_change_user_again + assert: + that: + - nm_change_user_again is not changed + - nm_change_user_again.current.id == nm_add_user.current.id + - nm_change_user_again.current.username == 'ansible_test' + - nm_change_user_again.current.emailAddress == 'mso2@cisco.com' + - nm_change_user_again.current.phoneNumber == '+32 478 436 300' + + - name: Add second user + mso_user: + <<: *user_change + user: ansible_test2 + user_password: 'S0m3!1n1t14l!p455w0rd' + first_name: Ansible + last_name: Test + roles: + - powerUser + state: present + register: nm_add_user_2 + + - name: Change user 2 again (normal mode) + mso_user: + <<: *user_change + user: ansible_test2 + user_password: null + first_name: Ansible + last_name: Test + register: nm_change_user_2_again + + - name: Verify nm_change_user_2_again + assert: + that: + - nm_change_user_2_again is not changed + - nm_change_user_2_again.current.id == nm_add_user_2.current.id + - nm_change_user_2_again.current.username == 'ansible_test2' + + # TODO: Add query with user ansible_test2 to try if user can login. + +# QUERY ALL USERS +- name: Query all users (check_mode) + mso_user: &user_query + <<: *mso_info + state: query + check_mode: yes + register: cm_query_all_users + +- name: Query all users (normal mode) + mso_user: *user_query + register: nm_query_all_users + +- name: Verify query_all_users + assert: + that: + - cm_query_all_users is not changed + - nm_query_all_users is not changed + # NOTE: Order of users is not stable between calls + #- cm_query_all_users == nm_query_all_users + + +# QUERY A USER +- name: Query our user + mso_user: + <<: *user_query + user: '{{ mso_username }}' + check_mode: yes + register: cm_query_user + +- name: Query our user + mso_user: + <<: *user_query + user: '{{ mso_username }}' + register: nm_query_user + +- name: Verify query_user + assert: + that: + - cm_query_user is not changed + - cm_query_user.current.id is defined + - cm_query_user.current.username == '{{ mso_username }}' + - nm_query_user is not changed + - nm_query_user.current.id is defined + - nm_query_user.current.username == '{{ mso_username }}' + - cm_query_user == nm_query_user + +- name: Execute tasks only for MSO version < 3.2 + when: version.current.version is version('3.2', '<') + block: + - name: Query our read-only user + mso_user: + <<: *user_query + user: ansible_test_read + register: nm_query_user2 + + - name: Verify query_user2 + assert: + that: + - nm_query_user2 is not changed + - nm_query_user2.current.roles[0].accessType == 'readOnly' + + # REMOVE USER + - name: Remove user (check_mode) + mso_user: + <<: *user_absent + user: ansible_test + state: absent + check_mode: yes + register: cm_remove_user + + - name: Verify cm_remove_user + assert: + that: + - cm_remove_user is changed + - cm_remove_user.current == {} + + - name: Remove user (normal mode) + mso_user: + <<: *user_absent + user: ansible_test + state: absent + register: nm_remove_user + + - name: Verify nm_remove_user + assert: + that: + - nm_remove_user is changed + - nm_remove_user.current == {} + + - name: Remove user again (check_mode) + mso_user: + <<: *user_absent + user: ansible_test + state: absent + check_mode: yes + register: cm_remove_user_again + + - name: Verify cm_remove_user_again + assert: + that: + - cm_remove_user_again is not changed + - cm_remove_user_again.current == {} + + - name: Remove user again (normal mode) + mso_user: + <<: *user_absent + user: ansible_test + state: absent + register: nm_remove_user_again + + - name: Verify nm_remove_user_again + assert: + that: + - nm_remove_user_again is not changed + - nm_remove_user_again.current == {} + +# QUERY NON-EXISTING USER +- name: Query non-existing user (check_mode) + mso_user: + <<: *user_query + user: ansible_test + check_mode: yes + register: cm_query_non_user + +- name: Query non-existing user (normal mode) + mso_user: + <<: *user_query + user: ansible_test + register: nm_query_non_user + +# TODO: Implement more tests +- name: Verify query_non_user + assert: + that: + - cm_query_non_user is not changed + - nm_query_non_user is not changed + - cm_query_non_user == nm_query_non_user + +- name: Execute tasks only for MSO version < 3.2 + when: version.current.version is version('3.2', '<') + block: + - name: inactive user (check_mode) + mso_user: + <<: *user_present + account_status: inactive + check_mode: yes + register: cm_inactive_user + + - name: inactive user (normal_mode) + mso_user: + <<: *user_present + account_status: inactive + register: nm_inactive_user + + - name: Verify cm_inactive_user and nm_inactive_user + assert: + that: + - cm_inactive_user is changed + - nm_inactive_user is changed + - cm_inactive_user.current.accountStatus == "inactive" + - nm_inactive_user.current.accountStatus == "inactive" + + + - name: active user (check_mode) + mso_user: + <<: *user_present + account_status: active + check_mode: yes + register: cm_active_user + + - name: active user (normal_mode) + mso_user: + <<: *user_present + account_status: active + register: nm_active_user + + - name: Verify cm_active_user and nm_active_user + assert: + that: + - cm_active_user is changed + - nm_active_user is changed + - cm_active_user.previous.accountStatus == nm_active_user.previous.accountStatus == "inactive" + - cm_active_user.current.accountStatus == nm_active_user.current.accountStatus == "active"
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/integration/targets/mso_version/aliases b/ansible_collections/cisco/mso/tests/integration/targets/mso_version/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_version/aliases @@ -0,0 +1,2 @@ +# No ACI MultiSite infrastructure, so not enabled +# unsupported 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 new file mode 100644 index 00000000..7114d4a9 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/mso_version/tasks/main.yml @@ -0,0 +1,96 @@ +# Test code for the MSO modules +# Copyright: (c) 2020, Lionel Hercot (@lhercot) <lhercot@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") }}' + +# QUERY VERSION +- name: Query MSO version + mso_version: &mso_query + <<: *mso_info + state: query + check_mode: yes + register: cm_query_version + +- name: Verify cm_query_version + assert: + that: + - cm_query_version is not changed + - cm_query_version.current.id is defined + - cm_query_version.current.version is defined + - cm_query_version.current.timestamp is defined + +- name: Query MSO version (normal mode) + mso_version: + <<: *mso_query + register: nm_query_version + +- name: Verify nm_query_version + assert: + that: + - nm_query_version is not changed + - nm_query_version.current.id is defined + - nm_query_version.current.version is defined + - nm_query_version.current.timestamp is defined + - nm_query_version.current.id == cm_query_version.current.id + - nm_query_version.current.version == cm_query_version.current.version + - nm_query_version.current.timestamp == cm_query_version.current.timestamp + +# USE A NON-EXISTING STATE +- name: Non-existing state for version (check_mode) + mso_version: + <<: *mso_query + state: non-existing-state + check_mode: yes + ignore_errors: yes + register: cm_non_existing_state + +- name: Non-existing state for version (normal_mode) + mso_version: + <<: *mso_query + state: non-existing-state + ignore_errors: yes + register: nm_non_existing_state + +- name: Verify non_existing_state + assert: + that: + - cm_non_existing_state is not changed + - nm_non_existing_state is not changed + - cm_non_existing_state == nm_non_existing_state + - cm_non_existing_state.msg == nm_non_existing_state.msg == "value of state must be one of{{':'}} query, got{{':'}} non-existing-state" + +# query without setting username&password in task +- name: Query MSO version + cisco.mso.mso_version: + state: query + register: query_version_global_params + when: ansible_connection != 'local' + +- name: Verify query_version_global_params + assert: + that: + - query_version_global_params is not changed + - query_version_global_params.current.id is defined + - query_version_global_params.current.version is defined + - query_version_global_params.current.timestamp is defined + - 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 diff --git a/ansible_collections/cisco/mso/tests/integration/targets/ndo_schema_template_deploy/aliases b/ansible_collections/cisco/mso/tests/integration/targets/ndo_schema_template_deploy/aliases new file mode 100644 index 00000000..5042c9c0 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/ndo_schema_template_deploy/aliases @@ -0,0 +1,2 @@ +# No ACI MultiSite infrastructure, so not enabled +# unsupported diff --git a/ansible_collections/cisco/mso/tests/integration/targets/ndo_schema_template_deploy/tasks/main.yml b/ansible_collections/cisco/mso/tests/integration/targets/ndo_schema_template_deploy/tasks/main.yml new file mode 100644 index 00000000..0dda3bbc --- /dev/null +++ b/ansible_collections/cisco/mso/tests/integration/targets/ndo_schema_template_deploy/tasks/main.yml @@ -0,0 +1,407 @@ +# Test code for the MSO modules +# Copyright: (c) 2022, 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: Test that we have an ACI MultiSite host, username and password + ansible.builtin.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 + ansible.builtin.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") }}' + +- name: Query MSO version + cisco.mso.mso_version: + <<: *mso_info + state: query + register: version + +- name: Ensure site exist + cisco.mso.mso_site: + <<: *mso_info + site: '{{ mso_site | default("ansible_test") }}' + apic_username: '{{ apic_username }}' + apic_password: '{{ apic_password }}' + apic_site_id: '{{ apic_site_id | default(101) }}' + urls: + - https://{{ apic_hostname }} + state: present + +- name: Ensure aws site exists + cisco.mso.mso_site: + <<: *mso_info + site: 'aws_{{ mso_site | default("ansible_test") }}' + apic_username: '{{ aws_apic_username }}' + apic_password: '{{ aws_apic_password }}' + apic_site_id: '{{ aws_site_id | default(102) }}' + urls: + - https://{{ aws_apic_hostname }} + state: present + +- name: Ensure azure site exists + cisco.mso.mso_site: + <<: *mso_info + site: 'azure_{{ mso_site | default("ansible_test") }}' + apic_username: '{{ azure_apic_username }}' + apic_password: '{{ azure_apic_password }}' + apic_site_id: '{{ azure_site_id | default(103) }}' + urls: + - https://{{ azure_apic_hostname }} + state: present + +- name: Undeploy template + cisco.mso.ndo_schema_template_deploy: + <<: *mso_info + schema: ansible_test + template: "{{ item }}" + sites: + - '{{ mso_site | default("ansible_test") }}' + state: undeploy + ignore_errors: yes + loop: + - Template 1 + - Template 2 + +- name: Remove schemas + cisco.mso.mso_schema: + <<: *mso_info + schema: '{{ item }}' + state: absent + loop: + - '{{ mso_schema | default("ansible_test") }}_2' + - '{{ mso_schema | default("ansible_test") }}' + +- name: Ensure tenant ansible_test exists + cisco.mso.mso_tenant: + <<: *mso_info + tenant: ansible_test + users: + - '{{ mso_username }}' + sites: + - '{{ mso_site | default("ansible_test") }}' + state: present + +- name: Ensure schema 1 with Template 1, and Template 2 exist + cisco.mso.mso_schema_template: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + tenant: ansible_test + template: '{{ item }}' + state: present + loop: + - Template 1 + - Template 2 + +- name: Add physical site to a schema + cisco.mso.mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: '{{ mso_site | default("ansible_test") }}' + template: '{{ item }}' + state: present + loop: + - Template 1 + - Template 2 + +- name: Deploy templates (check_mode) + cisco.mso.ndo_schema_template_deploy: + <<: *mso_info + schema: ansible_test + template: "{{ item }}" + sites: + - '{{ mso_site | default("ansible_test") }}' + state: deploy + check_mode: yes + register: cm_deploy_template + loop: + - Template 1 + - Template 2 + +- name: Verify cm_deploy_template + ansible.builtin.assert: + that: + - item is not changed + loop: "{{ cm_deploy_template.results }}" + +- name: Deploy templates (normal_mode) + cisco.mso.ndo_schema_template_deploy: + <<: *mso_info + schema: ansible_test + template: "{{ item }}" + sites: + - '{{ mso_site | default("ansible_test") }}' + state: deploy + register: nm_deploy_template + loop: + - Template 1 + - Template 2 + +- name: Verify nm_deploy_template + ansible.builtin.assert: + that: + - item is not changed + - '"isRedeploy" not in item.current.reqDetails' + loop: "{{ nm_deploy_template.results }}" + +- name: Verify nm_deploy_template 4.0 specific + ansible.builtin.assert: + that: + - '"deploy" in item.current.reqDetails' + loop: "{{ nm_deploy_template.results }}" + when: version.current.version is version('4.0', '>=') + +- name: Query deployment + cisco.mso.ndo_schema_template_deploy: + <<: *mso_info + schema: ansible_test + template: "{{ item }}" + state: query + register: query_deploy_status + loop: + - Template 1 + - Template 2 + +- name: Verify query_deploy_status + ansible.builtin.assert: + that: + - item is not changed + - item.current.status.0.status.siteStatus == "Succeeded" + loop: "{{ query_deploy_status.results }}" + +- name: Redeploy templates + cisco.mso.ndo_schema_template_deploy: + <<: *mso_info + schema: ansible_test + template: '{{ item }}' + sites: + - '{{ mso_site | default("ansible_test") }}' + state: redeploy + register: redeploy_template + loop: + - Template 1 + - Template 2 + +- name: Verify redeploy_template + ansible.builtin.assert: + that: + - item is not changed + - item.current.reqDetails.isRedeploy == true + loop: "{{ redeploy_template.results }}" + +- name: Verify redeploy_template 4.0 specific + ansible.builtin.assert: + that: + - '"deploy" in item.current.reqDetails' + loop: "{{ redeploy_template.results }}" + when: version.current.version is version('4.0', '>=') + +- name: Undeploy templates + cisco.mso.ndo_schema_template_deploy: + <<: *mso_info + schema: ansible_test + template: '{{ item }}' + sites: + - '{{ mso_site | default("ansible_test") }}' + state: undeploy + register: undeploy_template + loop: + - Template 1 + - Template 2 + +- name: Verify undeploy_template + assert: + that: + - item is not changed + - '"undeploy" in item.current.reqDetails' + loop: "{{ undeploy_template.results }}" + +- name: Add VRF1 with validation error + cisco.mso.mso_schema_template_vrf: &fail_validation + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 2 + vrf: VRF1 + layer3_multicast: true + vzany: true + state: present + +- name: Deploy template with validation error + cisco.mso.ndo_schema_template_deploy: + <<: *mso_info + schema: ansible_test + template: Template 2 + sites: + - '{{ mso_site | default("ansible_test") }}' + state: deploy + register: failed_validaton_deploy + ignore_errors: yes + +- name: Redeploy template with validation error + cisco.mso.ndo_schema_template_deploy: + <<: *mso_info + schema: ansible_test + template: Template 2 + sites: + - '{{ mso_site | default("ansible_test") }}' + state: redeploy + register: failed_validaton_redeploy + ignore_errors: yes + +- name: Verify validation errors before deploy + ansible.builtin.assert: + that: + - failed_validaton_deploy.msg == "MSO Error 400{{':'}} Bad Request{{':'}} Patch Failed, Received{{':'}} vzAny contract must be configured if vzAny flag is set. VRF(s) {{':'}} VRF1 exception while trying to update schema" + - failed_validaton_redeploy.msg == "MSO Error 400{{':'}} Bad Request{{':'}} Patch Failed, Received{{':'}} vzAny contract must be configured if vzAny flag is set. VRF(s) {{':'}} VRF1 exception while trying to update schema" + when: version.current.version is version('4.0', '<') + +- name: Verify validation errors before deploy and redploy + ansible.builtin.assert: + that: + - failed_validaton_deploy.msg == "MSO Error 400{{':'}} VRF{{':'}} VRF1 in Schema{{':'}} ansible_test , Template{{':'}} Template2 has VzAnyEnabled flag enabled but is not consuming or providing contracts" + - failed_validaton_redeploy.msg == "MSO Error 400{{':'}} VRF{{':'}} VRF1 in Schema{{':'}} ansible_test , Template{{':'}} Template2 has VzAnyEnabled flag enabled but is not consuming or providing contracts" + when: version.current.version is version('4.0', '>=') + +- name: Remove VRF1 with validation error + cisco.mso.mso_schema_template_vrf: + <<: *fail_validation + state: absent + +- name: Ensure AWS site is present under tenant ansible_test + cisco.mso.mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'aws_{{ mso_site | default("ansible_test") }}' + cloud_account: '000000000000' + aws_access_key: 1 + secret_key: 0 + state: present + +- name: Ensure Azure site is present under tenant ansible_test + cisco.mso.mso_tenant_site: + <<: *mso_info + tenant: ansible_test + site: 'azure_{{ mso_site | default("ansible_test") }}' + cloud_account: uni/tn-ansible_test/act-[9]-vendor-azure + state: present + +- name: Add AWS site to a schema + cisco.mso.mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'aws_{{ mso_site | default("ansible_test") }}' + template: Template 1 + state: present + +- name: Add Azure site to a schema + cisco.mso.mso_schema_site: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + site: 'azure_{{ mso_site | default("ansible_test") }}' + template: Template 1 + state: present + +- name: Deploy templates + cisco.mso.ndo_schema_template_deploy: + <<: *mso_info + schema: ansible_test + template: Template 1 + sites: + - '{{ mso_site | default("ansible_test") }}' + - 'aws_{{ mso_site | default("ansible_test") }}' + - 'azure_{{ mso_site | default("ansible_test") }}' + state: deploy + register: deploy_template_all + +- name: Query deployment + cisco.mso.ndo_schema_template_deploy: + <<: *mso_info + schema: ansible_test + template: Template 1 + state: query + register: query_deploy_status_all + +- name: Check deployment status of Template 1 + cisco.mso.mso_schema_template_deploy_status: + <<: *mso_info + schema: '{{ mso_schema | default("ansible_test") }}' + template: Template 1 + state: query + register: deployment_status + +- name: Redeploy templates + cisco.mso.ndo_schema_template_deploy: + <<: *mso_info + schema: ansible_test + template: Template 1 + sites: + - '{{ mso_site | default("ansible_test") }}' + - 'aws_{{ mso_site | default("ansible_test") }}' + - 'azure_{{ mso_site | default("ansible_test") }}' + state: redeploy + register: redeploy_template_all + +- name: Query redeployment + cisco.mso.ndo_schema_template_deploy: + <<: *mso_info + schema: ansible_test + template: Template 1 + state: query + register: query_redeploy_status_all + +- name: Undeploy templates + cisco.mso.ndo_schema_template_deploy: + <<: *mso_info + schema: ansible_test + template: Template 1 + sites: + - '{{ mso_site | default("ansible_test") }}' + - 'aws_{{ mso_site | default("ansible_test") }}' + - 'azure_{{ mso_site | default("ansible_test") }}' + state: undeploy + register: undeploy_template_all + +- name: Query undeployment + cisco.mso.ndo_schema_template_deploy: + <<: *mso_info + schema: ansible_test + template: Template 1 + state: query + register: query_undeploy_status_all + +- name: Verify multiple sites + ansible.builtin.assert: + that: + - deploy_template_all is not changed + - redeploy_template_all is not changed + - '"isRedeploy" in redeploy_template_all.current.reqDetails' + - undeploy_template_all is not changed + - '"undeploy" in undeploy_template_all.current.reqDetails' + - undeploy_template_all.current.reqDetails.undeploy | length == 3 + - deployment_status.current | length == 3 + - query_deploy_status_all.current.status | length == 3 + - query_deploy_status_all.current.status.0.status.siteStatus == "Succeeded" + - query_deploy_status_all.current.status.1.status.siteStatus == "Succeeded" + - query_deploy_status_all.current.status.2.status.siteStatus == "Succeeded" + - query_redeploy_status_all.current.status | length == 3 + - query_redeploy_status_all.current.status.0.status.siteStatus == "Succeeded" + - query_redeploy_status_all.current.status.1.status.siteStatus == "Succeeded" + - query_redeploy_status_all.current.status.2.status.siteStatus == "Succeeded" + - query_undeploy_status_all.current.status == [] + +- name: Verify multiple sites 4.0 specific + ansible.builtin.assert: + that: + - '"deploy" in deploy_template_all.current.reqDetails' + - '"deploy" in redeploy_template_all.current.reqDetails' + when: version.current.version is version('4.0', '>=')
\ No newline at end of file diff --git a/ansible_collections/cisco/mso/tests/sanity/requirements.txt b/ansible_collections/cisco/mso/tests/sanity/requirements.txt new file mode 100644 index 00000000..66ac0c81 --- /dev/null +++ b/ansible_collections/cisco/mso/tests/sanity/requirements.txt @@ -0,0 +1,5 @@ +packaging # needed for update-bundled and changelog +sphinx ; python_version >= '3.5' # docs build requires python 3+ +sphinx-notfound-page ; python_version >= '3.5' # docs build requires python 3+ +straight.plugin ; python_version >= '3.5' # needed for hacking/build-ansible.py which will host changelog generation and requires python 3+ +requests-toolbelt
\ No newline at end of file |