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/nxos/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/nxos/tests')
1159 files changed, 71814 insertions, 0 deletions
diff --git a/ansible_collections/cisco/nxos/tests/.gitignore b/ansible_collections/cisco/nxos/tests/.gitignore new file mode 100644 index 00000000..ea1472ec --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/.gitignore @@ -0,0 +1 @@ +output/ diff --git a/ansible_collections/cisco/nxos/tests/integration/network-integration.requirements.txt b/ansible_collections/cisco/nxos/tests/integration/network-integration.requirements.txt new file mode 100644 index 00000000..e8c81df1 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/network-integration.requirements.txt @@ -0,0 +1,6 @@ +pexpect # for _user test +scp # for Cisco ios +selectors2 # for ncclient +ncclient # for Junos +jxmlease # for Junos +xmltodict # for Junos diff --git a/ansible_collections/cisco/nxos/tests/integration/target-prefixes.network b/ansible_collections/cisco/nxos/tests/integration/target-prefixes.network new file mode 100644 index 00000000..c148c1ce --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/target-prefixes.network @@ -0,0 +1 @@ +nxos diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server/tests/common/radius.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server/tests/common/radius.yaml new file mode 100644 index 00000000..f0bf0a25 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server/tests/common/radius.yaml @@ -0,0 +1,96 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_aaa_server radius.yaml sanity test + +- name: Setup + ignore_errors: true + cisco.nxos.nxos_aaa_server: &id004 + server_type: radius + deadtime: default + server_timeout: default + directed_request: default + state: default + +- block: + - name: Configure radius server defaults + register: result + cisco.nxos.nxos_aaa_server: &id001 + server_type: radius + state: present + + - name: Check idempotence + register: result + cisco.nxos.nxos_aaa_server: *id001 + + - ansible.builtin.assert: &id003 + that: + - result.changed == false + + - name: Configure radius server non defaults + register: result + cisco.nxos.nxos_aaa_server: &id002 + server_type: radius + server_timeout: 9 + deadtime: 20 + directed_request: enabled + state: present + + - ansible.builtin.assert: &id005 + that: + - result.changed == true + + - name: Check idempotence + register: result + cisco.nxos.nxos_aaa_server: *id002 + + - ansible.builtin.assert: *id003 + + - name: Remove radius server configuration + register: result + cisco.nxos.nxos_aaa_server: *id004 + + - ansible.builtin.assert: *id005 + + - name: Configure radius server with global key + register: result + cisco.nxos.nxos_aaa_server: &id006 + server_type: radius + encrypt_type: 7 + global_key: test_key + state: present + + - ansible.builtin.assert: *id005 + + - name: Check idempotence + register: result + cisco.nxos.nxos_aaa_server: *id006 + + - ansible.builtin.assert: *id003 + + - name: Remove radius server configuration + register: result + cisco.nxos.nxos_aaa_server: &id007 + server_type: radius + deadtime: default + server_timeout: default + global_key: default + directed_request: default + state: default + + - ansible.builtin.assert: *id005 + + - name: Check idempotence + register: result + cisco.nxos.nxos_aaa_server: *id007 + + - ansible.builtin.assert: *id003 + rescue: + - ansible.builtin.debug: + msg: connection={{ ansible_connection }} nxos_aaa_server failure detected + always: + - name: Remove radius server configuration + register: result + cisco.nxos.nxos_aaa_server: *id004 + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_aaa_server radius.yaml sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server/tests/common/tacacs.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server/tests/common/tacacs.yaml new file mode 100644 index 00000000..7063cc61 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server/tests/common/tacacs.yaml @@ -0,0 +1,106 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_aaa_server tacacs.yaml sanity test + +- name: Enable 'feature tacacs+' + cisco.nxos.nxos_feature: + feature: tacacs+ + state: enabled + +- name: Setup + ignore_errors: true + cisco.nxos.nxos_aaa_server: &id004 + server_type: tacacs + deadtime: default + server_timeout: default + directed_request: default + state: default + +- block: + - name: Configure TACACS server defaults + register: result + cisco.nxos.nxos_aaa_server: &id001 + server_type: tacacs + state: present + + - name: Check idempotence + register: result + cisco.nxos.nxos_aaa_server: *id001 + + - ansible.builtin.assert: &id003 + that: + - result.changed == false + + - name: Configure TACACS server non defaults + register: result + cisco.nxos.nxos_aaa_server: &id002 + server_type: tacacs + server_timeout: 9 + deadtime: 20 + directed_request: enabled + state: present + + - ansible.builtin.assert: &id005 + that: + - result.changed == true + + - name: Check idempotence + register: result + cisco.nxos.nxos_aaa_server: *id002 + + - ansible.builtin.assert: *id003 + + - name: Remove TACACS server configuration + register: result + cisco.nxos.nxos_aaa_server: *id004 + + - ansible.builtin.assert: *id005 + + - name: Configure TACACS server with global key + register: result + cisco.nxos.nxos_aaa_server: &id006 + server_type: tacacs + encrypt_type: 7 + global_key: test_key + state: present + + - ansible.builtin.assert: *id005 + + - name: Check idempotence + register: result + cisco.nxos.nxos_aaa_server: *id006 + + - ansible.builtin.assert: *id003 + + - name: Remove TACACS server configuration + register: result + cisco.nxos.nxos_aaa_server: &id007 + server_type: tacacs + deadtime: default + server_timeout: default + global_key: default + directed_request: default + state: default + + - ansible.builtin.assert: *id005 + + - name: Check idempotence + register: result + cisco.nxos.nxos_aaa_server: *id007 + + - ansible.builtin.assert: *id003 + rescue: + - ansible.builtin.debug: + msg: connection={{ ansible_connection }} nxos_aaa_server failure detected + always: + - name: Remove TACACS server configuration + register: result + cisco.nxos.nxos_aaa_server: *id004 + + - name: Disable 'feature tacacs+' + cisco.nxos.nxos_feature: + feature: tacacs+ + state: disabled + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_aaa_server tacacs.yaml sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server_host/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server_host/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server_host/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server_host/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server_host/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server_host/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server_host/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server_host/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server_host/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server_host/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server_host/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server_host/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server_host/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server_host/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server_host/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server_host/tests/common/radius.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server_host/tests/common/radius.yaml new file mode 100644 index 00000000..c52dd80d --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server_host/tests/common/radius.yaml @@ -0,0 +1,196 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_aaa_server_host radius.yaml sanity test + +- name: Setup + ignore_errors: true + cisco.nxos.nxos_aaa_server_host: &id002 + server_type: radius + address: 8.8.8.8 + state: absent + +- block: + - name: Configure radius server defaults + register: result + cisco.nxos.nxos_aaa_server_host: &id001 + server_type: radius + address: 8.8.8.8 + state: present + + - ansible.builtin.assert: &id003 + that: + - result.changed == true + + - name: Check idempotence + register: result + cisco.nxos.nxos_aaa_server_host: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Remove radius server configuration + register: result + cisco.nxos.nxos_aaa_server_host: *id002 + + - ansible.builtin.assert: *id003 + + - name: Check idempotence + register: result + cisco.nxos.nxos_aaa_server_host: *id002 + + - ansible.builtin.assert: *id004 + + - name: Configure radius server non defaults + register: result + cisco.nxos.nxos_aaa_server_host: &id005 + server_type: radius + address: 8.8.8.8 + host_timeout: 25 + auth_port: 2083 + acct_port: 2084 + state: present + + - ansible.builtin.assert: *id003 + + - name: Check idempotence + register: result + cisco.nxos.nxos_aaa_server_host: *id005 + + - ansible.builtin.assert: *id004 + + - name: Configure some defaults on radius server + register: result + cisco.nxos.nxos_aaa_server_host: &id006 + server_type: radius + address: 8.8.8.8 + host_timeout: default + auth_port: 1000 + acct_port: default + state: present + + - ansible.builtin.assert: *id003 + + - name: Check idempotence + register: result + cisco.nxos.nxos_aaa_server_host: *id006 + + - ansible.builtin.assert: *id004 + + - name: Configure radius server with clear text pwd + register: result + cisco.nxos.nxos_aaa_server_host: &id007 + server_type: radius + address: 8.8.8.8 + host_timeout: 25 + auth_port: default + acct_port: 2084 + encrypt_type: 0 + key: hello + state: present + + - ansible.builtin.assert: *id003 + + - name: Check not idempotent + register: result + cisco.nxos.nxos_aaa_server_host: *id007 + + - ansible.builtin.assert: *id003 + + - name: Remove radius server configuration + register: result + cisco.nxos.nxos_aaa_server_host: *id002 + + - ansible.builtin.assert: *id003 + + - name: Configure radius server with type 7 encryption + register: result + cisco.nxos.nxos_aaa_server_host: &id008 + server_type: radius + address: 8.8.8.8 + host_timeout: 25 + auth_port: 2083 + acct_port: 2084 + encrypt_type: 7 + key: hello + state: present + + - ansible.builtin.assert: *id003 + + - name: Check idempotence + register: result + cisco.nxos.nxos_aaa_server_host: *id008 + + - ansible.builtin.assert: *id004 + + - name: Configure radius server with new type 7 encryption key + register: result + cisco.nxos.nxos_aaa_server_host: &id009 + server_type: radius + address: 8.8.8.8 + host_timeout: 25 + auth_port: 2083 + acct_port: 2084 + encrypt_type: 7 + key: helloback + state: present + + - ansible.builtin.assert: + that: + - result.changed == true + - "'key 7' in result.updates[0]" + + - name: Check idempotence + register: result + cisco.nxos.nxos_aaa_server_host: *id009 + + - ansible.builtin.assert: *id004 + + - name: Configure radius server with default key + register: result + cisco.nxos.nxos_aaa_server_host: &id010 + server_type: radius + address: 8.8.8.8 + host_timeout: default + auth_port: 1000 + acct_port: default + encrypt_type: 7 + key: default + state: present + + - ansible.builtin.assert: *id003 + + - name: Check idempotence + register: result + cisco.nxos.nxos_aaa_server_host: *id010 + + - ansible.builtin.assert: *id004 + + - name: Configure radius server with all def + register: result + cisco.nxos.nxos_aaa_server_host: &id011 + server_type: radius + address: 8.8.8.8 + host_timeout: default + auth_port: default + acct_port: default + key: default + state: present + + - ansible.builtin.assert: *id003 + + - name: Check idempotence + register: result + cisco.nxos.nxos_aaa_server_host: *id011 + + - ansible.builtin.assert: *id004 + rescue: + - ansible.builtin.debug: + msg: connection={{ ansible_connection }} nxos_aaa_server_host failure detected + always: + - name: Remove radius server configuration + register: result + cisco.nxos.nxos_aaa_server_host: *id002 + + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_aaa_server_host radius.yaml sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server_host/tests/common/tacacs.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server_host/tests/common/tacacs.yaml new file mode 100644 index 00000000..0258db28 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_aaa_server_host/tests/common/tacacs.yaml @@ -0,0 +1,199 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_aaa_server_host tacacs.yaml sanity test + +- name: Enable 'feature tacacs+' + cisco.nxos.nxos_feature: + feature: tacacs+ + state: enabled + +- name: Setup + ignore_errors: true + cisco.nxos.nxos_aaa_server_host: &id002 + server_type: tacacs + address: 8.8.8.8 + state: absent + +- block: + - name: Configure TACACS server defaults + register: result + cisco.nxos.nxos_aaa_server_host: &id001 + server_type: tacacs + address: 8.8.8.8 + state: present + + - ansible.builtin.assert: &id003 + that: + - result.changed == true + + - name: Check idempotence + register: result + cisco.nxos.nxos_aaa_server_host: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Remove TACACS server configuration + register: result + cisco.nxos.nxos_aaa_server_host: *id002 + + - ansible.builtin.assert: *id003 + + - name: Check idempotence + register: result + cisco.nxos.nxos_aaa_server_host: *id002 + + - ansible.builtin.assert: *id004 + + - name: Configure TACACS server non defaults + register: result + cisco.nxos.nxos_aaa_server_host: &id005 + server_type: tacacs + address: 8.8.8.8 + host_timeout: 25 + tacacs_port: 89 + state: present + + - ansible.builtin.assert: *id003 + + - name: Check idempotence + register: result + cisco.nxos.nxos_aaa_server_host: *id005 + + - ansible.builtin.assert: *id004 + + - name: Configure some defaults on TACACS server + register: result + cisco.nxos.nxos_aaa_server_host: &id006 + server_type: tacacs + address: 8.8.8.8 + host_timeout: default + tacacs_port: 100 + state: present + + - ansible.builtin.assert: *id003 + + - name: Check idempotence + register: result + cisco.nxos.nxos_aaa_server_host: *id006 + + - ansible.builtin.assert: *id004 + + - name: Configure TACACS server with clear text pwd + register: result + cisco.nxos.nxos_aaa_server_host: &id007 + server_type: tacacs + address: 8.8.8.8 + host_timeout: 25 + tacacs_port: default + encrypt_type: 0 + key: hello + state: present + + - ansible.builtin.assert: *id003 + + - name: Check not idempotent + register: result + cisco.nxos.nxos_aaa_server_host: *id007 + + - ansible.builtin.assert: *id003 + + - name: Remove TACACS server configuration + register: result + cisco.nxos.nxos_aaa_server_host: *id002 + + - ansible.builtin.assert: *id003 + + - name: Configure TACACS server with type 7 encryption + register: result + cisco.nxos.nxos_aaa_server_host: &id008 + server_type: tacacs + address: 8.8.8.8 + host_timeout: 25 + tacacs_port: 89 + encrypt_type: 7 + key: hello + state: present + + - ansible.builtin.assert: *id003 + + - name: Check idempotence + register: result + cisco.nxos.nxos_aaa_server_host: *id008 + + - ansible.builtin.assert: *id004 + + - name: Configure TACACS server with new type 7 encryption key + register: result + cisco.nxos.nxos_aaa_server_host: &id009 + server_type: tacacs + address: 8.8.8.8 + host_timeout: 25 + tacacs_port: 89 + encrypt_type: 7 + key: helloback + state: present + + - ansible.builtin.assert: + that: + - result.changed == true + - "'key 7' in result.updates[0]" + + - name: Check idempotence + register: result + cisco.nxos.nxos_aaa_server_host: *id009 + + - ansible.builtin.assert: *id004 + + - name: Configure TACACS server with default key + register: result + cisco.nxos.nxos_aaa_server_host: &id010 + server_type: tacacs + address: 8.8.8.8 + host_timeout: default + tacacs_port: 89 + encrypt_type: 7 + key: default + state: present + + - ansible.builtin.assert: *id003 + + - name: Check idempotence + register: result + cisco.nxos.nxos_aaa_server_host: *id010 + + - ansible.builtin.assert: *id004 + + - name: Configure TACACS server with all def + register: result + cisco.nxos.nxos_aaa_server_host: &id011 + server_type: tacacs + address: 8.8.8.8 + host_timeout: default + tacacs_port: default + key: default + state: present + + - ansible.builtin.assert: *id003 + + - name: Check idempotence + register: result + cisco.nxos.nxos_aaa_server_host: *id011 + + - ansible.builtin.assert: *id004 + rescue: + - ansible.builtin.debug: + msg: connection={{ ansible_connection }} nxos_aaa_server_host failure detected + always: + - name: Remove TACACS server configuration + register: result + cisco.nxos.nxos_aaa_server_host: *id002 + + - name: Disable 'feature tacacs+' + cisco.nxos.nxos_feature: + feature: tacacs+ + state: disabled + + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_aaa_server_host tacacs.yaml sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tasks/cli.yaml new file mode 100644 index 00000000..f41fb736 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tasks/main.yaml new file mode 100644 index 00000000..4384d22c --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tasks/main.yaml @@ -0,0 +1,15 @@ +--- +- name: Set system defaults for switchports + cisco.nxos.nxos_config: + lines: "no system default switchport" + connection: ansible.netcommon.network_cli + +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tasks/nxapi.yaml new file mode 100644 index 00000000..86c82add --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/templates/populate_config.cfg b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/templates/populate_config.cfg new file mode 100644 index 00000000..0863ffce --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/templates/populate_config.cfg @@ -0,0 +1,10 @@ +ip access-list ACL1v4 +ip access-list NewACLv4 +ipv6 access-list ACL1v6 +ipv6 access-list NewACLv6 +ip access-list PortACL +interface Ethernet1/5 + ip access-group ACL1v4 out + ipv6 traffic-filter ACL1v6 in +interface Ethernet1/2 + ipv6 traffic-filter ACL1v6 in diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/deleted.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/deleted.yml new file mode 100644 index 00000000..2f5ff4da --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/deleted.yml @@ -0,0 +1,57 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_acl_interfaces deleted integration tests connection = {{ansible_connection}} + +- ansible.builtin.include_tasks: remove_config.yaml + +- ansible.builtin.include_tasks: populate_acl.yaml + +- ansible.builtin.include_tasks: populate_config.yaml + +- block: + - name: Delete all acls configuration from given interface + register: result + cisco.nxos.nxos_acl_interfaces: &id002 + config: + - name: Ethernet1/2 + state: deleted + + - ansible.builtin.assert: + that: + - result.changed == True + - "'interface Ethernet1/2' in result.commands" + - "'no ipv6 traffic-filter ACL1v6 in' in result.commands" + - result.commands | length == 2 + + - ansible.builtin.include_tasks: populate_config.yaml + + - name: Delete all acls from all interfaces (from all interfaces) + register: result + cisco.nxos.nxos_acl_interfaces: + config: + state: deleted + + - name: Gather ACL interfaces facts + cisco.nxos.nxos_facts: &id001 + gather_subset: + - "!all" + - "!min" + gather_network_resources: acl_interfaces + + - ansible.builtin.assert: + that: + - result.changed == True + - ansible_facts.network_resources.acl_interfaces == result.after + + - name: Gather acls facts + cisco.nxos.nxos_facts: *id001 + + - name: Idempotence - deleted + register: result + cisco.nxos.nxos_acl_interfaces: *id002 + + - ansible.builtin.assert: + that: + - result.changed == false + always: + - ansible.builtin.include_tasks: remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/empty_config.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/empty_config.yml new file mode 100644 index 00000000..35b54f47 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/empty_config.yml @@ -0,0 +1,61 @@ +--- +- ansible.builtin.debug: + msg: START nxos_acl_interfaces empty_config integration tests on connection={{ ansible_connection }} + +- name: Merged with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_acl_interfaces: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_acl_interfaces: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Overridden with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_acl_interfaces: + config: + state: overridden + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Rendered with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_acl_interfaces: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' + +- name: Parsed with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_acl_interfaces: + running_config: + state: parsed + +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state parsed' + +- ansible.builtin.debug: + msg: END nxos_acl_interfaces empty_config integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/gathered.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/gathered.yml new file mode 100644 index 00000000..f0130fe7 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/gathered.yml @@ -0,0 +1,33 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_acl_interfaces gathered integration tests connection={{ansible_connection}}" + +- ansible.builtin.include_tasks: populate_config.yaml + +- block: + - name: Gather ACL interfaces facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: acl_interfaces + + - name: Gathered + register: result + cisco.nxos.nxos_acl_interfaces: &id001 + state: gathered + + - ansible.builtin.assert: + that: + - result.changed == false + - ansible_facts.network_resources.acl_interfaces == result.gathered + + - name: Idempotence - gathered + register: result + cisco.nxos.nxos_acl_interfaces: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + always: + - ansible.builtin.include_tasks: remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/merged.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/merged.yml new file mode 100644 index 00000000..0874a0bd --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/merged.yml @@ -0,0 +1,69 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_acl_interfaces merged integration tests connection = {{ansible_connection}} + +- ansible.builtin.include_tasks: remove_config.yaml + +- ansible.builtin.include_tasks: populate_acl.yaml + +- block: + - name: Gather ACL interfaces facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: acl_interfaces + + - name: Merged + register: result + cisco.nxos.nxos_acl_interfaces: &id001 + config: + - name: Ethernet1/2 + access_groups: + - afi: ipv6 + acls: + - name: ACL1v6 + direction: in + + - name: Eth1/6 + access_groups: + - afi: ipv4 + acls: + - name: PortACL + direction: in + port: true + + - name: Eth1/5 + access_groups: + - afi: ipv4 + acls: + - name: ACL1v4 + direction: out + + - afi: ipv6 + acls: + - name: ACL1v6 + direction: in + state: merged + + - ansible.builtin.assert: + that: + - result.changed == True + - "'interface Ethernet1/2' in result.commands" + - "'ipv6 traffic-filter ACL1v6 in' in result.commands" + - "'interface Ethernet1/6' in result.commands" + - "'ip port access-group PortACL in' in result.commands" + - "'interface Ethernet1/5' in result.commands" + - "'ip access-group ACL1v4 out' in result.commands" + - "'ipv6 traffic-filter ACL1v6 in' in result.commands" + - "result.commands | length == 7 " + + - name: Idempotence - merged + register: result + cisco.nxos.nxos_acl_interfaces: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + always: + - ansible.builtin.include_tasks: remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/overridden.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/overridden.yml new file mode 100644 index 00000000..e184156d --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/overridden.yml @@ -0,0 +1,75 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_acl_interfaces overridden integration tests connection = {{ansible_connection}} + +- ansible.builtin.include_tasks: remove_config.yaml + +- ansible.builtin.include_tasks: populate_acl.yaml + +- ansible.builtin.include_tasks: populate_config.yaml + +- block: + - name: Overridden + register: result + cisco.nxos.nxos_acl_interfaces: &id002 + config: + - name: Ethernet1/3 + access_groups: + - afi: ipv4 + acls: + - name: ACL1v4 + direction: out + + - name: Ethernet1/6 + access_groups: + - afi: ipv4 + acls: + - name: PortACL + port: true + direction: in + + - afi: ipv6 + acls: + - name: NewACLv6 + direction: in + port: true + state: overridden + + - ansible.builtin.assert: + that: + - result.changed == True + - "'interface Ethernet1/2' in result.commands" + - "'no ipv6 traffic-filter ACL1v6 in' in result.commands" + - "'interface Ethernet1/5' in result.commands" + - "'no ip access-group ACL1v4 out' in result.commands" + - "'no ipv6 traffic-filter ACL1v6 in' in result.commands" + - "'interface Ethernet1/3' in result.commands" + - "'ip access-group ACL1v4 out' in result.commands" + - "'interface Ethernet1/6' in result.commands" + - "'ip port access-group PortACL in' in result.commands" + - "'ipv6 port traffic-filter NewACLv6 in' in result.commands" + - result.commands | length == 10 + + - name: Gather acl_interfaces post facts + cisco.nxos.nxos_facts: &id001 + gather_subset: + - "!all" + - "!min" + gather_network_resources: acl_interfaces + + - name: Gather acls post facts + cisco.nxos.nxos_facts: *id001 + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.acl_interfaces == result.after + + - name: Idempotence - overridden + register: result + cisco.nxos.nxos_acl_interfaces: *id002 + + - ansible.builtin.assert: + that: + - result.changed == false + always: + - ansible.builtin.include_tasks: remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/parsed.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/parsed.yml new file mode 100644 index 00000000..0617a97b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/parsed.yml @@ -0,0 +1,31 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_acl_interfaces parsed integration tests connection={{ansible_connection}}" + +- block: + - name: Gather ACL interfaces facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: acl_interfaces + + - name: Parsed + register: result + cisco.nxos.nxos_acl_interfaces: &id001 + running_config: + "interface Ethernet1/2\nipv6 traffic-filter ACL1v6 in\ninterface Ethernet1/5\nipv6 traffic-filter ACL1v6 in\nip access-group ACL1v4 out\n\ + ip port access-group PortACL in\n" + state: parsed + + - ansible.builtin.assert: + that: + - result.changed == false + - result.parsed == parsed + + - name: Idempotence - parsed + register: result + cisco.nxos.nxos_acl_interfaces: *id001 + + - ansible.builtin.assert: + that: result.changed == false diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/populate_acl.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/populate_acl.yaml new file mode 100644 index 00000000..986c0cb8 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/populate_acl.yaml @@ -0,0 +1,11 @@ +--- +- name: Adding base configuration + cisco.nxos.nxos_config: + lines: + - "ip access-list ACL1v4" + - "ip access-list NewACLv4" + - "ipv6 access-list ACL1v6" + - "ipv6 access-list NewACLv6" + - "ip access-list PortACL" + - "interface ethernet 1/6" + - "switchport" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/populate_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/populate_config.yaml new file mode 100644 index 00000000..7265d081 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/populate_config.yaml @@ -0,0 +1,4 @@ +--- +- name: Adding base configuration + cisco.nxos.nxos_config: + src: populate_config.cfg diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/remove_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/remove_config.yaml new file mode 100644 index 00000000..3cad7ce5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/remove_config.yaml @@ -0,0 +1,43 @@ +--- +- name: Remove configuration - 1 + cisco.nxos.nxos_config: + lines: + - "no ip access-list ACL1v4" + - "no ip access-list NewACLv4" + - "no ip access-list PortACL" + - "no ipv6 access-list ACL1v6" + - "no ipv6 access-list NewACLv6" + - "interface Ethernet1/2" + - " no ipv6 traffic-filter ACL1v6 in" + ignore_errors: true + +- name: Remove configuration - 2 + cisco.nxos.nxos_config: + lines: + - no ip access-group ACL1v4 out + - no ipv6 traffic-filter ACL1v6 in + parents: interface Ethernet1/5 + ignore_errors: true + +- name: Remove configuration - 3 + cisco.nxos.nxos_config: + lines: + - no ip access-group ACL1v4 out + parents: interface Ethernet1/3 + ignore_errors: true + +- name: Remove configuration - 4 + cisco.nxos.nxos_config: + lines: + - no ip access-group NewACLv4 out + parents: interface Ethernet1/4 + ignore_errors: true + +- name: Remove configuration - 5 + cisco.nxos.nxos_config: + lines: + - no switchport + - no ipv6 port traffic-filter NewACLv6 in + - no ip port access-group PortACL in + parents: interface Ethernet1/6 + ignore_errors: true diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/rendered.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/rendered.yml new file mode 100644 index 00000000..e489104e --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/rendered.yml @@ -0,0 +1,55 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_acl_interfaces rendered tests connection={{ ansible_connection }} + +- name: Rendered + register: result + cisco.nxos.nxos_acl_interfaces: &id001 + config: + - name: Ethernet1/2 + access_groups: + - afi: ipv6 + acls: + - name: ACL1v6 + direction: in + + - name: Ethernet1/6 + access_groups: + - afi: ipv4 + acls: + - name: PortACL + direction: in + port: true + + - name: Ethernet1/5 + access_groups: + - afi: ipv4 + acls: + - name: ACL1v4 + direction: out + + - afi: ipv6 + acls: + - name: ACL1v6 + direction: in + state: rendered + +- ansible.builtin.assert: + that: + - result.changed == false + - "'interface Ethernet1/2' in result.rendered" + - "'ipv6 traffic-filter ACL1v6 in' in result.rendered" + - "'interface Ethernet1/6' in result.rendered" + - "'ip port access-group PortACL in' in result.rendered" + - "'interface Ethernet1/5' in result.rendered" + - "'ipv6 traffic-filter ACL1v6 in' in result.rendered" + - "'ip access-group ACL1v4 out' in result.rendered" + - result.rendered | length == 7 + +- name: Idempotence - rendered + register: result + cisco.nxos.nxos_acl_interfaces: *id001 + +- ansible.builtin.assert: + that: + - result.changed == false diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/replaced.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/replaced.yml new file mode 100644 index 00000000..d9fa0a7a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/replaced.yml @@ -0,0 +1,62 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_acl_interfaces replaced integration tests connection = {{ansible_connection}} + +- ansible.builtin.include_tasks: remove_config.yaml + +- ansible.builtin.include_tasks: populate_acl.yaml + +- ansible.builtin.include_tasks: populate_config.yaml + +- block: + - name: Replaced + register: result + cisco.nxos.nxos_acl_interfaces: &id001 + config: + - name: Eth1/5 + access_groups: + - afi: ipv4 + acls: + - name: NewACLv4 + direction: out + + - name: Ethernet1/6 + access_groups: + - afi: ipv6 + acls: + - name: NewACLv6 + direction: in + port: true + state: replaced + + - ansible.builtin.assert: + that: + - result.changed==True + - "'interface Ethernet1/5' in result.commands" + - "'no ip access-group ACL1v4 out' in result.commands" + - "'no ipv6 traffic-filter ACL1v6 in' in result.commands" + - "'ip access-group NewACLv4 out' in result.commands" + - "'interface Ethernet1/6' in result.commands" + - "'ipv6 port traffic-filter NewACLv6 in' in result.commands" + - result.commands|length==6 + + - name: Gather acl_interfaces post facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: acl_interfaces + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.acl_interfaces == result.after + + - name: Idempotence - replaced + register: result + cisco.nxos.nxos_acl_interfaces: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + always: + - ansible.builtin.include_tasks: remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/rtt.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/rtt.yml new file mode 100644 index 00000000..90f72fb3 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/tests/common/rtt.yml @@ -0,0 +1,107 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_acl_interfaces round trip integration tests connection = {{ansible_connection}} + +- ansible.builtin.include_tasks: remove_config.yaml + +- ansible.builtin.include_tasks: populate_acl.yaml + +- ansible.builtin.include_tasks: populate_config.yaml + +- block: + - name: Rtt- apply provided configuration + cisco.nxos.nxos_acl_interfaces: + config: + - name: Ethernet1/2 + access_groups: + - afi: ipv6 + acls: + - name: ACL1v6 + direction: in + + - name: Eth1/6 + access_groups: + - afi: ipv4 + acls: + - name: PortACL + direction: in + port: true + + - name: Eth1/5 + access_groups: + - afi: ipv4 + acls: + - name: ACL1v4 + direction: out + + - afi: ipv6 + acls: + - name: ACL1v6 + direction: in + state: merged + + - name: Gather interfaces facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: + - acl_interfaces + + - name: Apply configuration to be reverted + register: result + cisco.nxos.nxos_acl_interfaces: + config: + - name: Eth1/4 + access_groups: + - afi: ipv4 + acls: + - name: NewACLv4 + direction: out + + - name: Ethernet1/6 + access_groups: + - afi: ipv6 + acls: + - name: NewACLv6 + direction: in + port: true + state: overridden + + - name: Assert that changes were applied + ansible.builtin.assert: + that: + - result.changed==True + - "'interface Ethernet1/2' in result.commands" + - "'no ipv6 traffic-filter ACL1v6 in' in result.commands" + - "'interface Ethernet1/5' in result.commands" + - "'no ip access-group ACL1v4 out' in result.commands" + - "'no ipv6 traffic-filter ACL1v6 in' in result.commands" + - "'interface Ethernet1/4' in result.commands" + - "'ip access-group NewACLv4 out' in result.commands" + - "'interface Ethernet1/6' in result.commands" + - "'no ip port access-group PortACL in' in result.commands" + - "'ipv6 port traffic-filter NewACLv6 in' in result.commands" + + - name: Revert back to base configuration using facts round trip + register: result + cisco.nxos.nxos_acl_interfaces: + config: "{{ ansible_facts['network_resources']['acl_interfaces'] }}" + state: overridden + + - name: Assert that configuration was reverted + ansible.builtin.assert: + that: + - result.changed==True + - "'interface Ethernet1/2' in result.commands" + - "'ipv6 traffic-filter ACL1v6 in' in result.commands" + - "'interface Ethernet1/4' in result.commands" + - "'no ip access-group NewACLv4 out' in result.commands" + - "'interface Ethernet1/5' in result.commands" + - "'ip access-group ACL1v4 out' in result.commands" + - "'ipv6 traffic-filter ACL1v6 in' in result.commands" + - "'interface Ethernet1/6' in result.commands" + - "'ip port access-group PortACL in' in result.commands" + - "'no ipv6 port traffic-filter NewACLv6 in' in result.commands" + always: + - ansible.builtin.include_tasks: remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/vars/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/vars/main.yml new file mode 100644 index 00000000..ad0b22e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acl_interfaces/vars/main.yml @@ -0,0 +1,21 @@ +--- +parsed: + - access_groups: + - acls: + - direction: in + name: ACL1v6 + afi: ipv6 + name: Ethernet1/2 + - access_groups: + - acls: + - direction: out + name: ACL1v4 + - direction: in + name: PortACL + port: true + afi: ipv4 + - acls: + - direction: in + name: ACL1v6 + afi: ipv6 + name: Ethernet1/5 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tasks/cli.yaml new file mode 100644 index 00000000..c34726ef --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tasks/cli.yaml @@ -0,0 +1,31 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tasks/main.yaml new file mode 100644 index 00000000..f900849c --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tasks/main.yaml @@ -0,0 +1,17 @@ +--- +- name: Set system defaults for switchports + cisco.nxos.nxos_config: + lines: + - "no system default switchport" + - "system default switchport shutdown" + connection: ansible.netcommon.network_cli + +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tasks/nxapi.yaml new file mode 100644 index 00000000..e0ebc3f5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tasks/nxapi.yaml @@ -0,0 +1,31 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tests/common/deleted.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tests/common/deleted.yml new file mode 100644 index 00000000..d3e32fb6 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tests/common/deleted.yml @@ -0,0 +1,56 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_acls deleted integration tests connection={{ansible_connection}}" + +- ansible.builtin.include_tasks: populate_config.yaml + +- block: + - name: Deleted (all acls) + cisco.nxos.nxos_acls: + config: + state: deleted + + - name: Gather acls facts + cisco.nxos.nxos_facts: &id001 + gather_subset: + - "!all" + - "!min" + gather_network_resources: acls + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources == {} + + - ansible.builtin.include_tasks: populate_config.yaml + + - name: Deleted + register: result + cisco.nxos.nxos_acls: &id002 + config: + - afi: ipv4 + + - afi: ipv6 + + state: deleted + + - ansible.builtin.assert: + that: + - result.changed==True + - "'no ip access-list ACL1v4' in result.commands" + - "'no ip access-list ACL2v4' in result.commands" + - "'no ipv6 access-list ACL1v6' in result.commands" + - "'no ipv6 access-list ACL2v6' in result.commands" + - result.commands | length == 4 + + - name: Gather acls facts + cisco.nxos.nxos_facts: *id001 + + - name: Idempotence - deleted + register: result + cisco.nxos.nxos_acls: *id002 + + - ansible.builtin.assert: + that: + - result.changed == false + always: + - ansible.builtin.include_tasks: remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tests/common/gathered.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tests/common/gathered.yml new file mode 100644 index 00000000..851786a4 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tests/common/gathered.yml @@ -0,0 +1,33 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_acls gathered integration tests connection={{ansible_connection}}" + +- ansible.builtin.include_tasks: populate_config.yaml + +- block: + - name: Gather acls facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: acls + + - name: Gathered + register: result + cisco.nxos.nxos_acls: &id001 + state: gathered + + - ansible.builtin.assert: + that: + - result.changed == false + - ansible_facts.network_resources.acls == result.gathered + + - name: Idempotence - gathered + register: result + cisco.nxos.nxos_acls: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + always: + - ansible.builtin.include_tasks: remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tests/common/merged.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tests/common/merged.yml new file mode 100644 index 00000000..874a2ad9 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tests/common/merged.yml @@ -0,0 +1,107 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_acls merged integration tests connection={{ansible_connection}}" + +- ansible.builtin.include_tasks: remove_config.yaml + +- block: + - name: Merged + register: result + cisco.nxos.nxos_acls: &id001 + config: + - afi: ipv4 + acls: + - name: ACL1v4 + aces: + - grant: deny + destination: + address: 192.0.2.64 + wildcard_bits: 0.0.0.255 + source: + any: true + port_protocol: + lt: 25 + protocol: tcp + protocol_options: + tcp: + ack: true + fin: true + sequence: 50 + + - grant: permit + protocol: ip + source: + any: true + destination: + any: true + fragments: true + log: true + sequence: 20 + + - afi: ipv6 + acls: + - name: ACL1v6 + aces: + - grant: permit + sequence: 10 + source: + any: true + destination: + host: 2001:db8:12::128 + protocol: sctp + state: merged + + - ansible.builtin.assert: + that: + - result.changed == True + - "'ip access-list ACL1v4' in result.commands" + - "'20 permit ip any any fragments log' in result.commands" + - "'50 deny tcp any lt smtp 192.0.2.64 0.0.0.255 ack fin' in result.commands" + - "'ipv6 access-list ACL1v6' in result.commands" + - "'10 permit sctp any host 2001:db8:12::128' in result.commands" + - "result.commands | length == 5 " + + - name: Gather acls facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: acls + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.acls == result.after + + - name: Idempotence - merged + register: result + cisco.nxos.nxos_acls: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + + - name: Update one parameter of an existing ACE with state merged (should fail) + register: result + cisco.nxos.nxos_acls: + config: + - afi: ipv4 + acls: + - name: ACL1v4 + aces: + - grant: permit + protocol: tcp + source: + any: true + destination: + any: true + sequence: 20 + precedence: 5 + state: merged + ignore_errors: true + + - ansible.builtin.assert: + that: + - result.failed == True + - "'Cannot update existing ACE ACL1v4 of ACL 20 with state merged. Please use state replaced or overridden.' in result.msg" + always: + - ansible.builtin.include_tasks: remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tests/common/overridden.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tests/common/overridden.yml new file mode 100644 index 00000000..9421d7f5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tests/common/overridden.yml @@ -0,0 +1,99 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_acls overridden integration tests connection={{ansible_connection}}" + +- ansible.builtin.include_tasks: populate_config.yaml + +- block: + - name: Overridden (first test) + register: result + cisco.nxos.nxos_acls: + config: + - afi: ipv4 + acls: + - name: NewACL + aces: + - grant: deny + source: + address: 192.0.2.0 + wildcard_bits: 0.0.255.255 + destination: + any: true + protocol: eigrp + + - remark: Example for overridden state + state: overridden + + - ansible.builtin.assert: + that: + - result.changed==True + - "'no ip access-list ACL1v4' in result.commands" + - "'no ip access-list ACL2v4' in result.commands" + - "'no ipv6 access-list ACL1v6' in result.commands" + - "'no ipv6 access-list ACL2v6' in result.commands" + - "'ip access-list NewACL' in result.commands" + - "'deny eigrp 192.0.2.0 0.0.255.255 any' in result.commands" + - "'remark Example for overridden state' in result.commands" + - result.commands|length==7 + + - name: Gather acls post facts + cisco.nxos.nxos_facts: &id001 + gather_subset: + - "!all" + - "!min" + gather_network_resources: acls + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.acls == result.after + + - ansible.builtin.include_tasks: populate_config.yaml + + - name: Overridden (second test) + register: result + cisco.nxos.nxos_acls: &id002 + config: + - afi: ipv6 + acls: + - name: ACL1v6 + aces: + - grant: deny + protocol: udp + destination: + any: true + source: + host: 2001:db8:3431::12 + port_protocol: + lt: 35 + sequence: 10 + state: overridden + + - ansible.builtin.assert: + that: + - result.changed==True + - "'no ip access-list ACL1v4' in result.commands" + - "'no ip access-list ACL2v4' in result.commands" + - "'no ipv6 access-list ACL2v6' in result.commands" + - "'no ip access-list NewACL' in result.commands" + - "'ipv6 access-list ACL1v6' in result.commands" + - "'no 10 permit sctp any any' in result.commands" + - "'no 20 remark IPv6 ACL' in result.commands" + - "'10 deny udp host 2001:db8:3431::12 lt 35 any' in result.commands" + - result.commands|length==8 + + - name: Gather acls post facts + cisco.nxos.nxos_facts: *id001 + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.acls == result.after + + - name: Idempotence - overridden + register: result + cisco.nxos.nxos_acls: *id002 + + - ansible.builtin.assert: + that: + - result.changed == false + always: + - ansible.builtin.include_tasks: remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tests/common/parsed.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tests/common/parsed.yml new file mode 100644 index 00000000..b408fecf --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tests/common/parsed.yml @@ -0,0 +1,44 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_acls gathered integration tests connection={{ansible_connection}}" + +- ansible.builtin.include_tasks: populate_config.yaml + +- block: + - name: Gather acls facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: acls + + - name: Parsed + register: result + cisco.nxos.nxos_acls: &id001 + running_config: >- + ip access-list ACL1v4 + 10 permit ip any any + 20 deny udp any any + ip access-list ACL2v4 + 10 permit ahp 192.0.2.0 0.0.0.255 any + ipv6 access-list ACL1v6 + 10 permit sctp any any + 20 remark IPv6 ACL + ipv6 access-list ACL2v6 + 10 deny ipv6 any 2001:db8:3000::36/128 + 20 permit tcp 2001:db8:2000:2::2/128 2001:db8:2000:ab::2/128 + state: parsed + + - ansible.builtin.assert: + that: + - result.changed == false + - ansible_facts.network_resources.acls == result.parsed + + - name: Idempotence - parsed + register: result + cisco.nxos.nxos_acls: *id001 + + - ansible.builtin.assert: + that: result.changed == false + always: + - ansible.builtin.include_tasks: remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tests/common/populate_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tests/common/populate_config.yaml new file mode 100644 index 00000000..0d8644e9 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tests/common/populate_config.yaml @@ -0,0 +1,15 @@ +--- +- name: Add configuration + cisco.nxos.nxos_config: + lines: + - "ip access-list ACL1v4" + - " 10 permit ip any any" + - " 20 deny udp any any" + - "ip access-list ACL2v4" + - " 10 permit ahp 192.0.2.0 0.0.0.255 any" + - "ipv6 access-list ACL1v6" + - " 10 permit sctp any any" + - " 20 remark IPv6 ACL" + - "ipv6 access-list ACL2v6" + - " 10 deny ipv6 any host 2001:db8:3000::36" + - " 20 permit tcp host 2001:db8:2000:2::2 host 2001:db8:2000:ab::2" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tests/common/remove_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tests/common/remove_config.yaml new file mode 100644 index 00000000..17c6b5bc --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tests/common/remove_config.yaml @@ -0,0 +1,9 @@ +--- +- name: Remove configuration + cisco.nxos.nxos_config: + lines: + - "no ip access-list ACL1v4" + - "no ip access-list ACL2v4" + - "no ipv6 access-list ACL1v6" + - "no ipv6 access-list ACL2v6" + - "no ip access-list NewACL" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tests/common/rendered.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tests/common/rendered.yml new file mode 100644 index 00000000..e7eb3b33 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tests/common/rendered.yml @@ -0,0 +1,69 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_acls rendered tests connection={{ ansible_connection }} + +- name: Rendered + register: result + cisco.nxos.nxos_acls: &id001 + config: + - afi: ipv4 + acls: + - name: ACL1v4 + aces: + - grant: deny + destination: + address: 192.0.2.64 + wildcard_bits: 0.0.0.255 + source: + any: true + port_protocol: + eq: 43 + protocol: tcp + protocol_options: + tcp: + ack: true + fin: true + sequence: 50 + + - destination: + port_protocol: + range: + end: 4000 + start: 3949 + prefix: 203.0.113.0/24 + grant: permit + protocol: tcp + source: + any: true + sequence: 70 + + - afi: ipv6 + acls: + - name: ACL1v6 + aces: + - grant: permit + sequence: 10 + source: + any: true + destination: + prefix: 2001:db8:12::/32 + protocol: sctp + state: rendered + +- ansible.builtin.assert: + that: + - result.changed == false + - "'ip access-list ACL1v4' in result.rendered" + - "'50 deny tcp any eq whois 192.0.2.64 0.0.0.255 ack fin' in result.rendered" + - "'70 permit tcp any 203.0.113.0/24 range drip 4000' in result.rendered" + - "'ipv6 access-list ACL1v6' in result.rendered" + - "'10 permit sctp any 2001:db8:12::/32' in result.rendered" + - result.rendered | length == 5 + +- name: Idempotence - rendered + register: result + cisco.nxos.nxos_acls: *id001 + +- ansible.builtin.assert: + that: + - result.changed == false diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tests/common/replaced.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tests/common/replaced.yml new file mode 100644 index 00000000..6bc16487 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tests/common/replaced.yml @@ -0,0 +1,65 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_acls replaced integration tests connection={{ansible_connection}}" + +- ansible.builtin.include_tasks: populate_config.yaml + +- block: + - name: Replaced + register: result + cisco.nxos.nxos_acls: &id001 + config: + - afi: ipv4 + + - afi: ipv6 + acls: + - name: ACL1v6 + aces: + - sequence: 30 + grant: permit + source: + any: true + destination: + any: true + protocol: pim + + - sequence: 40 + remark: Replaced ACE + + - name: ACL2v6 + state: replaced + + - ansible.builtin.assert: + that: + - "'no ip access-list ACL1v4' in result.commands" + - "'no ip access-list ACL2v4' in result.commands" + - "'ipv6 access-list ACL1v6' in result.commands" + - "'no 10 permit sctp any any' in result.commands" + - "'no 20 remark IPv6 ACL' in result.commands" + - "'30 permit pim any any' in result.commands" + - "'40 remark Replaced ACE' in result.commands" + - "'ipv6 access-list ACL2v6' in result.commands" + - "'no 10 deny ipv6 any host 2001:db8:3000::36' in result.commands" + - "'no 20 permit tcp host 2001:db8:2000:2::2 host 2001:db8:2000:ab::2' in result.commands" + - result.commands|length == 10 + + - name: Gather static_routes post facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: acls + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.acls == result.after + + - name: Idempotence - replaced + register: result + cisco.nxos.nxos_acls: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + always: + - ansible.builtin.include_tasks: remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tests/common/rtt.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tests/common/rtt.yml new file mode 100644 index 00000000..4d35f8d6 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_acls/tests/common/rtt.yml @@ -0,0 +1,87 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_acls round trip integration tests connection = {{ansible_connection}} + +- block: + - name: Rtt - apply provided configuration + cisco.nxos.nxos_acls: + config: + - afi: ipv4 + acls: + - name: ACL1v4 + aces: + - grant: deny + destination: + address: 192.0.2.64 + wildcard_bits: 0.0.0.255 + source: + any: true + port_protocol: + lt: 25 + protocol: tcp + protocol_options: + tcp: + ack: true + fin: true + sequence: 50 + + - grant: permit + protocol: ip + source: + any: true + destination: + any: true + fragments: true + log: true + sequence: 20 + state: merged + + - name: Gather interfaces facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: + - acls + + - name: Apply configuration to be reverted + register: result + cisco.nxos.nxos_acls: + config: + - afi: ipv6 + acls: + - name: ACL1v6 + aces: + - grant: permit + sequence: 10 + source: + any: true + destination: + host: 2001:db8:12::128 + protocol: sctp + state: overridden + + - ansible.builtin.assert: + that: + - result.changed == True + - "'no ip access-list ACL1v4' in result.commands" + - "'ipv6 access-list ACL1v6' in result.commands" + - "'10 permit sctp any host 2001:db8:12::128' in result.commands" + - "result.commands | length == 3 " + + - name: Revert back to base configuration using facts round trip + register: result + cisco.nxos.nxos_acls: + config: "{{ ansible_facts['network_resources']['acls'] }}" + state: overridden + + - ansible.builtin.assert: + that: + - result.changed == True + - "'ip access-list ACL1v4' in result.commands" + - "'20 permit ip any any fragments log' in result.commands" + - "'50 deny tcp any lt smtp 192.0.2.64 0.0.0.255 fin ack' in result.commands" + - "'no ipv6 access-list ACL1v6' in result.commands" + - "result.commands | length == 4 " + always: + - ansible.builtin.include_tasks: remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_banner/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_banner/defaults/main.yaml new file mode 100644 index 00000000..9ef5ba51 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_banner/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "*" +test_items: [] diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_banner/meta/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_banner/meta/main.yaml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_banner/meta/main.yaml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_banner/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_banner/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_banner/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_banner/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_banner/tasks/main.yaml new file mode 100644 index 00000000..865cff2c --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_banner/tasks/main.yaml @@ -0,0 +1,15 @@ +--- +- name: Set a fact for 'banner_exec_image_ok' and 'banner_motd_image_ok' + ansible.builtin.set_fact: + banner_exec_image_ok: false + banner_motd_image_ok: false + +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_banner/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_banner/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_banner/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_banner/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_banner/tests/common/sanity.yaml new file mode 100644 index 00000000..93d0963b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_banner/tests/common/sanity.yaml @@ -0,0 +1,80 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_banner sanity test + +- name: Set a fact for 'banner_exec_image_ok' + ansible.builtin.set_fact: + banner_exec_image_ok: true + when: platform is search("N7K|N3K-F") + +- name: Set a fact for 'banner_motd_image_ok' + ansible.builtin.set_fact: + banner_motd_image_ok: true + when: imagetag is not search("I7") and ansible_connection != "ansible.netcommon.httpapi" + +- block: + - ansible.builtin.debug: + msg: START nxos_banner exec tests + + - name: Setup exec + cisco.nxos.nxos_banner: &id002 + banner: exec + state: absent + + - name: Set exec + register: result + cisco.nxos.nxos_banner: &id001 + banner: exec + text: "this is my exec banner\nthat has a multiline\nstring" + state: present + + - ansible.builtin.assert: + that: + - result.changed == true + - "'banner exec @\nthis is my exec banner\nthat has a multiline\nstring\n@' in result.commands" + + - name: Set exec again (idempotent) + register: result + cisco.nxos.nxos_banner: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands | length == 0 + + - name: Teardown exec + cisco.nxos.nxos_banner: *id002 + when: banner_exec_image_ok == True + +- block: + - name: Setup MOTD + cisco.nxos.nxos_banner: &id004 + banner: motd + state: absent + + - name: Set MOTD + register: result + cisco.nxos.nxos_banner: &id003 + banner: motd + text: "Junk motd banner\nover multiple lines" + state: present + + - ansible.builtin.assert: + that: + - result.changed == true + - "'banner motd @\nJunk motd banner\nover multiple lines\n@' in result.commands" + + - name: Set MOTD again (idempotent) + register: result + cisco.nxos.nxos_banner: *id003 + + - ansible.builtin.assert: + that: + - result.changed == false + + - name: Teardown MOTD + cisco.nxos.nxos_banner: *id004 + when: banner_motd_image_ok == True + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_banner sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_global/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_global/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_global/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_global/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_global/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_global/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_global/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_global/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_global/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_global/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_global/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_global/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_global/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_global/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_global/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_global/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_global/tests/common/sanity.yaml new file mode 100644 index 00000000..48322a82 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_global/tests/common/sanity.yaml @@ -0,0 +1,167 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_bfd_global sanity test + +- name: Set facts common + ansible.builtin.set_fact: + echo: deleted + nd_echo: loopback1 + interval: &id001 + tx: 50 + min_rx: 50 + multiplier: 3 + nd_interval: + tx: 51 + min_rx: 52 + multiplier: 4 + slow: 2000 + nd_slow: 2001 + +- name: Set facts (exclude 5k/6k) + ansible.builtin.set_fact: + echo_rx: 50 + nd_echo_rx: 51 + ipv4_echo_rx: 50 + nd_ipv4_echo_rx: 54 + ipv4_interval: *id001 + nd_ipv4_interval: &id002 + tx: 54 + min_rx: 56 + multiplier: 8 + ipv4_slow: 2000 + nd_ipv4_slow: 2044 + when: platform is not search('N5K|N6K') + +- name: Set facts (exclude 35/5k/6k) + ansible.builtin.set_fact: + ipv6_echo_rx: 50 + nd_ipv6_echo_rx: 56 + ipv6_interval: *id001 + nd_ipv6_interval: *id002 + ipv6_slow: 2000 + nd_ipv6_slow: 2046 + when: platform is not search('N35|N5K|N6K') + +- name: Set facts (exclude 5k/6k/7k) + ansible.builtin.set_fact: + startup: 5 + nd_startup: 6 + when: platform is not search('N35|N5K|N6K|N7K') + +- name: Set facts 3k defaults (resets some values above) + ansible.builtin.set_fact: + echo_rx: 250 + interval: &id003 + tx: 250 + min_rx: 250 + multiplier: 3 + ipv4_echo_rx: 250 + ipv6_echo_rx: 250 + ipv4_interval: *id003 + ipv6_interval: *id003 + ipv4_slow: 2000 + ipv6_slow: 2000 + when: platform is search('N3K') + +- name: Set facts fabricpath + ansible.builtin.set_fact: + fab_interval: *id001 + nd_fab_interval: + tx: 57 + min_rx: 57 + multiplier: 7 + fab_slow_timer: 2000 + nd_fab_slow_timer: 2007 + fab_vlan: 1 + nd_fab_vlan: 47 + when: platform is not search('N35|N3K|N9K') + +- name: Setup + ignore_errors: true + cisco.nxos.nxos_feature: &id008 + feature: bfd + state: disabled + +- name: Setup supporting loopback interface + cisco.nxos.nxos_config: + lines: interface loopback1 + match: none + +- name: "'feature bfd' init" + delay: 3 + retries: 1 + register: result + until: result is not failed + ignore_errors: true + cisco.nxos.nxos_bfd_global: + slow_timer: "{{ nd_slow }}" + +- block: + - name: Bfd non defaults + register: result + cisco.nxos.nxos_bfd_global: &id004 + echo_interface: "{{ nd_echo }}" + echo_rx_interval: "{{ nd_echo_rx | default(omit) }}" + interval: "{{ nd_interval }}" + slow_timer: "{{ nd_slow }}" + startup_timer: "{{ nd_startup | default(omit) }}" + ipv4_echo_rx_interval: "{{ nd_ipv4_echo_rx | default(omit) }}" + ipv6_echo_rx_interval: "{{ nd_ipv6_echo_rx | default(omit) }}" + ipv4_interval: "{{ nd_ipv4_interval | default(omit) }}" + ipv6_interval: "{{ nd_ipv6_interval | default(omit) }}" + ipv4_slow_timer: "{{ nd_ipv4_slow | default(omit) }}" + ipv6_slow_timer: "{{ nd_ipv6_slow | default(omit) }}" + fabricpath_interval: "{{ nd_fab_interval | default(omit) }}" + fabricpath_slow_timer: "{{ nd_fab_slow | default(omit) }}" + fabricpath_vlan: "{{ nd_fab_vlan | default(omit) }}" + + - ansible.builtin.assert: &id005 + that: + - result.changed == true + + - name: Bfd_non_def idempotence + register: result + cisco.nxos.nxos_bfd_global: *id004 + + - ansible.builtin.assert: &id007 + that: + - result.changed == false + + - name: Bfd defaults + register: result + cisco.nxos.nxos_bfd_global: &id006 + echo_interface: "{{ echo }}" + echo_rx_interval: "{{ echo_rx | default(omit) }}" + interval: "{{ interval }}" + slow_timer: "{{ slow }}" + startup_timer: "{{ startup | default(omit) }}" + ipv4_echo_rx_interval: "{{ ipv4_echo_rx | default(omit) }}" + ipv6_echo_rx_interval: "{{ ipv6_echo_rx | default(omit) }}" + ipv4_interval: "{{ ipv4_interval | default(omit) }}" + ipv6_interval: "{{ ipv6_interval | default(omit) }}" + ipv4_slow_timer: "{{ ipv4_slow | default(omit) }}" + ipv6_slow_timer: "{{ ipv6_slow | default(omit) }}" + fabricpath_interval: "{{ fab_interval | default(omit) }}" + fabricpath_slow_timer: "{{ fab_slow | default(omit) }}" + fabricpath_vlan: "{{ fab_vlan | default(omit) }}" + + - ansible.builtin.assert: *id005 + + - name: Bfd_def idempotence + register: result + cisco.nxos.nxos_bfd_global: *id006 + + - ansible.builtin.assert: *id007 + always: + - name: Teardown + ignore_errors: true + cisco.nxos.nxos_feature: *id008 + + - name: Teardown supporting loopback interface + ignore_errors: true + cisco.nxos.nxos_config: + lines: no interface loopback1 + match: none + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_bfd_global sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/defaults/main.yaml new file mode 100644 index 00000000..871ea460 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "[^_].*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tasks/cli.yaml new file mode 100644 index 00000000..9aa0d869 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tasks/cli.yaml @@ -0,0 +1,33 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tasks/nxapi.yaml new file mode 100644 index 00000000..5cb76e67 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tests/common/_populate_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tests/common/_populate_config.yaml new file mode 100644 index 00000000..6c260faf --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tests/common/_populate_config.yaml @@ -0,0 +1,15 @@ +--- +- name: Populate configuration - 1 + cisco.nxos.nxos_config: + lines: + - "feature bfd" + - "interface {{ nxos_int1 }}" + - " no switchport" + - " no bfd" + +- name: Populate configuration - 2 + cisco.nxos.nxos_config: + lines: + - "interface {{ nxos_int2 }}" + - " no switchport" + - " no bfd echo" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tests/common/_remove_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tests/common/_remove_config.yaml new file mode 100644 index 00000000..b1fa61c1 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tests/common/_remove_config.yaml @@ -0,0 +1,9 @@ +--- +- name: Remove configuration + cisco.nxos.nxos_config: + lines: + - "no feature bfd" + - "default interface {{ nxos_int1 }}" + - "default interface {{ nxos_int2 }}" + - "default interface {{ nxos_int3 }}" + ignore_errors: true diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tests/common/deleted.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tests/common/deleted.yaml new file mode 100644 index 00000000..7c07064b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tests/common/deleted.yaml @@ -0,0 +1,73 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_bfd_interfaces deleted integration tests connection={{ ansible_connection }} + +- name: Set a fact for 'test_int1' + ansible.builtin.set_fact: + test_int1: "{{ nxos_int1 }}" + +- name: Set a fact for 'bfd_disable' and 'bfd_enable' + ansible.builtin.set_fact: + bfd_enable: enable + bfd_disable: disable + when: platform is not search('N5K|N6K') + +- name: Setup1 + cisco.nxos.nxos_config: &id002 + lines: + - "no feature bfd" + - "default interface {{ test_int1 }}" + +- block: + - name: Setup2 + cisco.nxos.nxos_config: + lines: + - "feature bfd" + - "interface {{ test_int1 }}" + - " no switchport" + + - name: Setup initial BFD state + cisco.nxos.nxos_bfd_interfaces: + config: + - name: "{{ test_int1 }}" + bfd: "{{ bfd_disable|default(omit)}}" + echo: disable + state: merged + + - name: Gather bfd_interfaces facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: bfd_interfaces + + - name: Deleted + register: result + cisco.nxos.nxos_bfd_interfaces: &id001 + config: + - name: "{{ test_int1 }}" + state: deleted + + - ansible.builtin.assert: + that: + - result.changed == true + - "'bfd echo' in result.commands" + msg: "Assert failed. 'result.commands': {{ result.commands }}" + + - ansible.builtin.assert: + that: + - "{{ 'bfd' in result.commands }}" + msg: "Assert failed. 'result.commands': {{ result.commands }}" + when: bfd_enable is defined + + - name: Idempotence - deleted + register: result + cisco.nxos.nxos_bfd_interfaces: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + always: + - name: Teardown + cisco.nxos.nxos_config: *id002 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tests/common/empty_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tests/common/empty_config.yaml new file mode 100644 index 00000000..037de389 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tests/common/empty_config.yaml @@ -0,0 +1,61 @@ +--- +- ansible.builtin.debug: + msg: START nxos_bfd_interfaces empty_config integration tests on connection={{ ansible_connection }} + +- name: Merged with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_bfd_interfaces: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_bfd_interfaces: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Overridden with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_bfd_interfaces: + config: + state: overridden + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Rendered with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_bfd_interfaces: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' + +- name: Parsed with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_bfd_interfaces: + running_config: + state: parsed + +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state parsed' + +- ansible.builtin.debug: + msg: END nxos_bfd_interfaces empty_config integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tests/common/gathered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tests/common/gathered.yaml new file mode 100644 index 00000000..2b2c8d94 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tests/common/gathered.yaml @@ -0,0 +1,21 @@ +--- +- ansible.builtin.debug: + msg: START nxos_bfd_interfaces gathered integration tests on connection={{ ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Gather bfd_interfaces facts from the device using nxos_bfd_interfaces + register: result + cisco.nxos.nxos_bfd_interfaces: + state: gathered + + - ansible.builtin.assert: + that: "{{ result['gathered'][:3] | symmetric_difference(gathered) |length == 0 }}" + always: + - ansible.builtin.include_tasks: _remove_config.yaml + + - ansible.builtin.debug: + msg: END nxos_bfd_interfaces gathered integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tests/common/merged.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tests/common/merged.yaml new file mode 100644 index 00000000..2bbd1eb5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tests/common/merged.yaml @@ -0,0 +1,71 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_bfd_interfaces merged integration tests connection={{ ansible_connection }} + +- name: Set a fact for 'test_int1' + ansible.builtin.set_fact: + test_int1: "{{ nxos_int1 }}" + +- name: Set a fact for 'bfd_disable' and 'bfd_enable' + ansible.builtin.set_fact: + bfd_enable: enable + bfd_disable: disable + when: platform is not search('N5K|N6K') + +- name: Setup1 + cisco.nxos.nxos_config: &id002 + lines: + - "no feature bfd" + - "default interface {{ test_int1 }}" + +- block: + - name: Setup2 + cisco.nxos.nxos_config: + lines: + - "feature bfd" + - "interface {{ test_int1 }}" + - " no switchport" + + - name: Merged + register: result + cisco.nxos.nxos_bfd_interfaces: &id001 + config: + - name: "{{ test_int1 }}" + bfd: "{{ bfd_disable|default(omit)}}" + echo: disable + state: merged + + - ansible.builtin.assert: + that: + - result.changed == true + - "'no bfd echo' in result.commands" + msg: "Assert failed. 'result.commands': {{ result.commands }}" + + - ansible.builtin.assert: + that: + - "{{ 'no bfd' in result.commands }}" + msg: "Assert failed. 'result.commands': {{ result.commands }}" + when: bfd_enable is defined + + - name: Gather bfd_interfaces facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: bfd_interfaces + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.bfd_interfaces|symmetric_difference(result.after)|length == 0 + + - name: Idempotence - merged + register: result + cisco.nxos.nxos_bfd_interfaces: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + always: + - name: Teardown + cisco.nxos.nxos_config: *id002 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tests/common/overridden.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tests/common/overridden.yaml new file mode 100644 index 00000000..8b3a66d4 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tests/common/overridden.yaml @@ -0,0 +1,79 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_bfd_interfaces overridden integration tests connection={{ ansible_connection }} + +- name: Set a fact for 'test_int1' + ansible.builtin.set_fact: + test_int1: "{{ nxos_int1 }}" + +- name: Set a fact for 'test_int2' + ansible.builtin.set_fact: + test_int2: "{{ nxos_int2 }}" + +- name: Set a fact for 'bfd_disable' and 'bfd_enable' + ansible.builtin.set_fact: + bfd_enable: enable + bfd_disable: disable + when: platform is not search('N5K|N6K') + +- name: Setup1 + cisco.nxos.nxos_config: &id002 + lines: + - "no feature bfd" + - "default interface {{ test_int1 }}" + - "default interface {{ test_int2 }}" + +- block: + - name: Setup2 + cisco.nxos.nxos_config: + lines: + - "feature bfd" + + - name: Setup3 + cisco.nxos.nxos_config: + lines: + - "no switchport" + parents: "interface {{ item }}" + loop: + - "{{ test_int1 }}" + - "{{ test_int2 }}" + + - name: Setup initial BFD state + cisco.nxos.nxos_bfd_interfaces: + config: + - name: "{{ test_int1 }}" + bfd: "{{ bfd_disable|default(omit)}}" + echo: enable + + - name: "{{ test_int2 }}" + bfd: "{{ bfd_enable|default(omit)}}" + echo: disable + state: merged + + - name: Overridden + register: result + cisco.nxos.nxos_bfd_interfaces: &id001 + config: + - name: "{{ test_int1 }}" + bfd: "{{ bfd_disable|default(omit)}}" + echo: disable + state: overridden + + - ansible.builtin.assert: + that: + - result.changed == true + - result.commands[1] == 'bfd echo' + - result.commands[3] == 'no bfd echo' + msg: "Assert failed. 'result.commands': {{ result.commands }}" + + - name: Idempotence - overridden + register: result + cisco.nxos.nxos_bfd_interfaces: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + always: + - name: Teardown + cisco.nxos.nxos_config: *id002 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tests/common/parsed.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tests/common/parsed.yaml new file mode 100644 index 00000000..4cc9c6b3 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tests/common/parsed.yaml @@ -0,0 +1,31 @@ +--- +- ansible.builtin.debug: + msg: START nxos_bfd_interfaces parsed integration tests on connection={{ ansible_connection }} + +- block: + # Interfaces used in the task don't actually exist on the appliance + - name: Use parsed state to convert externally supplied configuration to structured format + register: result + cisco.nxos.nxos_bfd_interfaces: + running_config: | + feature bfd + interface Ethernet1/800 + no switchport + no bfd + no bfd echo + interface Ethernet1/801 + no switchport + no bfd + interface Ethernet1/802 + no switchport + no bfd echo + interface mgmt0 + ip address dhcp + vrf member management + state: parsed + + - ansible.builtin.assert: + that: "{{ parsed | symmetric_difference(result['parsed']) |length==0 }}" + +- ansible.builtin.debug: + msg: END nxos_bfd_interfaces parsed integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tests/common/rendered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tests/common/rendered.yaml new file mode 100644 index 00000000..56dae25f --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tests/common/rendered.yaml @@ -0,0 +1,36 @@ +--- +- ansible.builtin.debug: + msg: START nxos_bfd_interfaces rendered integration tests on connection={{ ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- block: + # Interfaces used here doesn't actually exist on the device + - name: Use rendered state to convert task input to device specific commands + register: result + cisco.nxos.nxos_bfd_interfaces: + config: + - name: Ethernet1/800 + bfd: enable + echo: enable + - name: Ethernet1/801 + bfd: disable + echo: disable + state: rendered + + - ansible.builtin.assert: + that: "{{ rendered | symmetric_difference(result['rendered']) |length==0 }}" + + - name: Gather bfd_interfaces facts from the device and assert that its empty + register: result + cisco.nxos.nxos_bfd_interfaces: + state: gathered + + - name: Make sure that rendered task actually did not make any changes to the device + ansible.builtin.assert: + that: "{{ result['gathered'] == [] }}" + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: END nxos_bfd_interfaces rendered integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tests/common/replaced.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tests/common/replaced.yaml new file mode 100644 index 00000000..498ee7d9 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/tests/common/replaced.yaml @@ -0,0 +1,68 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_bfd_interfaces replaced integration tests connection={{ ansible_connection }} + +- name: Set a fact for 'test_int1' + ansible.builtin.set_fact: + test_int1: "{{ nxos_int1 }}" + +- name: Set a fact for 'bfd_disable' and 'bfd_enable' + ansible.builtin.set_fact: + bfd_enable: enable + bfd_disable: disable + when: platform is not search('N5K|N6K') + +- name: Setup1 + cisco.nxos.nxos_config: &id002 + lines: + - "no feature bfd" + - "default interface {{ test_int1 }}" + +- block: + - name: Setup2 + cisco.nxos.nxos_config: + lines: + - "feature bfd" + - "interface {{ test_int1 }}" + - " no switchport" + + - name: Setup initial BFD state + cisco.nxos.nxos_bfd_interfaces: + config: + - name: "{{ test_int1 }}" + bfd: "{{ bfd_disable|default(omit)}}" + echo: enable + state: merged + + - name: Replaced + register: result + cisco.nxos.nxos_bfd_interfaces: &id001 + config: + - name: "{{ test_int1 }}" + bfd: "{{ bfd_enable|default(omit)}}" + echo: disable + state: replaced + + - ansible.builtin.assert: + that: + - result.changed == true + - "'no bfd echo' in result.commands" + msg: "Assert failed. 'result.commands': {{ result.commands }}" + + - ansible.builtin.assert: + that: + - "{{ 'bfd' in result.commands }}" + msg: "Assert failed. 'result.commands': {{ result.commands }}" + when: bfd_enable is defined + + - name: Idempotence - replaced + register: result + cisco.nxos.nxos_bfd_interfaces: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + always: + - name: Teardown + cisco.nxos.nxos_config: *id002 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/vars/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/vars/main.yml new file mode 100644 index 00000000..eec612c5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bfd_interfaces/vars/main.yml @@ -0,0 +1,33 @@ +--- +gathered: + - name: "{{ nxos_int1 }}" + bfd: disable + echo: enable + - name: "{{ nxos_int2 }}" + echo: disable + bfd: enable + - name: "{{ nxos_int3 }}" + bfd: enable + echo: enable + +parsed: + - bfd: disable + echo: disable + name: Ethernet1/800 + - bfd: disable + echo: enable + name: Ethernet1/801 + - bfd: enable + echo: disable + name: Ethernet1/802 + - bfd: enable + echo: enable + name: mgmt0 + +rendered: + - "interface Ethernet1/800" + - "bfd" + - "bfd echo" + - "interface Ethernet1/801" + - "no bfd" + - "no bfd echo" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp/defaults/main.yaml new file mode 100644 index 00000000..525b7aab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp/defaults/main.yaml @@ -0,0 +1,5 @@ +--- +testcase: "*" +vrfs: + - default + - myvrf diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp/tests/common/dis_policy.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp/tests/common/dis_policy.yaml new file mode 100644 index 00000000..0f4bd883 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp/tests/common/dis_policy.yaml @@ -0,0 +1,85 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_bgp parameter test + +- ansible.builtin.debug: + msg: This bgp_disable_policy is not supported on {{ image_version }} + when: imagetag is search("A8|D1") + +- name: Set a fact for 'bgp_disable_policy' + ansible.builtin.set_fact: + bgp_disable_policy: false + +- name: Set a fact for 'bgp_disable_policy' + ansible.builtin.set_fact: + bgp_disable_policy: true + when: imagetag is not search("A8|D1") + +- name: Disable 'feature bgp' + ignore_errors: true + cisco.nxos.nxos_feature: + feature: bgp + state: disabled + +- name: Enable 'feature bgp' + ignore_errors: true + cisco.nxos.nxos_feature: + feature: bgp + state: enabled + +- block: + - name: Set disable policy + register: result + when: bgp_disable_policy + cisco.nxos.nxos_bgp: &id001 + asn: 65535 + disable_policy_batching: true + disable_policy_batching_ipv4_prefix_list: v4_p + disable_policy_batching_ipv6_prefix_list: v6_p + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + when: bgp_disable_policy + + - name: Check idempotence + register: result + when: bgp_disable_policy + cisco.nxos.nxos_bgp: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + when: bgp_disable_policy + + - name: Reset disable policy + register: result + when: bgp_disable_policy + cisco.nxos.nxos_bgp: &id003 + asn: 65535 + disable_policy_batching: false + disable_policy_batching_ipv4_prefix_list: default + disable_policy_batching_ipv6_prefix_list: default + + - ansible.builtin.assert: *id002 + when: bgp_disable_policy + + - name: Check idempotence + register: result + when: bgp_disable_policy + cisco.nxos.nxos_bgp: *id003 + + - ansible.builtin.assert: *id004 + when: bgp_disable_policy + rescue: + - ansible.builtin.debug: + msg: Tests can fail on A8 or helsinki images + always: + - name: Disable 'feature bgp' + ignore_errors: true + cisco.nxos.nxos_feature: + feature: bgp + state: disabled + + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_bgp parameter test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp/tests/common/hels.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp/tests/common/hels.yaml new file mode 100644 index 00000000..65b7c725 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp/tests/common/hels.yaml @@ -0,0 +1,101 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_bgp parameter test + +- ansible.builtin.debug: + msg: This test is not supported on {{ image_version }} + when: imagetag is search("D1") + +- name: Set a fact for 'test_helsinki' + ansible.builtin.set_fact: + test_helsinki: false + +- name: Set a fact for 'test_helsinki' + ansible.builtin.set_fact: + test_helsinki: true + when: imagetag is not search("D1") + +- name: Disable 'feature bgp' + ignore_errors: true + when: test_helsinki + cisco.nxos.nxos_feature: + feature: bgp + state: disabled + +- name: Enable 'feature bgp' + ignore_errors: true + when: test_helsinki + cisco.nxos.nxos_feature: + feature: bgp + state: enabled + +- block: + - name: Set helsinki + with_items: "{{ vrfs }}" + register: result + when: test_helsinki + cisco.nxos.nxos_bgp: &id001 + asn: 65535 + vrf: "{{ item }}" + graceful_restart_timers_restart: 130 + graceful_restart_timers_stalepath_time: 310 + neighbor_down_fib_accelerate: true + reconnect_interval: 55 + timer_bgp_hold: 110 + timer_bgp_keepalive: 45 + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + when: test_helsinki + + - name: Check idempotence + with_items: "{{ vrfs }}" + register: result + when: test_helsinki + cisco.nxos.nxos_bgp: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + when: test_helsinki + + - name: Reset helsinki + with_items: "{{ vrfs }}" + register: result + when: test_helsinki + cisco.nxos.nxos_bgp: &id003 + asn: 65535 + vrf: "{{ item }}" + graceful_restart: true + graceful_restart_timers_restart: default + graceful_restart_timers_stalepath_time: default + neighbor_down_fib_accelerate: false + reconnect_interval: default + timer_bgp_hold: default + timer_bgp_keepalive: default + + - ansible.builtin.assert: *id002 + when: test_helsinki + + - name: Check idempotence + with_items: "{{ vrfs }}" + register: result + when: test_helsinki + cisco.nxos.nxos_bgp: *id003 + + - ansible.builtin.assert: *id004 + when: test_helsinki + rescue: + - ansible.builtin.debug: + msg: Tests can fail on helsinki images + always: + - name: Disable 'feature bgp' + ignore_errors: true + when: test_helsinki + cisco.nxos.nxos_feature: + feature: bgp + state: disabled + + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_bgp parameter test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp/tests/common/isolate.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp/tests/common/isolate.yaml new file mode 100644 index 00000000..de4bafb1 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp/tests/common/isolate.yaml @@ -0,0 +1,81 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_bgp parameter test + +- ansible.builtin.debug: + msg: This bgp_isolate is not supported on {{ image_version }} + when: imagetag is search("A8") + +- name: Set a fact for 'bgp_isolate' + ansible.builtin.set_fact: + bgp_isolate: false + +- name: Set a fact for 'bgp_isolate' + ansible.builtin.set_fact: + bgp_isolate: true + when: imagetag is not search("A8") + +- name: Disable 'feature bgp' + ignore_errors: true + cisco.nxos.nxos_feature: + feature: bgp + state: disabled + +- name: Enable 'feature bgp' + ignore_errors: true + cisco.nxos.nxos_feature: + feature: bgp + state: enabled + +- block: + - name: Set isolate + register: result + when: bgp_isolate + cisco.nxos.nxos_bgp: &id001 + asn: 65535 + isolate: false + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + when: bgp_isolate + + - name: Check idempotence + register: result + when: bgp_isolate + cisco.nxos.nxos_bgp: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + when: bgp_isolate + + - name: Reset isolate + register: result + when: bgp_isolate + cisco.nxos.nxos_bgp: &id003 + asn: 65535 + isolate: true + + - ansible.builtin.assert: *id002 + when: bgp_isolate + + - name: Check idempotence + register: result + when: bgp_isolate + cisco.nxos.nxos_bgp: *id003 + + - ansible.builtin.assert: *id004 + when: bgp_isolate + rescue: + - ansible.builtin.debug: + msg: Tests can fail on A8 images + always: + - name: Disable 'feature bgp' + ignore_errors: true + cisco.nxos.nxos_feature: + feature: bgp + state: disabled + + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_bgp parameter test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp/tests/common/param.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp/tests/common/param.yaml new file mode 100644 index 00000000..a4d7c2ff --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp/tests/common/param.yaml @@ -0,0 +1,258 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_bgp parameter test + +- name: Disable 'feature bgp' + ignore_errors: true + cisco.nxos.nxos_feature: + feature: bgp + state: disabled + +- name: Enable 'feature bgp' + ignore_errors: true + cisco.nxos.nxos_feature: + feature: bgp + state: enabled + +- block: + - name: Set multi VRF params + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp: &id001 + asn: 65535 + vrf: "{{ item }}" + router_id: 192.0.2.1 + bestpath_always_compare_med: true + bestpath_aspath_multipath_relax: true + bestpath_compare_routerid: true + bestpath_cost_community_ignore: true + bestpath_med_confed: true + bestpath_med_missing_as_worst: true + bestpath_med_non_deterministic: true + graceful_restart_helper: true + log_neighbor_changes: true + maxas_limit: 50 + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Check idempotence + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Reset multi VRF params + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp: &id003 + asn: 65535 + vrf: "{{ item }}" + bestpath_always_compare_med: false + bestpath_aspath_multipath_relax: false + bestpath_compare_routerid: false + bestpath_cost_community_ignore: false + bestpath_med_confed: false + bestpath_med_missing_as_worst: false + bestpath_med_non_deterministic: false + graceful_restart_helper: false + log_neighbor_changes: false + maxas_limit: default + router_id: default + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp: *id003 + + - ansible.builtin.assert: *id004 + + - name: Set clusterid + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp: &id005 + asn: 65535 + vrf: "{{ item }}" + cluster_id: 10.0.0.1 + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp: *id005 + + - ansible.builtin.assert: *id004 + + - name: Reset cluster_id + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp: &id006 + asn: 65535 + vrf: "{{ item }}" + cluster_id: default + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp: *id006 + + - ansible.builtin.assert: *id004 + + - name: Set confederation + register: result + cisco.nxos.nxos_bgp: &id007 + asn: 65535 + confederation_id: 99 + confederation_peers: + - 16 + - 22 + - 18 + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_bgp: *id007 + + - ansible.builtin.assert: *id004 + + - name: Reset confederation + register: result + cisco.nxos.nxos_bgp: &id008 + asn: 65535 + confederation_id: default + confederation_peers: default + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_bgp: *id008 + + - ansible.builtin.assert: *id004 + + - name: Set confederation_local_as + register: result + cisco.nxos.nxos_bgp: &id009 + asn: 65535 + vrf: myvrf + local_as: 33 + confederation_id: 99 + confederation_peers: + - 16 + - 22 + - 18 + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_bgp: *id009 + + - ansible.builtin.assert: *id004 + + - name: Reset confederation local_as + register: result + cisco.nxos.nxos_bgp: &id010 + asn: 65535 + vrf: myvrf + local_as: default + confederation_id: default + confederation_peers: default + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_bgp: *id010 + + - ansible.builtin.assert: *id004 + + - name: Set local_as + register: result + cisco.nxos.nxos_bgp: &id011 + asn: 65535 + vrf: myvrf + local_as: 33 + confederation_id: 99 + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_bgp: *id011 + + - ansible.builtin.assert: *id004 + + - name: Reset local_as + register: result + cisco.nxos.nxos_bgp: &id012 + asn: 65535 + vrf: myvrf + confederation_id: default + local_as: default + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_bgp: *id012 + + - ansible.builtin.assert: *id004 + + - name: Set default VRF params + register: result + cisco.nxos.nxos_bgp: &id013 + asn: 65535 + event_history_cli: size_medium + event_history_detail: size_large + event_history_events: size_medium + event_history_periodic: size_small + enforce_first_as: false + fast_external_fallover: false + flush_routes: true + shutdown: true + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_bgp: *id013 + + - ansible.builtin.assert: *id004 + + - name: Reset default VRF params + register: result + cisco.nxos.nxos_bgp: &id014 + asn: 65535 + event_history_detail: default + enforce_first_as: true + fast_external_fallover: true + flush_routes: false + shutdown: false + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_bgp: *id014 + + - ansible.builtin.assert: *id004 + always: + - name: Disable 'feature bgp' + ignore_errors: true + cisco.nxos.nxos_feature: + feature: bgp + state: disabled + + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_bgp parameter test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp/tests/common/sanity.yaml new file mode 100644 index 00000000..dc2b018c --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp/tests/common/sanity.yaml @@ -0,0 +1,138 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_bgp sanity test + +- name: Set a fact for 'neighbor_down_fib_accelerate' + ansible.builtin.set_fact: + neighbor_down_fib_accelerate: true + when: (not titanium) and ((imagetag != 'N1') and (imagetag != 'D1')) + +- name: Set a fact for 'reconnect_interval' + ansible.builtin.set_fact: + reconnect_interval: "55" + when: (not titanium) and ((imagetag != 'N1') and (imagetag != 'D1')) + +- name: Set a fact for 'isolate' + ansible.builtin.set_fact: + isolate: false + when: platform is not match("N35") + +- name: Enable 'feature bgp' + ignore_errors: true + cisco.nxos.nxos_feature: + feature: bgp + state: enabled + +- name: Setup + ignore_errors: true + register: result + cisco.nxos.nxos_bgp: &id002 + asn: 65535 + state: absent + +- block: + - name: Configure BGP defaults + register: result + cisco.nxos.nxos_bgp: &id001 + asn: 65535 + router_id: 192.0.2.1 + state: present + + - ansible.builtin.assert: &id003 + that: + - result.changed == true + + - name: Check idempotence + register: result + cisco.nxos.nxos_bgp: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Remove BGP + register: result + cisco.nxos.nxos_bgp: *id002 + + - ansible.builtin.assert: *id003 + + - name: Check idempotence + register: result + cisco.nxos.nxos_bgp: *id002 + + - ansible.builtin.assert: *id004 + + - name: Configure BGP non defaults + register: result + cisco.nxos.nxos_bgp: &id005 + asn: 65535 + router_id: 192.0.2.1 + bestpath_always_compare_med: true + bestpath_aspath_multipath_relax: true + bestpath_compare_routerid: true + bestpath_cost_community_ignore: true + bestpath_med_confed: true + bestpath_med_missing_as_worst: true + bestpath_med_non_deterministic: true + cluster_id: 10.0.0.1 + confederation_id: 99 + disable_policy_batching: true + enforce_first_as: false + fast_external_fallover: false + flush_routes: true + graceful_restart_helper: true + graceful_restart_timers_restart: 130 + graceful_restart_timers_stalepath_time: 310 + isolate: "{{isolate|default(omit)}}" + log_neighbor_changes: true + maxas_limit: 50 + neighbor_down_fib_accelerate: "{{neighbor_down_fib_accelerate|default(omit)}}" + reconnect_interval: "{{reconnect_interval|default(omit)}}" + shutdown: true + timer_bestpath_limit: 255 + timer_bgp_hold: 110 + timer_bgp_keepalive: 45 + event_history_cli: size_medium + event_history_detail: size_large + event_history_events: size_medium + event_history_periodic: size_small + suppress_fib_pending: true + state: present + + - ansible.builtin.assert: *id003 + + - name: Check idempotence + register: result + cisco.nxos.nxos_bgp: *id005 + + - ansible.builtin.assert: *id004 + + - name: Remove BGP + register: result + cisco.nxos.nxos_bgp: *id002 + + - ansible.builtin.assert: *id003 + + - name: Check idempotence + register: result + cisco.nxos.nxos_bgp: *id002 + + - ansible.builtin.assert: *id004 + + - name: Disable 'feature bgp' + cisco.nxos.nxos_feature: + feature: bgp + state: disabled + rescue: + - name: Cleanup BGP + ignore_errors: true + cisco.nxos.nxos_bgp: *id002 + + - name: Disable 'feature bgp' + ignore_errors: true + cisco.nxos.nxos_feature: + feature: bgp + state: disabled + always: + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_bgp sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp/tests/common/supp_fib.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp/tests/common/supp_fib.yaml new file mode 100644 index 00000000..ead5a515 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp/tests/common/supp_fib.yaml @@ -0,0 +1,120 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_bgp parameter test + +- name: Set a fact for 'bgp_best_path_limit' + ansible.builtin.set_fact: + bgp_best_path_limit: false + +- name: Set a fact for 'bgp_best_path_limit' + ansible.builtin.set_fact: + bgp_best_path_limit: true + when: imagetag is not search("I2") + +- name: Set a fact for 'bgp_suppress_fib_supported' + ansible.builtin.set_fact: + bgp_suppress_fib_supported: false + +- name: Set a fact for 'bgp_suppress_fib_supported' + ansible.builtin.set_fact: + bgp_suppress_fib_supported: true + when: imagetag is not search("A8|D1|I2|I4") + +- name: Disable 'feature bgp' + ignore_errors: true + cisco.nxos.nxos_feature: + feature: bgp + state: disabled + +- name: Enable 'feature bgp' + ignore_errors: true + cisco.nxos.nxos_feature: + feature: bgp + state: enabled + +- block: + - name: Set bestpath limit + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp: &id001 + asn: 65535 + vrf: "{{ item }}" + timer_bestpath_limit: 255 + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Check idempotence + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Reset bestpath limit + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp: &id003 + asn: 65535 + vrf: "{{ item }}" + timer_bestpath_limit: default + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + with_items: "{{ vrfs }}" + register: result + when: bgp_best_path_limit + cisco.nxos.nxos_bgp: *id003 + + - ansible.builtin.assert: *id004 + when: bgp_best_path_limit + + - name: Set suppress FIB + register: result + cisco.nxos.nxos_bgp: &id005 + asn: 65535 + suppress_fib_pending: false + + - ansible.builtin.assert: *id002 + when: bgp_suppress_fib_supported + + - name: Check idempotence + register: result + when: bgp_suppress_fib_supported + cisco.nxos.nxos_bgp: *id005 + + - ansible.builtin.assert: *id004 + when: bgp_suppress_fib_supported + + - name: Reset suppress FIB + register: result + cisco.nxos.nxos_bgp: &id006 + asn: 65535 + suppress_fib_pending: true + + - ansible.builtin.assert: *id002 + when: bgp_suppress_fib_supported + + - name: Check idempotence + register: result + when: bgp_suppress_fib_supported + cisco.nxos.nxos_bgp: *id006 + + - ansible.builtin.assert: *id004 + when: bgp_suppress_fib_supported + rescue: + - ansible.builtin.debug: + msg: Tests can fail on I2/I4/A8/Fretta or helsinki images + always: + - name: Disable 'feature bgp' + ignore_errors: true + cisco.nxos.nxos_feature: + feature: bgp + state: disabled + + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_bgp parameter test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/defaults/main.yaml new file mode 100644 index 00000000..871ea460 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "[^_].*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/meta/main.yml new file mode 100644 index 00000000..ed97d539 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/meta/main.yml @@ -0,0 +1 @@ +--- diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tasks/cli.yaml new file mode 100644 index 00000000..9e4fb34b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tasks/main.yaml new file mode 100644 index 00000000..026b6e47 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tasks/main.yaml @@ -0,0 +1,26 @@ +--- +- name: Enable 'feature bgp' + cisco.nxos.nxos_feature: + feature: bgp + vars: + ansible_connection: ansible.netcommon.network_cli + +- name: Run the CLI and NX-API tests + block: + - name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + + - name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi + + always: + - name: Disable 'feature bgp' + cisco.nxos.nxos_feature: + feature: bgp + state: disabled + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tasks/nxapi.yaml new file mode 100644 index 00000000..5cb76e67 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tests/common/_populate_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tests/common/_populate_config.yaml new file mode 100644 index 00000000..337d1c9e --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tests/common/_populate_config.yaml @@ -0,0 +1,19 @@ +--- +- name: "Setup - 1" + cisco.nxos.nxos_config: + lines: + - "router bgp 65536" + - " address-family ipv4 multicast" + - " nexthop route-map rmap2" + - " nexthop trigger-delay critical 120 non-critical 180" + - " network 192.0.2.32/27" + - " network 192.0.2.64/27 route-map rmap1" + - " vrf site-1" + - " address-family ipv4 unicast" + - " default-information originate" + - " aggregate-address 203.0.113.0/24 as-set summary-only" + - " address-family ipv6 multicast" + - " redistribute ospfv3 100 route-map rmap-ospf-1" + - " redistribute eigrp 101 route-map rmap-eigrp-1" + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tests/common/_remove_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tests/common/_remove_config.yaml new file mode 100644 index 00000000..af709257 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tests/common/_remove_config.yaml @@ -0,0 +1,8 @@ +--- +- name: Remove pre-existing BGP configurations + cisco.nxos.nxos_config: + lines: + - no router bgp 65536 + ignore_errors: true + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tests/common/deleted.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tests/common/deleted.yaml new file mode 100644 index 00000000..5f068d66 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tests/common/deleted.yaml @@ -0,0 +1,87 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_bgp_address_family deleted integration tests connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- name: Setup more afs + cisco.nxos.nxos_config: + lines: + - "router bgp 65536" + - " vrf site-1" + - " address-family ipv4 multicast" + - " vrf site-2" + - " address-family ipv6 unicast" + vars: + ansible_connection: ansible.netcommon.network_cli + +- block: + - name: Delete BGP configs handled by this module + cisco.nxos.nxos_bgp_address_family: + config: + as_number: 65536 + address_family: + - afi: ipv4 + safi: multicast + - vrf: site-1 + afi: ipv4 + safi: unicast + - vrf: site-1 + afi: ipv6 + safi: multicast + state: deleted + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ deleted['before']['address_family'] | symmetric_difference(result['before']['address_family']) |length == 0 }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ result['commands'] | symmetric_difference(deleted['commands']) |length == 0 }}" + + - name: Assert that after dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ deleted['after']['address_family'] | symmetric_difference(result['after']['address_family']) |length == 0 }}" + + - ansible.builtin.include_tasks: _remove_config.yaml + + - ansible.builtin.include_tasks: _populate_config.yaml + + - name: Delete all BGP configs handled by this module + cisco.nxos.nxos_bgp_address_family: &id001 + state: deleted + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ merged['after']['address_family'] | symmetric_difference(result['before']['address_family']) |length == 0 }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ result['commands'] | symmetric_difference(deleted_all['commands']) |length == 0 }}" + + - name: Assert that after dicts were correctly generated + ansible.builtin.assert: + that: + - deleted_all['after'] == result['after'] + + - name: Delete all BGP configs handled by this module (idempotent) + cisco.nxos.nxos_bgp_address_family: *id001 + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tests/common/empty_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tests/common/empty_config.yaml new file mode 100644 index 00000000..5b9ff2f7 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tests/common/empty_config.yaml @@ -0,0 +1,61 @@ +--- +- ansible.builtin.debug: + msg: START nxos_bgp_address_family empty_config integration tests on connection={{ ansible_connection }} + +- name: Merged with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_bgp_address_family: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_bgp_address_family: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Overridden with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_bgp_address_family: + config: + state: overridden + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Rendered with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_bgp_address_family: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' + +- name: Parsed with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_bgp_address_family: + running_config: + state: parsed + +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state parsed' + +- ansible.builtin.debug: + msg: END nxos_bgp_address_family empty_config integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tests/common/fixtures/parsed.cfg b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tests/common/fixtures/parsed.cfg new file mode 100644 index 00000000..9716bb92 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tests/common/fixtures/parsed.cfg @@ -0,0 +1,13 @@ +router bgp 65536 + address-family ipv4 multicast + nexthop route-map rmap2 + nexthop trigger-delay critical 120 non-critical 180 + network 192.0.2.32/27 + network 192.0.2.64/27 route-map rmap1 + vrf site-1 + address-family ipv4 unicast + default-information originate + aggregate-address 203.0.113.0/24 as-set summary-only + address-family ipv6 multicast + redistribute ospfv3 100 route-map rmap-ospf-1 + redistribute eigrp 101 route-map rmap-eigrp-1 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tests/common/gathered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tests/common/gathered.yaml new file mode 100644 index 00000000..bc7e63c6 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tests/common/gathered.yaml @@ -0,0 +1,22 @@ +--- +- ansible.builtin.debug: + msg: START nxos_bgp_address_family gathered integration tests on connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Gather BGP facts using gathered + register: result + cisco.nxos.nxos_bgp_address_family: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: + - "{{ merged['after']['address_family'] | symmetric_difference(result['gathered']['address_family']) |length == 0 }}" + - merged['after']['as_number'] == result['gathered']['as_number'] + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tests/common/merged.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tests/common/merged.yaml new file mode 100644 index 00000000..b3c50d4c --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tests/common/merged.yaml @@ -0,0 +1,70 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_bgp_address_family merged integration tests connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- block: + - name: Merge the provided configuration with the existing running configuration + cisco.nxos.nxos_bgp_address_family: &id001 + config: + as_number: 65536 + address_family: + - afi: ipv4 + safi: multicast + networks: + - prefix: 192.0.2.32/27 + - prefix: 192.0.2.64/27 + route_map: rmap1 + nexthop: + route_map: rmap2 + trigger_delay: + critical_delay: 120 + non_critical_delay: 180 + - afi: ipv4 + safi: unicast + vrf: site-1 + default_information: + originate: true + aggregate_address: + - prefix: 203.0.113.0/24 + as_set: true + summary_only: true + - afi: ipv6 + safi: multicast + vrf: site-1 + redistribute: + - protocol: ospfv3 + id: 100 + route_map: rmap-ospf-1 + - protocol: eigrp + id: 101 + route_map: rmap-eigrp-1 + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ result['before'] == {} }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ merged['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ merged['after']['address_family'] | symmetric_difference(result['after']['address_family']) |length == 0 }}" + - merged['after']['as_number'] == result['after']['as_number'] + + - name: Merge the provided configuration with the existing running configuration (idempotent) + cisco.nxos.nxos_bgp_address_family: *id001 + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tests/common/overridden.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tests/common/overridden.yaml new file mode 100644 index 00000000..8aa99e45 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tests/common/overridden.yaml @@ -0,0 +1,57 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_bgp_address_family overridden integration tests connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Override all BGP AF configuration with provided configuration + cisco.nxos.nxos_bgp_address_family: &overridden + config: + as_number: 65536 + address_family: + - afi: ipv4 + safi: multicast + networks: + - prefix: 192.0.2.64/27 + route_map: rmap1 + aggregate_address: + - prefix: 203.0.113.0/24 + as_set: true + summary_only: true + - afi: ipv4 + safi: unicast + vrf: site-1 + state: overridden + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ merged['after']['address_family'] | symmetric_difference(result['before']['address_family']) |length == 0 }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ overridden['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ overridden['after']['address_family'] | symmetric_difference(result['after']['address_family']) |length == 0 }}" + - overridden['after']['as_number'] == result['after']['as_number'] + + - name: Replace device configurations of listed OSPF processes with provided configurarions (idempotent) + register: result + cisco.nxos.nxos_bgp_address_family: *overridden + + - name: Assert that task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tests/common/parsed.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tests/common/parsed.yaml new file mode 100644 index 00000000..6636605a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tests/common/parsed.yaml @@ -0,0 +1,15 @@ +--- +- ansible.builtin.debug: + msg: START nxos_bgp_address_family parsed integration tests on connection={{ ansible_connection }} + +- name: Parse externally provided BGP configuration + register: result + cisco.nxos.nxos_bgp_address_family: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed + +- name: Assert that configuration was correctly parsed + ansible.builtin.assert: + that: + - "{{ merged['after']['address_family'] | symmetric_difference(result['parsed']['address_family']) |length == 0 }}" + - merged['after']['as_number'] == result['parsed']['as_number'] diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tests/common/rendered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tests/common/rendered.yaml new file mode 100644 index 00000000..2f405b28 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tests/common/rendered.yaml @@ -0,0 +1,56 @@ +--- +- ansible.builtin.debug: + msg: START nxos_bgp_address_family rendered integration tests on connection={{ ansible_connection }} + +- name: Render platform specific configuration lines with state rendered (without connecting to the device) + cisco.nxos.nxos_bgp_address_family: + config: + as_number: 65536 + address_family: + - afi: ipv4 + safi: multicast + networks: + - prefix: 192.0.2.32/27 + - prefix: 192.0.2.64/27 + route_map: rmap1 + nexthop: + route_map: rmap2 + trigger_delay: + critical_delay: 120 + non_critical_delay: 180 + - afi: ipv4 + safi: unicast + vrf: site-1 + default_information: + originate: true + aggregate_address: + - prefix: 203.0.113.0/24 + as_set: true + summary_only: true + - afi: ipv6 + safi: multicast + vrf: site-1 + redistribute: + - protocol: ospfv3 + id: 100 + route_map: rmap-ospf-1 + - protocol: eigrp + id: 101 + route_map: rmap-eigrp-1 + state: rendered + register: result + +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - "{{ merged['commands'] | symmetric_difference(result['rendered']) |length == 0 }}" + +- name: Gather BGP facts + cisco.nxos.nxos_bgp_address_family: + state: gathered + register: result + +- name: Ensure that no configuration changes were made + ansible.builtin.assert: + that: + - result.gathered == {} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tests/common/replaced.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tests/common/replaced.yaml new file mode 100644 index 00000000..d6cb9d3d --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/tests/common/replaced.yaml @@ -0,0 +1,62 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_bgp_address_family replaced integration tests connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Merge the provided configuration with the existing running configuration + cisco.nxos.nxos_bgp_address_family: &replaced + config: + as_number: 65536 + address_family: + - afi: ipv4 + safi: multicast + networks: + - prefix: 192.0.2.64/27 + route_map: rmap1 + nexthop: + route_map: rmap2 + trigger_delay: + critical_delay: 120 + non_critical_delay: 180 + aggregate_address: + - prefix: 203.0.113.0/24 + as_set: true + summary_only: true + - afi: ipv4 + safi: unicast + vrf: site-1 + state: replaced + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ merged['after']['address_family'] | symmetric_difference(result['before']['address_family']) |length == 0 }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ replaced['after']['address_family'] | symmetric_difference(result['after']['address_family']) |length == 0 }}" + - replaced['after']['as_number'] == result['after']['as_number'] + + - name: Replace device configurations of listed OSPF processes with provided configurarions (idempotent) + register: result + cisco.nxos.nxos_bgp_address_family: *replaced + + - name: Assert that task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/vars/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/vars/main.yml new file mode 100644 index 00000000..bc245dad --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_address_family/vars/main.yml @@ -0,0 +1,195 @@ +--- +merged: + commands: + - router bgp 65536 + - address-family ipv4 multicast + - nexthop route-map rmap2 + - nexthop trigger-delay critical 120 non-critical 180 + - network 192.0.2.32/27 + - network 192.0.2.64/27 route-map rmap1 + - vrf site-1 + - address-family ipv4 unicast + - default-information originate + - aggregate-address 203.0.113.0/24 as-set summary-only + - address-family ipv6 multicast + - redistribute ospfv3 100 route-map rmap-ospf-1 + - redistribute eigrp 101 route-map rmap-eigrp-1 + after: + as_number: "65536" + address_family: + - afi: ipv4 + safi: multicast + networks: + - prefix: 192.0.2.32/27 + - prefix: 192.0.2.64/27 + route_map: rmap1 + nexthop: + route_map: rmap2 + trigger_delay: + critical_delay: 120 + non_critical_delay: 180 + - afi: ipv4 + safi: unicast + vrf: site-1 + default_information: + originate: true + aggregate_address: + - prefix: 203.0.113.0/24 + as_set: true + summary_only: true + - afi: ipv6 + safi: multicast + vrf: site-1 + redistribute: + - id: "100" + protocol: ospfv3 + route_map: rmap-ospf-1 + - id: "101" + protocol: eigrp + route_map: rmap-eigrp-1 + +replaced: + commands: + - router bgp 65536 + - address-family ipv4 multicast + - no network 192.0.2.32/27 + - aggregate-address 203.0.113.0/24 as-set summary-only + - vrf site-1 + - address-family ipv4 unicast + - no default-information originate + - no aggregate-address 203.0.113.0/24 as-set summary-only + after: + as_number: "65536" + address_family: + - afi: ipv4 + safi: multicast + networks: + - prefix: 192.0.2.64/27 + route_map: rmap1 + nexthop: + route_map: rmap2 + trigger_delay: + critical_delay: 120 + non_critical_delay: 180 + aggregate_address: + - prefix: 203.0.113.0/24 + as_set: true + summary_only: true + + - afi: ipv4 + safi: unicast + vrf: site-1 + + - afi: ipv6 + safi: multicast + vrf: site-1 + redistribute: + - protocol: ospfv3 + id: "100" + route_map: rmap-ospf-1 + - protocol: eigrp + id: "101" + route_map: rmap-eigrp-1 + +overridden: + commands: + - router bgp 65536 + - vrf site-1 + - no address-family ipv6 multicast + - exit + - address-family ipv4 multicast + - no nexthop route-map rmap2 + - no nexthop trigger-delay critical 120 non-critical 180 + - aggregate-address 203.0.113.0/24 as-set summary-only + - no network 192.0.2.32/27 + - vrf site-1 + - address-family ipv4 unicast + - no default-information originate + - no aggregate-address 203.0.113.0/24 as-set summary-only + after: + as_number: "65536" + address_family: + - afi: ipv4 + safi: multicast + networks: + - prefix: 192.0.2.64/27 + route_map: rmap1 + aggregate_address: + - prefix: 203.0.113.0/24 + as_set: true + summary_only: true + - afi: ipv4 + safi: unicast + vrf: site-1 + +deleted: + before: + as_number: "65536" + address_family: + - afi: ipv4 + safi: multicast + networks: + - prefix: 192.0.2.32/27 + - prefix: 192.0.2.64/27 + route_map: rmap1 + nexthop: + route_map: rmap2 + trigger_delay: + critical_delay: 120 + non_critical_delay: 180 + + - afi: ipv4 + safi: unicast + vrf: site-1 + default_information: + originate: true + aggregate_address: + - prefix: 203.0.113.0/24 + as_set: true + summary_only: true + + - afi: ipv4 + safi: multicast + vrf: site-1 + + - afi: ipv6 + safi: multicast + vrf: site-1 + redistribute: + - id: "100" + protocol: ospfv3 + route_map: rmap-ospf-1 + - id: "101" + protocol: eigrp + route_map: rmap-eigrp-1 + + - afi: ipv6 + safi: unicast + vrf: site-2 + commands: + - router bgp 65536 + - no address-family ipv4 multicast + - vrf site-1 + - no address-family ipv4 unicast + - no address-family ipv6 multicast + - exit + after: + as_number: "65536" + address_family: + - afi: ipv4 + safi: multicast + vrf: site-1 + - afi: ipv6 + safi: unicast + vrf: site-2 + +deleted_all: + commands: + - router bgp 65536 + - no address-family ipv4 multicast + - vrf site-1 + - no address-family ipv4 unicast + - no address-family ipv6 multicast + - exit + after: + as_number: "65536" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_af/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_af/defaults/main.yaml new file mode 100644 index 00000000..525b7aab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_af/defaults/main.yaml @@ -0,0 +1,5 @@ +--- +testcase: "*" +vrfs: + - default + - myvrf diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_af/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_af/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_af/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_af/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_af/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_af/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_af/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_af/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_af/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_af/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_af/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_af/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_af/tests/common/multisite.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_af/tests/common/multisite.yaml new file mode 100644 index 00000000..93eb7654 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_af/tests/common/multisite.yaml @@ -0,0 +1,132 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_bgp_af multisite sanity test + +- name: Enable 'feature bgp' - multisite + ignore_errors: true + cisco.nxos.nxos_feature: + feature: bgp + state: enabled + +- name: Enable 'feature nv overlay' - multisite + ignore_errors: true + cisco.nxos.nxos_feature: + feature: nv overlay + state: enabled + +- name: Setup - multisite + ignore_errors: true + cisco.nxos.nxos_bgp: + asn: 65535 + state: absent + +- name: Enable NV overlay EVPN - multisite + when: platform is search('N9K') + ignore_errors: true + cisco.nxos.nxos_config: + lines: + - nv overlay evpn + +- name: Enable multisite border gateway - multisite + ignore_errors: true + register: multiout + cisco.nxos.nxos_config: + lines: + - evpn multisite border-gateway 10 + +- block: + - name: Configure BGP_AF route target name + register: result + cisco.nxos.nxos_bgp_af: &id001 + asn: 65535 + afi: l2vpn + safi: evpn + state: present + retain_route_target: abc + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Check idempotence + register: result + cisco.nxos.nxos_bgp_af: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Configure BGP_AF route target default + register: result + cisco.nxos.nxos_bgp_af: &id003 + asn: 65535 + afi: l2vpn + safi: evpn + state: present + retain_route_target: default + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_bgp_af: *id003 + + - ansible.builtin.assert: *id004 + + - name: Configure BGP_AF 1 route target all + register: result + cisco.nxos.nxos_bgp_af: &id005 + asn: 65535 + afi: l2vpn + safi: evpn + state: present + retain_route_target: all + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_bgp_af: *id005 + + - ansible.builtin.assert: *id004 + + - name: Remove BGP - route target + register: result + cisco.nxos.nxos_bgp_af: + asn: 65535 + afi: l2vpn + safi: evpn + retain_route_target: all + state: absent + + - ansible.builtin.assert: *id002 + + - name: Disable multisite border gateway - multisite + cisco.nxos.nxos_config: + lines: + - no evpn multisite border-gateway 10 + when: multiout is not search("Invalid command") + +- name: Disable 'feature bgp' - multisite + ignore_errors: true + cisco.nxos.nxos_feature: + feature: bgp + state: disabled + +- name: Disable 'feature nv overlay' - multisite + ignore_errors: true + cisco.nxos.nxos_feature: + feature: nv overlay + state: disabled + +- ansible.builtin.pause: + seconds: 5 + +- name: Remove NV overlay EVPN - multisite + when: platform is search('N9K') + cisco.nxos.nxos_config: + lines: + - no nv overlay evpn + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_bgp_af multisite sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_af/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_af/tests/common/sanity.yaml new file mode 100644 index 00000000..fa06c19f --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_af/tests/common/sanity.yaml @@ -0,0 +1,342 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_bgp_af sanity test + +- name: Set a fact for 'advertise_l2vpn_evpn' + ansible.builtin.set_fact: + advertise_l2vpn_evpn: true + when: platform is search('N9K') + +- name: Enable 'feature bgp' + ignore_errors: true + cisco.nxos.nxos_feature: + feature: bgp + state: enabled + +- name: Enable 'feature nv overlay' + ignore_errors: true + cisco.nxos.nxos_feature: + feature: nv overlay + state: enabled + +- name: Setup + ignore_errors: true + cisco.nxos.nxos_bgp: &id012 + asn: 65535 + state: absent + +- block: + - name: Enable NV overlay EVPN + when: platform is search('N9K') + cisco.nxos.nxos_config: + lines: + - nv overlay evpn + + - name: Configure BGP_AF 1 + register: result + cisco.nxos.nxos_bgp_af: &id001 + asn: 65535 + vrf: testing + afi: ipv4 + safi: unicast + advertise_l2vpn_evpn: "{{advertise_l2vpn_evpn|default(omit)}}" + state: present + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Check idempotence + register: result + cisco.nxos.nxos_bgp_af: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Remove BGP + register: result + cisco.nxos.nxos_bgp_af: + asn: 65535 + vrf: testing + afi: ipv4 + safi: unicast + state: absent + + - ansible.builtin.assert: *id002 + + - name: Configure BGP_AF 2 + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_af: &id003 + asn: 65535 + vrf: "{{ item }}" + afi: ipv4 + safi: unicast + dampening_state: true + additional_paths_install: true + additional_paths_receive: true + additional_paths_selection: RouteMap + additional_paths_send: true + client_to_client: false + default_information_originate: true + state: present + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_af: *id003 + + - ansible.builtin.assert: *id004 + + - name: Configure BGP_AF def2 + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_af: &id005 + asn: 65535 + vrf: "{{ item }}" + afi: ipv4 + safi: unicast + dampening_state: false + additional_paths_install: false + additional_paths_receive: false + additional_paths_selection: default + additional_paths_send: false + client_to_client: true + default_information_originate: false + state: present + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_af: *id005 + + - ansible.builtin.assert: *id004 + + - name: Remove BGP + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_af: &id008 + asn: 65535 + vrf: "{{ item }}" + afi: ipv4 + safi: unicast + state: absent + + - ansible.builtin.assert: *id002 + + - name: Configure BGP_AF 3 + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_af: &id006 + asn: 65535 + vrf: "{{ item }}" + afi: ipv4 + safi: unicast + dampening_routemap: abcd + default_metric: 50 + distance_ebgp: 30 + distance_ibgp: 60 + distance_local: 90 + maximum_paths: 9 + maximum_paths_ibgp: 9 + next_hop_route_map: RouteMap + suppress_inactive: true + table_map: RouteMap + table_map_filter: true + state: present + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_af: *id006 + + - ansible.builtin.assert: *id004 + + - name: Configure BGP_AF def3 + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_af: &id007 + asn: 65535 + vrf: "{{ item }}" + afi: ipv4 + safi: unicast + dampening_routemap: default + default_metric: default + distance_ebgp: default + distance_ibgp: default + distance_local: default + maximum_paths: default + maximum_paths_ibgp: default + next_hop_route_map: default + suppress_inactive: false + table_map: default + table_map_filter: false + state: present + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_af: *id007 + + - ansible.builtin.assert: *id004 + + - name: Remove BGP + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_af: *id008 + + - ansible.builtin.assert: *id002 + + - name: Configure BGP_AF 4 + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_af: &id009 + asn: 65535 + vrf: "{{ item }}" + afi: ipv4 + safi: unicast + dampen_igp_metric: 200 + dampening_half_time: 1 + dampening_max_suppress_time: 4 + dampening_reuse_time: 2 + dampening_suppress_time: 3 + inject_map: + - - lax_inject_map + - lax_exist_map + - - nyc_inject_map + - nyc_exist_map + - copy-attributes + - - fsd_inject_map + - fsd_exist_map + networks: + - - 10.0.0.0/16 + - routemap_LA + - - 192.168.1.1/32 + - Chicago + - - 192.168.2.0/24 + - - 192.168.3.0/24 + - routemap_NYC + redistribute: + - - direct + - rm_direct + - - lisp + - rm_lisp + state: present + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_af: *id009 + + - ansible.builtin.assert: *id004 + + - name: Configure BGP_AF 5 + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_af: &id010 + asn: 65535 + vrf: "{{ item }}" + afi: ipv4 + safi: unicast + dampen_igp_metric: 300 + dampening_half_time: 10 + dampening_max_suppress_time: 40 + dampening_reuse_time: 20 + dampening_suppress_time: 30 + inject_map: + - - fsd_inject_map + - fsd_exist_map + networks: + - - 192.168.2.0/24 + redistribute: + - - lisp + - rm_lisp + state: present + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_af: *id010 + + - ansible.builtin.assert: *id004 + + - name: Configure BGP_AF def5 + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_af: &id011 + asn: 65535 + vrf: "{{ item }}" + afi: ipv4 + safi: unicast + dampen_igp_metric: default + dampening_half_time: default + dampening_max_suppress_time: default + dampening_reuse_time: default + dampening_suppress_time: default + inject_map: default + networks: default + redistribute: default + state: present + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_af: *id011 + + - ansible.builtin.assert: *id004 + + - name: Remove BGP + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_af: *id008 + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_af: *id008 + + - ansible.builtin.assert: *id004 + rescue: + - name: Cleanup BGP + ignore_errors: true + cisco.nxos.nxos_bgp: *id012 + always: + - name: Disable 'feature bgp' + cisco.nxos.nxos_feature: + feature: bgp + state: disabled + + - name: Disable 'feature nv overlay' + ignore_errors: true + cisco.nxos.nxos_feature: + feature: nv overlay + state: disabled + + - ansible.builtin.pause: + seconds: 5 + + - name: Remove NV overlay EVPN + when: platform is search('N9K') + cisco.nxos.nxos_config: + lines: + - no nv overlay evpn + + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_bgp_af sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/defaults/main.yaml new file mode 100644 index 00000000..871ea460 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "[^_].*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/meta/main.yml new file mode 100644 index 00000000..ed97d539 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/meta/main.yml @@ -0,0 +1 @@ +--- diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tasks/cli.yaml new file mode 100644 index 00000000..9e4fb34b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tasks/main.yaml new file mode 100644 index 00000000..7e1c3b63 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tasks/main.yaml @@ -0,0 +1,34 @@ +--- +- name: Enable 'feature bgp' + cisco.nxos.nxos_feature: + feature: bgp + vars: + ansible_connection: ansible.netcommon.network_cli + +- name: Enable fabric forwarding + cisco.nxos.nxos_config: + lines: feature fabric forwarding + +- name: Run the CLI and NX-API tests + block: + - name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + + - name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi + + always: + - name: Disable 'feature bgp' + cisco.nxos.nxos_feature: + feature: bgp + state: disabled + vars: + ansible_connection: ansible.netcommon.network_cli + + - name: Disable fabric forwarding + cisco.nxos.nxos_config: + lines: no feature fabric forwarding diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tasks/nxapi.yaml new file mode 100644 index 00000000..5cb76e67 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/_populate_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/_populate_config.yaml new file mode 100644 index 00000000..a036433a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/_populate_config.yaml @@ -0,0 +1,61 @@ +--- +- name: "Setup - 1" + cisco.nxos.nxos_config: + lines: + - "router bgp 65536" + - "bestpath as-path multipath-relax" + - "bestpath compare-neighborid" + - "bestpath cost-community ignore" + - "confederation identifier 42" + - "log-neighbor-changes" + - "maxas-limit 20" + - "neighbor-down fib-accelerate" + - "router-id 198.51.100.2" + - "confederation peers 65020 65030 65040" + - "neighbor 198.51.100.20" + - " remote-as 65537" + - " affinity-group 160" + - " description NBR-1" + - " low-memory exempt" + vars: + ansible_connection: ansible.netcommon.network_cli + +- name: "Setup - 2" + cisco.nxos.nxos_config: + lines: + - "neighbor 198.51.100.21" + - " remote-as 65537" + - "vrf site-2" + - " local-as 300" + - " log-neighbor-changes" + - " neighbor-down fib-accelerate" + - " neighbor 203.0.113.2" + - " remote-as 65539" + - " description site-2-nbr-1" + parents: "router bgp 65536" + vars: + ansible_connection: ansible.netcommon.network_cli + +- name: "Setup - 3" + cisco.nxos.nxos_config: + lines: + - "vrf site-1" + - " local-as 200" + - " log-neighbor-changes" + - " neighbor 192.0.2.10" + - " remote-as 65538" + - " description site-1-nbr-1" + parents: "router bgp 65536" + vars: + ansible_connection: ansible.netcommon.network_cli + +- name: "Setup - 3" + cisco.nxos.nxos_config: + lines: + - "vrf site-1" + - " neighbor 192.0.2.11" + - " remote-as 65538" + - " description site-1-nbr-2" + parents: "router bgp 65536" + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/_remove_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/_remove_config.yaml new file mode 100644 index 00000000..af709257 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/_remove_config.yaml @@ -0,0 +1,8 @@ +--- +- name: Remove pre-existing BGP configurations + cisco.nxos.nxos_config: + lines: + - no router bgp 65536 + ignore_errors: true + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/deleted.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/deleted.yaml new file mode 100644 index 00000000..9f9f4dd8 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/deleted.yaml @@ -0,0 +1,44 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_bgp_global deleted integration tests connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Delete BGP configs handled by this module + cisco.nxos.nxos_bgp_global: &id001 + state: deleted + register: result + + - name: Assert that before dicts are correctly generated + ansible.builtin.assert: + that: + - merged['after'] == result['before'] + + - ansible.builtin.debug: + msg: "{{ result['commands'] | symmetric_difference(deleted['commands']) }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ result['commands'] | symmetric_difference(deleted['commands']) |length == 0 }}" + + - name: Assert that after dict is correctly generated + ansible.builtin.assert: + that: + - deleted['after'] == result['after'] + + - name: Delete BGP configs handled by this module (idempotent) + register: result + cisco.nxos.nxos_bgp_global: *id001 + + - name: Assert that task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/deleted_af.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/deleted_af.yaml new file mode 100644 index 00000000..32ee6372 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/deleted_af.yaml @@ -0,0 +1,113 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_bgp_global deleted_af integration tests connection={{ ansible_connection}} + +- name: Remove pre-existing BGP configurations + cisco.nxos.nxos_config: &remove + lines: + - no router bgp 65536 + ignore_errors: true + +- name: "Setup - 1 (add neighbor with AF config)" + cisco.nxos.nxos_config: + lines: + - "router bgp 65536" + - "log-neighbor-changes" + - "maxas-limit 20" + - "router-id 198.51.100.2" + - "neighbor 203.0.113.2" + - " address-family ipv4 unicast" + - " next-hop-self" + - " remote-as 65538" + - " affinity-group 160" + - " description NBR-1" + - " low-memory exempt" + - "neighbor 192.0.2.1" + - " remote-as 65537" + +- block: + - name: Remove a neighbor having AF configurations (should fail) + cisco.nxos.nxos_bgp_global: &deleted + state: deleted + register: result + ignore_errors: true + + - name: Assert that the task failed + ansible.builtin.assert: + that: + - result.failed == True + - "'Neighbor 203.0.113.2 has address-family configurations. Please use the nxos_bgp_neighbor_af module to remove those first.' in result.msg" + + - name: Remove pre-existing BGP configurations + cisco.nxos.nxos_config: *remove + ignore_errors: true + + - name: "Setup - 2 (add neighbor with AF configuration under a vrf)" + cisco.nxos.nxos_config: + lines: + - "router bgp 65536" + - "log-neighbor-changes" + - "maxas-limit 20" + - "router-id 198.51.100.2" + - "neighbor 192.0.2.1" + - " remote-as 65537" + - "vrf site-1" + - " neighbor 203.0.113.2" + - " address-family ipv4 unicast" + - " next-hop-self" + - " remote-as 65538" + - " affinity-group 160" + - " description NBR-1" + - " low-memory exempt" + - " neighbor-down fib-accelerate" + + - name: Remove a neighbor under a VRF having AF configurations (should fail) + cisco.nxos.nxos_bgp_global: *deleted + register: result + ignore_errors: true + + - name: Assert that the task failed + ansible.builtin.assert: + that: + - result.failed == True + - "'VRF site-1 has address-family configurations. Please use the nxos_bgp_af module to remove those first.' in result.msg" + + - name: Remove pre-existing BGP configurations + cisco.nxos.nxos_config: *remove + ignore_errors: true + + - name: "Setup - 3 (add a VRF with AF config)" + cisco.nxos.nxos_config: + lines: + - "router bgp 65536" + - "log-neighbor-changes" + - "maxas-limit 20" + - "router-id 198.51.100.2" + - "neighbor 192.0.2.1" + - " remote-as 65537" + - " password 7 12090404011C03162E" + - "vrf site-1" + - " address-family ipv4 unicast" + - " default-information originate" + - " neighbor 203.0.113.2" + - " remote-as 65538" + - " affinity-group 160" + - " description NBR-1" + - " low-memory exempt" + - "vrf site-2" + - " neighbor-down fib-accelerate" + + - name: Remove a neighbor under a VRF having AF configurations (should fail) + cisco.nxos.nxos_bgp_global: *deleted + register: result + ignore_errors: true + + - name: Assert that the task failed + ansible.builtin.assert: + that: + - result.failed == True + - "'VRF site-1 has address-family configurations. Please use the nxos_bgp_af module to remove those first.' in result.msg" + + always: + - name: Remove pre-existing BGP configurations + cisco.nxos.nxos_config: *remove diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/empty_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/empty_config.yaml new file mode 100644 index 00000000..05b95e48 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/empty_config.yaml @@ -0,0 +1,50 @@ +--- +- ansible.builtin.debug: + msg: START nxos_bgp_global empty_config integration tests on connection={{ ansible_connection }} + +- name: Merged with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_bgp_global: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_bgp_global: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Rendered with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_bgp_global: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' + +- name: Parsed with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_bgp_global: + running_config: + state: parsed + +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state parsed' + +- ansible.builtin.debug: + msg: END nxos_bgp_global empty_config integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/fixtures/parsed.cfg b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/fixtures/parsed.cfg new file mode 100644 index 00000000..9dc978a7 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/fixtures/parsed.cfg @@ -0,0 +1,33 @@ +router bgp 65536 + router-id 198.51.100.2 + confederation identifier 42 + confederation peers 65020 65030 65040 + bestpath as-path multipath-relax + bestpath cost-community ignore + bestpath compare-neighborid + neighbor-down fib-accelerate + maxas-limit 20 + log-neighbor-changes + neighbor 198.51.100.20 + low-memory exempt + remote-as 65537 + description NBR-1 + affinity-group 160 + neighbor 198.51.100.21 + remote-as 65537 + vrf site-1 + local-as 200 + log-neighbor-changes + neighbor 192.0.2.10 + remote-as 65538 + description site-1-nbr-1 + neighbor 192.0.2.11 + remote-as 65538 + description site-1-nbr-2 + vrf site-2 + local-as 300 + neighbor-down fib-accelerate + log-neighbor-changes + neighbor 203.0.113.2 + remote-as 65539 + description site-2-nbr-1 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/gathered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/gathered.yaml new file mode 100644 index 00000000..7b4d28a5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/gathered.yaml @@ -0,0 +1,20 @@ +--- +- ansible.builtin.debug: + msg: START nxos_bgp_global gathered integration tests on connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Gather BGP facts using gathered + register: result + cisco.nxos.nxos_bgp_global: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: merged['after'] == result['gathered'] + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/merged.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/merged.yaml new file mode 100644 index 00000000..84d216d4 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/merged.yaml @@ -0,0 +1,84 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_bgp_global merged integration tests connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- block: + - name: Merge the provided configuration with the existing running configuration + cisco.nxos.nxos_bgp_global: &id001 + config: + as_number: 65536 + router_id: 198.51.100.2 + bestpath: + as_path: + multipath_relax: true + compare_neighborid: true + cost_community_ignore: true + confederation: + identifier: 42 + peers: + - 65020 + - 65030 + - 65040 + log_neighbor_changes: true + maxas_limit: 20 + neighbors: + - neighbor_address: 198.51.100.20 + neighbor_affinity_group: + group_id: 160 + remote_as: 65537 + description: NBR-1 + low_memory: + exempt: true + - neighbor_address: 198.51.100.21 + remote_as: 65537 + neighbor_down: + fib_accelerate: true + vrfs: + - vrf: site-1 + local_as: 200 + log_neighbor_changes: true + neighbors: + - neighbor_address: 192.0.2.10 + description: site-1-nbr-1 + remote_as: 65538 + - neighbor_address: 192.0.2.11 + remote_as: 65538 + description: site-1-nbr-2 + - vrf: site-2 + local_as: 300 + log_neighbor_changes: true + neighbors: + - neighbor_address: 203.0.113.2 + description: site-2-nbr-1 + remote_as: 65539 + neighbor_down: + fib_accelerate: true + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ result['before'] == {} }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ merged['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dicts were correctly generated + ansible.builtin.assert: + that: + - merged['after'] == result['after'] + + - name: Merge the provided configuration with the existing running configuration (idempotent) + cisco.nxos.nxos_bgp_global: *id001 + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/parsed.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/parsed.yaml new file mode 100644 index 00000000..73da9ca8 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/parsed.yaml @@ -0,0 +1,14 @@ +--- +- ansible.builtin.debug: + msg: START nxos_bgp_global parsed integration tests on connection={{ ansible_connection }} + +- name: Parse externally provided BGP configuration + register: result + cisco.nxos.nxos_bgp_global: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed + +- name: Assert that configuration was correctly parsed + ansible.builtin.assert: + that: + - merged['after'] == result['parsed'] diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/purged.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/purged.yaml new file mode 100644 index 00000000..c0288a5b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/purged.yaml @@ -0,0 +1,42 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_bgp_global purged integration tests connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Delete all BGP configuration from the device + cisco.nxos.nxos_bgp_global: &id001 + state: purged + register: result + + - name: Assert that before dicts are correctly generated + ansible.builtin.assert: + that: + - merged['after'] == result['before'] + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "'no router bgp 65536' in result.commands" + - result.commands|length == 1 + + - name: Assert that after dict is correctly generated + ansible.builtin.assert: + that: + - result['after'] == {} + + - name: Delete all BGP configuration from the device (idempotent) + register: result + cisco.nxos.nxos_bgp_global: *id001 + + - name: Assert that task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/rendered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/rendered.yaml new file mode 100644 index 00000000..af3505fb --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/rendered.yaml @@ -0,0 +1,71 @@ +--- +- ansible.builtin.debug: + msg: START nxos_bgp_global rendered integration tests on connection={{ ansible_connection }} + +- name: Render platform specific configuration lines with state rendered (without connecting to the device) + cisco.nxos.nxos_bgp_global: + config: + as_number: 65536 + router_id: 198.51.100.2 + bestpath: + as_path: + multipath_relax: true + compare_neighborid: true + cost_community_ignore: true + confederation: + identifier: 42 + peers: + - 65020 + - 65030 + - 65040 + log_neighbor_changes: true + maxas_limit: 20 + neighbors: + - neighbor_address: 198.51.100.20 + neighbor_affinity_group: + group_id: 160 + remote_as: 65537 + description: NBR-1 + low_memory: + exempt: true + - neighbor_address: 198.51.100.21 + remote_as: 65537 + neighbor_down: + fib_accelerate: true + vrfs: + - vrf: site-1 + local_as: 200 + log_neighbor_changes: true + neighbors: + - neighbor_address: 192.0.2.10 + description: site-1-nbr-1 + remote_as: 65538 + - neighbor_address: 192.0.2.11 + remote_as: 65538 + description: site-1-nbr-2 + - vrf: site-2 + local_as: 300 + log_neighbor_changes: true + neighbors: + - neighbor_address: 203.0.113.2 + description: site-2-nbr-1 + remote_as: 65539 + neighbor_down: + fib_accelerate: true + state: rendered + register: result + +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - merged['commands'] == result['rendered'] + +- name: Gather BGP facts + cisco.nxos.nxos_bgp_global: + state: gathered + register: result + +- name: Ensure that no configuration changes were made + ansible.builtin.assert: + that: + - result.gathered == {} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/replaced.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/replaced.yaml new file mode 100644 index 00000000..62ea0ca5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/replaced.yaml @@ -0,0 +1,76 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_bgp_global replaced integration tests connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Replace BGP configuration with provided configuration + cisco.nxos.nxos_bgp_global: &id001 + config: + as_number: 65536 + router_id: 198.51.100.2 + bestpath: + compare_neighborid: true + cost_community_ignore: true + confederation: + identifier: 42 + peers: + - 65020 + - 65030 + - 65050 + maxas_limit: 40 + neighbors: + - neighbor_address: 198.51.100.20 + neighbor_affinity_group: + group_id: 160 + remote_as: 65537 + description: NBR-1 + low_memory: + exempt: true + neighbor_down: + fib_accelerate: true + vrfs: + - vrf: site-2 + local_as: 300 + log_neighbor_changes: true + neighbors: + - neighbor_address: 203.0.113.2 + neighbor_down: + fib_accelerate: true + state: replaced + register: result + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dict is correctly generated + ansible.builtin.assert: + that: + - replaced['after'] == result['after'] + + - name: Assert that before dicts are correctly generated + ansible.builtin.assert: + that: + - merged['after'] == result['before'] + + - name: Replace device configurations of listed OSPF processes with provided configurarions (idempotent) + register: result + cisco.nxos.nxos_bgp_global: *id001 + + - name: Assert that task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + - name: Assert that before dict is correctly generated + ansible.builtin.assert: + that: + - replaced['after'] == result['before'] + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/replaced_af.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/replaced_af.yaml new file mode 100644 index 00000000..c6e28068 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/replaced_af.yaml @@ -0,0 +1,146 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_bgp_global replaced_af integration tests connection={{ ansible_connection}} + +- name: Remove pre-existing BGP configurations + cisco.nxos.nxos_config: &remove + lines: + - no router bgp 65536 + ignore_errors: true + +- name: "Setup - 1 (add neighbor with AF config)" + cisco.nxos.nxos_config: + lines: + - "router bgp 65536" + - "log-neighbor-changes" + - "maxas-limit 20" + - "router-id 198.51.100.2" + - "neighbor 203.0.113.2" + - " address-family ipv4 unicast" + - " next-hop-self" + - " remote-as 65538" + - " affinity-group 160" + - " description NBR-1" + - " low-memory exempt" + - "neighbor 192.0.2.1" + - " remote-as 65537" + +- block: + - name: Remove a neighbor having AF configurations (should fail) + cisco.nxos.nxos_bgp_global: + config: + as_number: 65536 + router_id: 198.51.100.2 + maxas_limit: 20 + log_neighbor_changes: true + neighbors: + - neighbor_address: 192.0.2.1 + remote_as: 65537 + state: replaced + register: result + ignore_errors: true + + - name: Assert that the task failed + ansible.builtin.assert: + that: + - result.failed == True + - "'Neighbor 203.0.113.2 has address-family configurations. Please use the nxos_bgp_neighbor_af module to remove those first.' in result.msg" + + - name: Remove pre-existing BGP configurations + cisco.nxos.nxos_config: *remove + ignore_errors: true + + - name: "Setup - 2 (add neighbor with AF configuration under a vrf)" + cisco.nxos.nxos_config: + lines: + - "router bgp 65536" + - "log-neighbor-changes" + - "maxas-limit 20" + - "router-id 198.51.100.2" + - "neighbor 192.0.2.1" + - " remote-as 65537" + - "vrf site-1" + - " neighbor 203.0.113.2" + - " address-family ipv4 unicast" + - " next-hop-self" + - " remote-as 65538" + - " affinity-group 160" + - " description NBR-1" + - " low-memory exempt" + - " neighbor-down fib-accelerate" + + - name: Remove a neighbor under a VRF having AF configurations (should fail) + cisco.nxos.nxos_bgp_global: + config: + as_number: 65536 + router_id: 198.51.100.2 + maxas_limit: 20 + log_neighbor_changes: true + neighbors: + - neighbor_address: 192.0.2.1 + remote_as: 65537 + vrfs: + - vrf: site-1 + neighbor_down: + fib_accelerate: true + state: replaced + register: result + ignore_errors: true + + - name: Assert that the task failed + ansible.builtin.assert: + that: + - result.failed == True + - "'Neighbor 203.0.113.2 has address-family configurations. Please use the nxos_bgp_neighbor_af module to remove those first.' in result.msg" + + - name: Remove pre-existing BGP configurations + cisco.nxos.nxos_config: *remove + ignore_errors: true + + - name: "Setup - 3 (add a VRF with AF config)" + cisco.nxos.nxos_config: + lines: + - "router bgp 65536" + - "log-neighbor-changes" + - "maxas-limit 20" + - "router-id 198.51.100.2" + - "neighbor 192.0.2.1" + - " remote-as 65537" + - "vrf site-1" + - " address-family ipv4 unicast" + - " default-information originate" + - " neighbor 203.0.113.2" + - " remote-as 65538" + - " affinity-group 160" + - " description NBR-1" + - " low-memory exempt" + - "vrf site-2" + - " neighbor-down fib-accelerate" + + - name: Remove a VRF having AF configurations (should fail) + cisco.nxos.nxos_bgp_global: + config: + as_number: 65536 + router_id: 198.51.100.2 + maxas_limit: 20 + log_neighbor_changes: true + neighbors: + - neighbor_address: 192.0.2.1 + remote_as: 65537 + vrfs: + - vrf: site-2 + neighbor_down: + fib_accelerate: true + state: replaced + register: result + ignore_errors: true + + - name: Assert that the task failed + ansible.builtin.assert: + that: + - result.failed == True + - "'VRF site-1 has address-family configurations. Please use the nxos_bgp_af module to remove those first.' in result.msg" + + always: + - name: Remove pre-existing BGP configurations + cisco.nxos.nxos_config: *remove diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/sanity.yaml new file mode 100644 index 00000000..8ed423f3 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/tests/common/sanity.yaml @@ -0,0 +1,41 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_bgp_global sanity integration tests connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Replace BGP configuration with different asn (should fail) + cisco.nxos.nxos_bgp_global: + config: + as_number: "65538" + router_id: 198.51.100.2 + bestpath: + compare_neighborid: true + cost_community_ignore: true + state: replaced + ignore_errors: true + register: result + + - ansible.builtin.assert: + that: + - result.failed == True + - "'BGP is already configured with ASN 65536. Please remove it with state purged before configuring new ASN' in result.msg" + + - name: Merge BGP configuration with different asn (should fail) + cisco.nxos.nxos_bgp_global: + config: + as_number: "65538" + router_id: 198.51.100.9 + state: merged + ignore_errors: true + register: result + + - ansible.builtin.assert: + that: + - result.failed == True + - "'BGP is already configured with ASN 65536. Please remove it with state purged before configuring new ASN' in result.msg" + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/vars/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/vars/main.yml new file mode 100644 index 00000000..6155f1fe --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_global/vars/main.yml @@ -0,0 +1,152 @@ +--- +merged: + commands: + - router bgp 65536 + - bestpath as-path multipath-relax + - bestpath compare-neighborid + - bestpath cost-community ignore + - confederation identifier 42 + - log-neighbor-changes + - maxas-limit 20 + - neighbor-down fib-accelerate + - router-id 198.51.100.2 + - confederation peers 65020 65030 65040 + - neighbor 198.51.100.20 + - remote-as 65537 + - affinity-group 160 + - description NBR-1 + - low-memory exempt + - neighbor 198.51.100.21 + - remote-as 65537 + - vrf site-1 + - local-as 200 + - log-neighbor-changes + - neighbor 192.0.2.10 + - remote-as 65538 + - description site-1-nbr-1 + - neighbor 192.0.2.11 + - remote-as 65538 + - description site-1-nbr-2 + - vrf site-2 + - local-as 300 + - log-neighbor-changes + - neighbor-down fib-accelerate + - neighbor 203.0.113.2 + - remote-as 65539 + - description site-2-nbr-1 + + after: + as_number: "65536" + bestpath: + as_path: + multipath_relax: true + compare_neighborid: true + cost_community_ignore: true + confederation: + identifier: "42" + peers: + - "65020" + - "65030" + - "65040" + log_neighbor_changes: true + maxas_limit: 20 + neighbor_down: + fib_accelerate: true + neighbors: + - description: NBR-1 + low_memory: + exempt: true + neighbor_address: 198.51.100.20 + neighbor_affinity_group: + group_id: 160 + remote_as: "65537" + - neighbor_address: 198.51.100.21 + remote_as: "65537" + router_id: 198.51.100.2 + vrfs: + - local_as: "200" + log_neighbor_changes: true + neighbors: + - description: site-1-nbr-1 + neighbor_address: 192.0.2.10 + remote_as: "65538" + - description: site-1-nbr-2 + neighbor_address: 192.0.2.11 + remote_as: "65538" + vrf: site-1 + - local_as: "300" + log_neighbor_changes: true + neighbor_down: + fib_accelerate: true + neighbors: + - description: site-2-nbr-1 + neighbor_address: 203.0.113.2 + remote_as: "65539" + vrf: site-2 + +replaced: + commands: + - router bgp 65536 + - no bestpath as-path multipath-relax + - no log-neighbor-changes + - maxas-limit 40 + - no confederation peers 65020 65030 65040 + - confederation peers 65020 65030 65050 + - no neighbor 198.51.100.21 + - vrf site-2 + - neighbor 203.0.113.2 + - no remote-as 65539 + - no description site-2-nbr-1 + - no vrf site-1 + + after: + as_number: "65536" + bestpath: + compare_neighborid: true + cost_community_ignore: true + confederation: + identifier: "42" + peers: + - "65020" + - "65030" + - "65050" + maxas_limit: 40 + neighbor_down: + fib_accelerate: true + neighbors: + - description: NBR-1 + low_memory: + exempt: true + neighbor_address: 198.51.100.20 + neighbor_affinity_group: + group_id: 160 + remote_as: "65537" + router_id: 198.51.100.2 + vrfs: + - local_as: "300" + log_neighbor_changes: true + neighbor_down: + fib_accelerate: true + neighbors: + - neighbor_address: 203.0.113.2 + vrf: site-2 + +deleted: + commands: + - router bgp 65536 + - no bestpath as-path multipath-relax + - no bestpath compare-neighborid + - no bestpath cost-community ignore + - no confederation identifier 42 + - no log-neighbor-changes + - no maxas-limit 20 + - no neighbor-down fib-accelerate + - no router-id 198.51.100.2 + - no confederation peers 65020 65030 65040 + - no neighbor 198.51.100.20 + - no neighbor 198.51.100.21 + - no vrf site-1 + - no vrf site-2 + + after: + as_number: "65536" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor/defaults/main.yaml new file mode 100644 index 00000000..525b7aab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor/defaults/main.yaml @@ -0,0 +1,5 @@ +--- +testcase: "*" +vrfs: + - default + - myvrf diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor/tests/common/multisite.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor/tests/common/multisite.yaml new file mode 100644 index 00000000..f567a6e0 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor/tests/common/multisite.yaml @@ -0,0 +1,123 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_bgp_neighbor multisite sanity test + +- name: Set a fact for 'intname' + ansible.builtin.set_fact: + intname: "{{ nxos_int1 }}" + +- name: "Setup: disable features - multisite" + loop: + - bgp + - bfd + - nv overlay + ignore_errors: true + cisco.nxos.nxos_feature: + feature: "{{ item }}" + state: disabled + +- name: "Setup: enable features - multisite" + loop: + - bgp + - bfd + - nv overlay + ignore_errors: true + cisco.nxos.nxos_feature: + feature: "{{ item }}" + state: enabled + +- name: Enable NV overlay EVPN - multisite + when: platform is search('N9K') + ignore_errors: true + cisco.nxos.nxos_config: + lines: + - nv overlay evpn + +- name: Enable multisite border gateway - multisite + ignore_errors: true + register: multiout + cisco.nxos.nxos_config: + lines: + - evpn multisite border-gateway 10 + +- block: + - name: Configure BGP neighbor1 - multisite + register: result + cisco.nxos.nxos_bgp_neighbor: &id001 + asn: 65535 + neighbor: 192.0.2.3/32 + remote_as: 33.22 + description: just a description + shutdown: true + state: present + peer_type: fabric_border_leaf + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Check idempotence + register: result + cisco.nxos.nxos_bgp_neighbor: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Configure BGP neighbor2 - multisite + register: result + cisco.nxos.nxos_bgp_neighbor: &id003 + asn: 65535 + neighbor: 192.0.2.3/32 + peer_type: disable + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_bgp_neighbor: *id003 + + - ansible.builtin.assert: *id004 + + - name: Configure BGP neighbor3 - multisite + register: result + cisco.nxos.nxos_bgp_neighbor: &id005 + asn: 65535 + neighbor: 192.0.2.3/32 + peer_type: fabric_external + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_bgp_neighbor: *id005 + + - ansible.builtin.assert: *id004 + + - name: Disable multisite border gateway - multisite + cisco.nxos.nxos_config: + lines: + - no evpn multisite border-gateway 10 + when: multiout is not search("Invalid command") + +- name: "Teardown: disable features" + loop: + - bgp + - bfd + - nv overlay + ignore_errors: true + cisco.nxos.nxos_feature: + feature: "{{ item }}" + state: disabled + +- ansible.builtin.pause: + seconds: 5 + +- name: Remove NV overlay EVPN - multisite + when: platform is search('N9K') + cisco.nxos.nxos_config: + lines: + - no nv overlay evpn + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_bgp_neighbor multisite sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor/tests/common/sanity.yaml new file mode 100644 index 00000000..c2fff45a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor/tests/common/sanity.yaml @@ -0,0 +1,357 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_bgp_neighbor sanity test + +- name: Set a fact for 'intname' + ansible.builtin.set_fact: + intname: "{{ nxos_int1 }}" + +- name: Set a fact for 'log_neighbor_changese' + ansible.builtin.set_fact: + log_neighbor_changese: enable + when: (imagetag and imagetag is not search("D1|N1")) + +- name: Set a fact for 'log_neighbor_changesd' + ansible.builtin.set_fact: + log_neighbor_changesd: disable + when: (imagetag and imagetag is not search("D1|N1")) + +- ansible.builtin.debug: + var: titanium + +- name: Set a fact for 'remove_private_asa' + ansible.builtin.set_fact: + remove_private_asa: all + when: not titanium + +- name: Set a fact for 'remove_private_asr' + ansible.builtin.set_fact: + remove_private_asr: replace-as + when: not titanium + +- name: "Setup: disable features" + loop: + - bgp + - bfd + ignore_errors: true + cisco.nxos.nxos_feature: + feature: "{{ item }}" + state: disabled + +- name: "Setup: enable features" + loop: + - bgp + - bfd + cisco.nxos.nxos_feature: + feature: "{{ item }}" + state: enabled + +- block: + - name: Configure BGP neighbor1 + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_neighbor: &id001 + asn: 65535 + neighbor: 192.0.2.3/32 + vrf: "{{ item }}" + connected_check: true + capability_negotiation: true + dynamic_capability: true + ebgp_multihop: 2 + low_memory_exempt: true + maximum_peers: 10 + suppress_4_byte_as: true + timers_keepalive: 90 + timers_holdtime: 270 + log_neighbor_changes: "{{log_neighbor_changese|default(omit)}}" + local_as: 22.33 + remote_as: 33.22 + description: just a description + update_source: "{{ intname.capitalize() }}" + shutdown: true + state: present + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Check idempotence + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_neighbor: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Configure BGP neighbor2 + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_neighbor: &id003 + asn: 65535 + neighbor: 192.0.2.3/32 + vrf: "{{ item }}" + connected_check: false + capability_negotiation: false + dynamic_capability: false + ebgp_multihop: default + low_memory_exempt: false + maximum_peers: default + suppress_4_byte_as: false + timers_keepalive: default + timers_holdtime: default + log_neighbor_changes: "{{log_neighbor_changesd|default(omit)}}" + local_as: default + remote_as: default + description: default + update_source: default + shutdown: false + state: present + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_neighbor: *id003 + + - ansible.builtin.assert: *id004 + + - name: Remove BGP + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_neighbor: &id005 + asn: 65535 + neighbor: 192.0.2.3/32 + vrf: "{{ item }}" + state: absent + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_neighbor: *id005 + + - ansible.builtin.assert: *id004 + + - name: Configure BGP neighbor3 + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_neighbor: &id006 + asn: 65535 + neighbor: 192.0.2.3/32 + vrf: "{{ item }}" + description: tested by ansible + remove_private_as: "{{remove_private_asa|default(omit)}}" + state: present + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_neighbor: *id006 + + - ansible.builtin.assert: *id004 + + - name: Configure BGP neighbor4 + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_neighbor: &id007 + asn: 65535 + neighbor: 192.0.2.3/32 + vrf: "{{ item }}" + description: tested by ansible + remove_private_as: "{{remove_private_asr|default(omit)}}" + state: present + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_neighbor: *id007 + + - ansible.builtin.assert: *id004 + + - name: Remove BGP + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_neighbor: *id005 + + - ansible.builtin.assert: *id002 + + - name: Configure BGP neighbor 3des password + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_neighbor: &id008 + asn: 65535 + neighbor: 192.0.2.3/32 + vrf: "{{ item }}" + remote_as: 30 + pwd: 386c0565965f89de + pwd_type: 3des + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_neighbor: *id008 + + - ansible.builtin.assert: *id004 + + - name: Remove BGP + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_neighbor: *id005 + + - ansible.builtin.assert: *id002 + + - name: Configure BGP neighbor type 7 password + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_neighbor: &id009 + asn: 65535 + neighbor: 192.0.2.3/32 + vrf: "{{ item }}" + remote_as: 30 + pwd: 386c0565965f89de + pwd_type: cisco_type_7 + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_neighbor: *id009 + + - ansible.builtin.assert: *id004 + + - name: Remove BGP neighbor password + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_neighbor: &id010 + asn: 65535 + neighbor: 192.0.2.3/32 + vrf: "{{ item }}" + remote_as: 30 + pwd: default + pwd_type: default + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_neighbor: *id010 + + - ansible.builtin.assert: *id004 + + - name: Remove BGP + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_neighbor: *id005 + + - ansible.builtin.assert: *id002 + + - name: Configure BGP neighbor transport type passive + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_neighbor: &id011 + asn: 65535 + neighbor: 192.0.2.3 + vrf: "{{ item }}" + remote_as: 30 + transport_passive_only: true + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_neighbor: *id011 + + - ansible.builtin.assert: *id004 + + - name: Configure BGP neighbor transport type default + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_neighbor: &id012 + asn: 65535 + neighbor: 192.0.2.3 + vrf: "{{ item }}" + remote_as: 30 + transport_passive_only: false + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_neighbor: *id012 + + - ansible.builtin.assert: *id004 + + - name: Remove BGP + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_neighbor: &id013 + asn: 65535 + neighbor: 192.0.2.3 + vrf: "{{ item }}" + state: absent + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + with_items: "{{ vrfs }}" + register: result + cisco.nxos.nxos_bgp_neighbor: *id013 + + - ansible.builtin.assert: *id004 + + - name: Configure BFD enable + register: result + cisco.nxos.nxos_bgp_neighbor: &id014 + asn: 65535 + neighbor: 192.168.1.1 + bfd: enable + state: present + + - ansible.builtin.assert: *id002 + + - name: Check BFD enable idempotence + register: result + cisco.nxos.nxos_bgp_neighbor: *id014 + + - ansible.builtin.assert: *id004 + + - name: Configure BFD disable idempotence + register: result + cisco.nxos.nxos_bgp_neighbor: &id015 + asn: 65535 + neighbor: 192.168.1.1 + bfd: disable + state: present + + - ansible.builtin.assert: *id002 + + - name: Check BFD disable idempotence + register: result + cisco.nxos.nxos_bgp_neighbor: *id015 + + - ansible.builtin.assert: *id004 + always: + - name: "Teardown: disable features" + loop: + - bgp + - bfd + ignore_errors: true + cisco.nxos.nxos_feature: + feature: "{{ item }}" + state: disabled + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_bgp_neighbor sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/defaults/main.yaml new file mode 100644 index 00000000..871ea460 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "[^_].*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/meta/main.yml new file mode 100644 index 00000000..ed97d539 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/meta/main.yml @@ -0,0 +1 @@ +--- diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tasks/cli.yaml new file mode 100644 index 00000000..9e4fb34b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tasks/main.yaml new file mode 100644 index 00000000..13eaed64 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tasks/main.yaml @@ -0,0 +1,26 @@ +--- +- name: Enable BGP feature + cisco.nxos.nxos_feature: + feature: bgp + vars: + ansible_connection: ansible.netcommon.network_cli + +- name: Run the CLI and NX-API tests + block: + - name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + + - name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi + + always: + - name: Disable BGP feature + cisco.nxos.nxos_feature: + feature: bgp + state: disabled + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tasks/nxapi.yaml new file mode 100644 index 00000000..5cb76e67 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tests/common/_populate_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tests/common/_populate_config.yaml new file mode 100644 index 00000000..15c07071 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tests/common/_populate_config.yaml @@ -0,0 +1,44 @@ +--- +- name: Populate configuration + cisco.nxos.nxos_bgp_neighbor_address_family: + config: + as_number: 65536 + neighbors: + - neighbor_address: 192.0.2.32 + address_family: + - afi: ipv4 + safi: unicast + maximum_prefix: + max_prefix_limit: 20 + generate_warning_threshold: 75 + weight: 100 + prefix_list: + inbound: rmap1 + outbound: rmap2 + - afi: ipv6 + safi: unicast + - neighbor_address: 192.0.2.33 + address_family: + - afi: ipv4 + safi: multicast + inherit: + template: BasePolicy + sequence: 200 + vrfs: + - vrf: site-1 + neighbors: + - neighbor_address: 203.0.113.1 + address_family: + - afi: ipv4 + safi: unicast + suppress_inactive: true + next_hop_self: + set: true + - neighbor_address: 203.0.113.2 + address_family: + - afi: ipv6 + safi: unicast + - afi: ipv4 + safi: multicast + send_community: + set: true diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tests/common/_remove_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tests/common/_remove_config.yaml new file mode 100644 index 00000000..af709257 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tests/common/_remove_config.yaml @@ -0,0 +1,8 @@ +--- +- name: Remove pre-existing BGP configurations + cisco.nxos.nxos_config: + lines: + - no router bgp 65536 + ignore_errors: true + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tests/common/deleted.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tests/common/deleted.yaml new file mode 100644 index 00000000..7428ad83 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tests/common/deleted.yaml @@ -0,0 +1,78 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_bgp_neighbor_address_family deleted integration tests connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Delete BGP configs handled by this module + cisco.nxos.nxos_bgp_neighbor_address_family: + config: + as_number: 65536 + neighbors: + - neighbor_address: 192.0.2.32 + address_family: + - afi: ipv4 + safi: unicast + vrfs: + - vrf: site-1 + neighbors: + - neighbor_address: 203.0.113.2 + address_family: + - afi: ipv6 + safi: unicast + state: deleted + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ merged['after']['neighbors'] | symmetric_difference(result['before']['neighbors']) |length == 0 }}" + - "{{ merged['after']['vrfs'] | symmetric_difference(result['before']['vrfs']) |length == 0 }}" + - merged['after']['as_number'] == result['before']['as_number'] + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ deleted['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ deleted['after']['neighbors'] | symmetric_difference(result['after']['neighbors']) |length == 0 }}" + - "{{ deleted['after']['vrfs'] | symmetric_difference(result['after']['vrfs']) |length == 0 }}" + - deleted['after']['as_number'] == result['after']['as_number'] + + - ansible.builtin.include_tasks: _remove_config.yaml + + - ansible.builtin.include_tasks: _populate_config.yaml + + - name: Delete all BGP neighbor AF configs handled by this module + cisco.nxos.nxos_bgp_neighbor_address_family: &deleted_all + state: deleted + register: result + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ result['commands'] | symmetric_difference(deleted_all['commands']) |length == 0 }}" + + - name: Assert that after dicts were correctly generated + ansible.builtin.assert: + that: + - deleted_all['after'] == result['after'] + + - name: Delete all BGP neighbor AF configs (idempotent) + cisco.nxos.nxos_bgp_neighbor_address_family: *deleted_all + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tests/common/empty_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tests/common/empty_config.yaml new file mode 100644 index 00000000..5128d38c --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tests/common/empty_config.yaml @@ -0,0 +1,61 @@ +--- +- ansible.builtin.debug: + msg: START nxos_bgp_neighbor_address_family empty_config integration tests on connection={{ ansible_connection }} + +- name: Merged with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_bgp_neighbor_address_family: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_bgp_neighbor_address_family: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Overridden with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_bgp_neighbor_address_family: + config: + state: overridden + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Rendered with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_bgp_neighbor_address_family: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' + +- name: Parsed with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_bgp_neighbor_address_family: + running_config: + state: parsed + +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state parsed' + +- ansible.builtin.debug: + msg: END nxos_bgp_neighbor_address_family empty_config integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tests/common/fixtures/parsed.cfg b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tests/common/fixtures/parsed.cfg new file mode 100644 index 00000000..b2ff94b5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tests/common/fixtures/parsed.cfg @@ -0,0 +1,20 @@ +router bgp 65536 + neighbor 192.0.2.32 + address-family ipv4 unicast + maximum-prefix 20 75 + weight 100 + prefix-list rmap1 in + prefix-list rmap2 out + address-family ipv6 unicast + neighbor 192.0.2.33 + address-family ipv4 multicast + inherit peer-policy BasePolicy 200 + vrf site-1 + neighbor 203.0.113.1 + address-family ipv4 unicast + suppress-inactive + next-hop-self + neighbor 203.0.113.2 + address-family ipv4 multicast + send-community + address-family ipv6 unicast diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tests/common/gathered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tests/common/gathered.yaml new file mode 100644 index 00000000..05bce177 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tests/common/gathered.yaml @@ -0,0 +1,23 @@ +--- +- ansible.builtin.debug: + msg: START nxos_bgp_neighbor_address_family gathered integration tests on connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Gather BGP facts using gathered + register: result + cisco.nxos.nxos_bgp_neighbor_address_family: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: + - "{{ merged['after']['neighbors'] | symmetric_difference(result['gathered']['neighbors']) |length == 0 }}" + - "{{ merged['after']['vrfs'] | symmetric_difference(result['gathered']['vrfs']) |length == 0 }}" + - merged['after']['as_number'] == result['gathered']['as_number'] + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tests/common/merged.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tests/common/merged.yaml new file mode 100644 index 00000000..cf73f960 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tests/common/merged.yaml @@ -0,0 +1,79 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_bgp_neighbor_address_family merged integration tests connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- block: + - name: Merge the provided configuration with the existing running configuration + cisco.nxos.nxos_bgp_neighbor_address_family: &id001 + config: + as_number: 65536 + neighbors: + - neighbor_address: 192.0.2.32 + address_family: + - afi: ipv4 + safi: unicast + maximum_prefix: + max_prefix_limit: 20 + generate_warning_threshold: 75 + weight: 100 + prefix_list: + inbound: rmap1 + outbound: rmap2 + - afi: ipv6 + safi: unicast + - neighbor_address: 192.0.2.33 + address_family: + - afi: ipv4 + safi: multicast + inherit: + template: BasePolicy + sequence: 200 + vrfs: + - vrf: site-1 + neighbors: + - neighbor_address: 203.0.113.1 + address_family: + - afi: ipv4 + safi: unicast + suppress_inactive: true + next_hop_self: + set: true + - neighbor_address: 203.0.113.2 + address_family: + - afi: ipv6 + safi: unicast + - afi: ipv4 + safi: multicast + send_community: + set: true + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ result['before'] == {} }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ merged['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ merged['after']['neighbors'] | symmetric_difference(result['after']['neighbors']) |length == 0 }}" + - "{{ merged['after']['vrfs'] | symmetric_difference(result['after']['vrfs']) |length == 0 }}" + - merged['after']['as_number'] == result['after']['as_number'] + + - name: Merge the provided configuration with the existing running configuration (idempotent) + cisco.nxos.nxos_bgp_neighbor_address_family: *id001 + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tests/common/overridden.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tests/common/overridden.yaml new file mode 100644 index 00000000..c83481b2 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tests/common/overridden.yaml @@ -0,0 +1,62 @@ +--- +- ansible.builtin.debug: + msg: "Start nxos_bgp_neighbor_address_family overridden integration tests connection={{ ansible_connection }}" + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Override all BGP AF configuration with provided configuration + cisco.nxos.nxos_bgp_neighbor_address_family: &overridden + config: + as_number: 65536 + neighbors: + - neighbor_address: 192.0.2.32 + address_family: + - afi: ipv4 + safi: unicast + vrfs: + - vrf: site-1 + neighbors: + - neighbor_address: 203.0.113.1 + address_family: + - afi: ipv4 + safi: unicast + suppress_inactive: true + next_hop_self: + set: true + state: overridden + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ merged['after']['neighbors'] | symmetric_difference(result['before']['neighbors']) |length == 0 }}" + - "{{ merged['after']['vrfs'] | symmetric_difference(result['before']['vrfs']) |length == 0 }}" + - merged['after']['as_number'] == result['before']['as_number'] + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ overridden['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ overridden['after']['neighbors'] | symmetric_difference(result['after']['neighbors']) |length == 0 }}" + - "{{ overridden['after']['vrfs'] | symmetric_difference(result['after']['vrfs']) |length == 0 }}" + - overridden['after']['as_number'] == result['after']['as_number'] + + - name: Override all BGP AF configuration with provided configuration (idempotent) + register: result + cisco.nxos.nxos_bgp_neighbor_address_family: *overridden + + - name: Assert that task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tests/common/parsed.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tests/common/parsed.yaml new file mode 100644 index 00000000..299c0e09 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tests/common/parsed.yaml @@ -0,0 +1,16 @@ +--- +- ansible.builtin.debug: + msg: START nxos_bgp_neighbor_address_family parsed integration tests on connection={{ ansible_connection }} + +- name: Parse externally provided BGP configuration + register: result + cisco.nxos.nxos_bgp_neighbor_address_family: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed + +- name: Assert that configuration was correctly parsed + ansible.builtin.assert: + that: + - "{{ merged['after']['neighbors'] | symmetric_difference(result['parsed']['neighbors']) |length == 0 }}" + - "{{ merged['after']['vrfs'] | symmetric_difference(result['parsed']['vrfs']) |length == 0 }}" + - merged['after']['as_number'] == result['parsed']['as_number'] diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tests/common/rendered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tests/common/rendered.yaml new file mode 100644 index 00000000..5b2c47de --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tests/common/rendered.yaml @@ -0,0 +1,64 @@ +--- +- ansible.builtin.debug: + msg: START nxos_bgp_neighbor_address_family rendered integration tests on connection={{ ansible_connection }} + +- name: Render platform specific configuration lines with state rendered (without connecting to the device) + cisco.nxos.nxos_bgp_neighbor_address_family: + config: + as_number: 65536 + neighbors: + - neighbor_address: 192.0.2.32 + address_family: + - afi: ipv4 + safi: unicast + maximum_prefix: + max_prefix_limit: 20 + generate_warning_threshold: 75 + weight: 100 + prefix_list: + inbound: rmap1 + outbound: rmap2 + - afi: ipv6 + safi: unicast + - neighbor_address: 192.0.2.33 + address_family: + - afi: ipv4 + safi: multicast + inherit: + template: BasePolicy + sequence: 200 + vrfs: + - vrf: site-1 + neighbors: + - neighbor_address: 203.0.113.1 + address_family: + - afi: ipv4 + safi: unicast + suppress_inactive: true + next_hop_self: + set: true + - neighbor_address: 203.0.113.2 + address_family: + - afi: ipv6 + safi: unicast + - afi: ipv4 + safi: multicast + send_community: + set: true + state: rendered + register: result + +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - "{{ merged['commands'] | symmetric_difference(result['rendered']) |length == 0 }}" + +- name: Gather BGP facts + cisco.nxos.nxos_bgp_neighbor_address_family: + state: gathered + register: result + +- name: Ensure that no configuration changes were made + ansible.builtin.assert: + that: + - result.gathered == {} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tests/common/replaced.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tests/common/replaced.yaml new file mode 100644 index 00000000..1b90933b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/tests/common/replaced.yaml @@ -0,0 +1,77 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_bgp_neighbor_address_family replaced integration tests connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Replace specified neighbor afs with given configuration + cisco.nxos.nxos_bgp_neighbor_address_family: &replaced + config: + as_number: 65536 + neighbors: + - neighbor_address: 192.0.2.32 + address_family: + - afi: ipv4 + safi: unicast + weight: 110 + - afi: ipv6 + safi: unicast + - neighbor_address: 192.0.2.33 + address_family: + - afi: ipv4 + safi: multicast + inherit: + template: BasePolicy + sequence: 200 + vrfs: + - vrf: site-1 + neighbors: + - neighbor_address: 203.0.113.1 + address_family: + - afi: ipv4 + safi: unicast + - neighbor_address: 203.0.113.2 + address_family: + - afi: ipv6 + safi: unicast + - afi: ipv4 + safi: multicast + send_community: + set: true + state: replaced + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ merged['after']['neighbors'] | symmetric_difference(result['before']['neighbors']) |length == 0 }}" + - "{{ merged['after']['vrfs'] | symmetric_difference(result['before']['vrfs']) |length == 0 }}" + - merged['after']['as_number'] == result['before']['as_number'] + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ replaced['after']['neighbors'] | symmetric_difference(result['after']['neighbors']) |length == 0 }}" + - "{{ replaced['after']['vrfs'] | symmetric_difference(result['after']['vrfs']) |length == 0 }}" + - replaced['after']['as_number'] == result['after']['as_number'] + + - name: Replace device configurations of listed OSPF processes with provided configurarions (idempotent) + register: result + cisco.nxos.nxos_bgp_neighbor_address_family: *replaced + + - name: Assert that task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/vars/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/vars/main.yml new file mode 100644 index 00000000..894dcbd0 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_address_family/vars/main.yml @@ -0,0 +1,201 @@ +--- +merged: + commands: + - router bgp 65536 + - neighbor 192.0.2.32 + - address-family ipv4 unicast + - maximum-prefix 20 75 + - weight 100 + - prefix-list rmap1 in + - prefix-list rmap2 out + - address-family ipv6 unicast + - neighbor 192.0.2.33 + - address-family ipv4 multicast + - inherit peer-policy BasePolicy 200 + - vrf site-1 + - neighbor 203.0.113.1 + - address-family ipv4 unicast + - suppress-inactive + - next-hop-self + - neighbor 203.0.113.2 + - address-family ipv6 unicast + - address-family ipv4 multicast + - send-community + after: + as_number: "65536" + neighbors: + - neighbor_address: 192.0.2.32 + address_family: + - afi: ipv4 + safi: unicast + maximum_prefix: + max_prefix_limit: 20 + generate_warning_threshold: 75 + weight: 100 + prefix_list: + inbound: rmap1 + outbound: rmap2 + - afi: ipv6 + safi: unicast + - neighbor_address: 192.0.2.33 + address_family: + - afi: ipv4 + safi: multicast + inherit: + template: BasePolicy + sequence: 200 + vrfs: + - vrf: site-1 + neighbors: + - neighbor_address: 203.0.113.1 + address_family: + - afi: ipv4 + safi: unicast + suppress_inactive: true + next_hop_self: + set: true + - neighbor_address: 203.0.113.2 + address_family: + - afi: ipv4 + safi: multicast + send_community: + standard: true + - afi: ipv6 + safi: unicast + +replaced: + commands: + - router bgp 65536 + - neighbor 192.0.2.32 + - address-family ipv4 unicast + - no maximum-prefix 20 75 + - weight 110 + - no prefix-list rmap1 in + - no prefix-list rmap2 out + - vrf site-1 + - neighbor 203.0.113.1 + - address-family ipv4 unicast + - no suppress-inactive + - no next-hop-self + after: + as_number: "65536" + neighbors: + - neighbor_address: 192.0.2.32 + address_family: + - afi: ipv4 + safi: unicast + weight: 110 + - afi: ipv6 + safi: unicast + - neighbor_address: 192.0.2.33 + address_family: + - afi: ipv4 + safi: multicast + inherit: + template: BasePolicy + sequence: 200 + vrfs: + - vrf: site-1 + neighbors: + - neighbor_address: 203.0.113.1 + address_family: + - afi: ipv4 + safi: unicast + - neighbor_address: 203.0.113.2 + address_family: + - afi: ipv4 + safi: multicast + send_community: + standard: true + - afi: ipv6 + safi: unicast + +overridden: + commands: + - router bgp 65536 + - neighbor 192.0.2.32 + - address-family ipv4 unicast + - no maximum-prefix 20 75 + - no weight 100 + - no prefix-list rmap1 in + - no prefix-list rmap2 out + - no address-family ipv6 unicast + - neighbor 192.0.2.33 + - no address-family ipv4 multicast + - vrf site-1 + - neighbor 203.0.113.2 + - no address-family ipv4 multicast + - no address-family ipv6 unicast + after: + as_number: "65536" + neighbors: + - neighbor_address: 192.0.2.32 + address_family: + - afi: ipv4 + safi: unicast + vrfs: + - vrf: site-1 + neighbors: + - neighbor_address: 203.0.113.1 + address_family: + - afi: ipv4 + safi: unicast + suppress_inactive: true + next_hop_self: + set: true + +deleted: + commands: + - router bgp 65536 + - neighbor 192.0.2.32 + - no address-family ipv4 unicast + - vrf site-1 + - neighbor 203.0.113.2 + - no address-family ipv6 unicast + after: + as_number: "65536" + neighbors: + - neighbor_address: 192.0.2.32 + address_family: + - afi: ipv6 + safi: unicast + - neighbor_address: 192.0.2.33 + address_family: + - afi: ipv4 + safi: multicast + inherit: + template: BasePolicy + sequence: 200 + vrfs: + - vrf: site-1 + neighbors: + - neighbor_address: 203.0.113.1 + address_family: + - afi: ipv4 + safi: unicast + suppress_inactive: true + next_hop_self: + set: true + - neighbor_address: 203.0.113.2 + address_family: + - afi: ipv4 + safi: multicast + send_community: + standard: true + +deleted_all: + commands: + - router bgp 65536 + - neighbor 192.0.2.32 + - no address-family ipv4 unicast + - no address-family ipv6 unicast + - neighbor 192.0.2.33 + - no address-family ipv4 multicast + - vrf site-1 + - neighbor 203.0.113.1 + - no address-family ipv4 unicast + - neighbor 203.0.113.2 + - no address-family ipv6 unicast + - no address-family ipv4 multicast + after: + as_number: "65536" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_af/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_af/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_af/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_af/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_af/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_af/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_af/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_af/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_af/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_af/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_af/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_af/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_af/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_af/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_af/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_af/tests/common/multisite.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_af/tests/common/multisite.yaml new file mode 100644 index 00000000..12c31f7a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_af/tests/common/multisite.yaml @@ -0,0 +1,117 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_bgp_neighbor_af multisite sanity test + +- name: Set a fact for 'soft_reconfiguration_ina' + ansible.builtin.set_fact: + soft_reconfiguration_ina: always + when: imagetag is not search("D1|N1") + +- name: Disable 'feature bgp' - multisite + ignore_errors: true + cisco.nxos.nxos_feature: + feature: bgp + state: disabled + +- name: Enable 'feature bgp' - multisite + ignore_errors: true + cisco.nxos.nxos_feature: + feature: bgp + state: enabled + +- name: Enable 'feature nv overlay' - multisite + ignore_errors: true + cisco.nxos.nxos_feature: + feature: nv overlay + state: enabled + +- name: Enable NV overlay EVPN - multisite + when: platform is search('N9K') + cisco.nxos.nxos_config: + lines: + - nv overlay evpn + +- name: Enable multisite border gateway - multisite + ignore_errors: true + register: multiout + cisco.nxos.nxos_config: + lines: + - evpn multisite border-gateway 10 + +- block: + - name: Configure EBGP - multisite + cisco.nxos.nxos_bgp_neighbor: + asn: 65535 + neighbor: 192.0.2.3 + remote_as: 2 + + - name: Configure BGP neighbor - multisite + register: result + cisco.nxos.nxos_bgp_neighbor_af: &id001 + asn: 65535 + neighbor: 192.0.2.3 + afi: l2vpn + safi: evpn + send_community: standard + rewrite_evpn_rt_asn: true + state: present + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Check idempotence + register: result + cisco.nxos.nxos_bgp_neighbor_af: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Configure BGP neighbor 1 - multisite + register: result + cisco.nxos.nxos_bgp_neighbor_af: &id003 + asn: 65535 + neighbor: 192.0.2.3 + afi: l2vpn + safi: evpn + send_community: standard + rewrite_evpn_rt_asn: false + state: present + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_bgp_neighbor_af: *id003 + + - ansible.builtin.assert: *id004 + + - name: Disable multisite border gateway - multisite + cisco.nxos.nxos_config: + lines: + - no evpn multisite border-gateway 10 + when: multiout is not search("Invalid command") + +- name: Disable 'feature bgp' - multisite + cisco.nxos.nxos_feature: + feature: bgp + state: disabled + +- name: Disable 'feature nv overlay' - multisite + ignore_errors: true + cisco.nxos.nxos_feature: + feature: nv overlay + state: disabled + +- ansible.builtin.pause: + seconds: 5 + +- name: Remove NV overlay EVPN - multisite + when: platform is search('N9K') + cisco.nxos.nxos_config: + lines: + - no nv overlay evpn + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_bgp_neighbor_af multisite sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_af/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_af/tests/common/sanity.yaml new file mode 100644 index 00000000..3b680ad5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_bgp_neighbor_af/tests/common/sanity.yaml @@ -0,0 +1,295 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_bgp_neighbor_af sanity test + +- name: Set a fact for 'soft_reconfiguration_ina' + ansible.builtin.set_fact: + soft_reconfiguration_ina: always + when: imagetag is not search("D1|N1") + +- name: Disable 'feature bgp' + ignore_errors: true + cisco.nxos.nxos_feature: &id013 + feature: bgp + state: disabled + +- name: Enable 'feature bgp' + ignore_errors: true + cisco.nxos.nxos_feature: + feature: bgp + state: enabled + +- block: + - name: Configure BGP neighbor address-family + register: result + cisco.nxos.nxos_bgp_neighbor_af: &id001 + asn: 65535 + neighbor: 192.0.2.3 + afi: ipv4 + safi: unicast + additional_paths_receive: enable + additional_paths_send: enable + advertise_map_exist: + - ansible_rm + - my_exist_map + allowas_in: true + default_originate: true + disable_peer_as_check: true + filter_list_in: my_filter_list_in + filter_list_out: my_filter_list_out + max_prefix_limit: 100 + max_prefix_threshold: 50 + max_prefix_warning: "true" + next_hop_self: true + next_hop_third_party: false + prefix_list_in: pfx_in + prefix_list_out: pfx_out + send_community: both + soft_reconfiguration_in: enable + suppress_inactive: true + unsuppress_map: unsup_map + weight: "30" + state: present + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Check idempotence + register: result + cisco.nxos.nxos_bgp_neighbor_af: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Configure BGP neighbor address-family def1 + register: result + cisco.nxos.nxos_bgp_neighbor_af: &id003 + asn: 65535 + neighbor: 192.0.2.3 + afi: ipv4 + safi: unicast + additional_paths_receive: inherit + additional_paths_send: inherit + advertise_map_exist: default + allowas_in: false + default_originate: false + disable_peer_as_check: false + filter_list_in: default + filter_list_out: default + max_prefix_limit: default + max_prefix_threshold: default + max_prefix_warning: false + next_hop_self: false + next_hop_third_party: false + prefix_list_in: default + prefix_list_out: default + send_community: none + soft_reconfiguration_in: inherit + suppress_inactive: false + unsuppress_map: default + weight: default + state: present + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_bgp_neighbor_af: *id003 + + - ansible.builtin.assert: *id004 + + - name: "Setup: remove BGP configuration" + register: result + cisco.nxos.nxos_bgp_neighbor_af: &id005 + asn: 65535 + neighbor: 192.0.2.3 + afi: ipv4 + safi: unicast + state: absent + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_bgp_neighbor_af: *id005 + + - ansible.builtin.assert: *id004 + + - name: Configure BGP neighbor address-family + register: result + cisco.nxos.nxos_bgp_neighbor_af: &id006 + asn: 65535 + neighbor: 192.0.2.3 + afi: ipv4 + safi: unicast + allowas_in_max: "5" + advertise_map_non_exist: + - ansible_rm + - my_non_exist_map + default_originate_route_map: my_route_map + max_prefix_limit: 100 + max_prefix_interval: 30 + max_prefix_threshold: 50 + route_map_in: rm_in + route_map_out: rm_out + state: present + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_bgp_neighbor_af: *id006 + + - ansible.builtin.assert: *id004 + + - name: Configure BGP neighbor address-family def2 + register: result + cisco.nxos.nxos_bgp_neighbor_af: &id007 + asn: 65535 + neighbor: 192.0.2.3 + afi: ipv4 + safi: unicast + allowas_in_max: default + advertise_map_non_exist: default + default_originate_route_map: default + max_prefix_limit: default + max_prefix_interval: default + max_prefix_threshold: default + route_map_in: default + route_map_out: default + state: present + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_bgp_neighbor_af: *id007 + + - ansible.builtin.assert: *id004 + + - name: "Setup: remove BGP configuration" + register: result + cisco.nxos.nxos_bgp_neighbor_af: *id005 + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_bgp_neighbor_af: *id005 + + - ansible.builtin.assert: *id004 + + - name: Configure EBGP + cisco.nxos.nxos_bgp_neighbor: + asn: 65535 + vrf: blue + neighbor: 192.0.2.3 + remote_as: 2 + + - name: Configure BGP neighbor 3 + register: result + cisco.nxos.nxos_bgp_neighbor_af: &id008 + asn: 65535 + vrf: blue + neighbor: 192.0.2.3 + afi: ipv4 + safi: unicast + additional_paths_receive: disable + additional_paths_send: disable + as_override: "true" + send_community: standard + soft_reconfiguration_in: "{{soft_reconfiguration_ina|default(omit)}}" + soo: "3:3" + next_hop_third_party: true + state: present + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_bgp_neighbor_af: *id008 + + - ansible.builtin.assert: *id004 + + - name: Configure BGP neighbor def3 + register: result + cisco.nxos.nxos_bgp_neighbor_af: &id009 + asn: 65535 + vrf: blue + neighbor: 192.0.2.3 + afi: ipv4 + safi: unicast + additional_paths_receive: inherit + additional_paths_send: inherit + as_override: false + send_community: default + soo: default + state: present + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_bgp_neighbor_af: *id009 + + - ansible.builtin.assert: *id004 + + - name: "Setup: remove BGP configuration" + register: result + cisco.nxos.nxos_bgp: &id012 + asn: 65535 + state: absent + + - ansible.builtin.assert: *id002 + + - name: Configure BGP neighbor AF route_reflector_client + cisco.nxos.nxos_bgp_neighbor: + asn: 65535 + neighbor: 192.0.2.2 + remote_as: 65535 + + - name: Configure BGP neighbor 4 + register: result + cisco.nxos.nxos_bgp_neighbor_af: &id010 + asn: 65535 + neighbor: 192.0.2.2 + afi: ipv4 + safi: unicast + route_reflector_client: "true" + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_bgp_neighbor_af: *id010 + + - ansible.builtin.assert: *id004 + + - name: Configure BGP neighbor def4 + register: result + cisco.nxos.nxos_bgp_neighbor_af: &id011 + asn: 65535 + neighbor: 192.0.2.2 + afi: ipv4 + safi: unicast + route_reflector_client: false + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_bgp_neighbor_af: *id011 + + - ansible.builtin.assert: *id004 + always: + - name: Cleanup BGP + ignore_errors: true + cisco.nxos.nxos_bgp: *id012 + + - name: Disable 'feature bgp' + cisco.nxos.nxos_feature: *id013 + + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_bgp_neighbor_af sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/defaults/main.yaml new file mode 100644 index 00000000..9ef5ba51 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "*" +test_items: [] diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/cli/cli_command.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/cli/cli_command.yaml new file mode 100644 index 00000000..27f6ab16 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/cli/cli_command.yaml @@ -0,0 +1,27 @@ +--- +- ansible.builtin.debug: + msg: START cli/cli_command.yaml on connection={{ ansible_connection }} + +- name: Get output for single command + register: result + ansible.netcommon.cli_command: + command: show version + +- ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + +- name: Send invalid command + register: result + ignore_errors: true + ansible.netcommon.cli_command: + command: show foo + +- ansible.builtin.assert: + that: + - result.failed == true + - result.msg is defined + +- ansible.builtin.debug: + msg: END cli/cli_command.yaml on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/cli/contains.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/cli/contains.yaml new file mode 100644 index 00000000..6879ab68 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/cli/contains.yaml @@ -0,0 +1,20 @@ +--- +- ansible.builtin.debug: + msg: START common/contains.yaml on connection={{ ansible_connection }} + +- name: Test contains operator + register: result + cisco.nxos.nxos_command: + commands: + - show version + - show interface mgmt0 | json + wait_for: + - result[0] contains NX-OS + - result[1].TABLE_interface.ROW_interface.interface contains mgmt + +- ansible.builtin.assert: + that: + - result.changed == false + +- ansible.builtin.debug: + msg: END common/contains.yaml on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/cli/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/cli/sanity.yaml new file mode 100644 index 00000000..74c777bd --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/cli/sanity.yaml @@ -0,0 +1,67 @@ +--- +- ansible.builtin.debug: + msg: START cli/sanity.yaml on connection={{ ansible_connection }} + +- name: Disable 'feature bgp' + cisco.nxos.nxos_feature: + feature: bgp + state: disabled + +- block: + - name: Run show running-config BGP - should fail + ignore_errors: true + register: result + cisco.nxos.nxos_command: + commands: + - sh running-config bgp + + - ansible.builtin.assert: &id001 + that: + - result.failed == true + + - name: Enable 'feature bgp' + cisco.nxos.nxos_feature: + feature: bgp + state: enabled + + - name: Configure BGP defaults + register: result + cisco.nxos.nxos_bgp: + asn: 65535 + router_id: 192.0.2.1 + state: present + + - ansible.builtin.assert: + that: + - result.changed == true + + - name: Run show running-config BGP - should pass + register: result + cisco.nxos.nxos_command: + commands: + - sh running-config bgp + + - ansible.builtin.assert: + that: + - result.failed == false + - "'65535' in result.stdout[0]" + + - name: Run an invalid command - should fail + ignore_errors: true + register: result + cisco.nxos.nxos_command: + commands: + - show interface bief + + - ansible.builtin.assert: *id001 + rescue: + - ansible.builtin.debug: + msg: nxos_command sanity test failure detected + always: + - name: Disable 'feature bgp' + cisco.nxos.nxos_feature: + feature: bgp + state: disabled + +- ansible.builtin.debug: + msg: END cli/sanity.yaml on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/common/bad_operator.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/common/bad_operator.yaml new file mode 100644 index 00000000..73be2df7 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/common/bad_operator.yaml @@ -0,0 +1,21 @@ +--- +- ansible.builtin.debug: + msg: START common/bad_operator.yaml on connection={{ ansible_connection }} + +- name: Test bad operator + register: result + ignore_errors: true + cisco.nxos.nxos_command: + commands: + - show version + - show interface mgmt0 | json + wait_for: + - result[1].TABLE_interface.ROW_interface.state foo up + +- ansible.builtin.assert: + that: + - result.failed == true + - result.msg is defined + +- ansible.builtin.debug: + msg: END common/bad_operator.yaml on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/common/equal.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/common/equal.yaml new file mode 100644 index 00000000..a303ebdf --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/common/equal.yaml @@ -0,0 +1,32 @@ +--- +- ansible.builtin.debug: + msg: START common/equal.yaml on connection={{ ansible_connection }} + +- name: Test eq operator + register: result + cisco.nxos.nxos_command: + commands: + - show version + - show interface mgmt0 | json + wait_for: + - result[1].TABLE_interface.ROW_interface.state eq up + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Test == operator + register: result + cisco.nxos.nxos_command: + commands: + - show version + - show interface mgmt0 | json + wait_for: + - result[1].TABLE_interface.ROW_interface.state == up + +- ansible.builtin.assert: + that: + - result.changed == false + +- ansible.builtin.debug: + msg: END common/equal.yaml on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/common/greaterthan.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/common/greaterthan.yaml new file mode 100644 index 00000000..dcdee7b4 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/common/greaterthan.yaml @@ -0,0 +1,32 @@ +--- +- ansible.builtin.debug: + msg: START common/greaterthan.yaml on connection={{ ansible_connection }} + +- name: Test 'gt' operator + register: result + cisco.nxos.nxos_command: + commands: + - show version + - show interface mgmt0 | json + wait_for: + - result[1].TABLE_interface.ROW_interface.eth_ip_mask gt 0 + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Test > operator + register: result + cisco.nxos.nxos_command: + commands: + - show version + - show interface mgmt0 | json + wait_for: + - result[1].TABLE_interface.ROW_interface.eth_ip_mask > 0 + +- ansible.builtin.assert: + that: + - result.changed == false + +- ansible.builtin.debug: + msg: END common/greaterthan.yaml on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/common/greaterthanorequal.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/common/greaterthanorequal.yaml new file mode 100644 index 00000000..6446e6b8 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/common/greaterthanorequal.yaml @@ -0,0 +1,32 @@ +--- +- ansible.builtin.debug: + msg: START common/greaterthanorequal.yaml on connection={{ ansible_connection }} + +- name: Test 'ge' operator + register: result + cisco.nxos.nxos_command: + commands: + - show version + - show interface mgmt0 | json + wait_for: + - result[1].TABLE_interface.ROW_interface.eth_ip_mask ge 0 + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Test >= operator + register: result + cisco.nxos.nxos_command: + commands: + - show version + - show interface mgmt0 | json + wait_for: + - result[1].TABLE_interface.ROW_interface.eth_ip_mask >= 0 + +- ansible.builtin.assert: + that: + - result.changed == false + +- ansible.builtin.debug: + msg: END common/greaterthanorequal.yaml on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/common/invalid.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/common/invalid.yaml new file mode 100644 index 00000000..9fac6a3a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/common/invalid.yaml @@ -0,0 +1,29 @@ +--- +- ansible.builtin.debug: + msg: START common/invalid.yaml on connection={{ ansible_connection }} + +- name: Run invalid command + register: result + ignore_errors: true + cisco.nxos.nxos_command: + commands: + - show foo + +- ansible.builtin.assert: + that: + - result.failed == true + +- name: Run commands that include invalid command + register: result + ignore_errors: true + cisco.nxos.nxos_command: + commands: + - show version + - show foo + +- ansible.builtin.assert: + that: + - result.failed == true + +- ansible.builtin.debug: + msg: END common/invalid.yaml on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/common/lessthan.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/common/lessthan.yaml new file mode 100644 index 00000000..dd01ecc7 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/common/lessthan.yaml @@ -0,0 +1,32 @@ +--- +- ansible.builtin.debug: + msg: START common/lessthan.yaml on connection={{ ansible_connection }} + +- name: Test 'lt' operator + register: result + cisco.nxos.nxos_command: + commands: + - show version + - show interface mgmt0 | json + wait_for: + - result[1].TABLE_interface.ROW_interface.eth_ip_mask lt 33 + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Test < operator + register: result + cisco.nxos.nxos_command: + commands: + - show version + - show interface mgmt0 | json + wait_for: + - result[1].TABLE_interface.ROW_interface.eth_ip_mask lt 33 + +- ansible.builtin.assert: + that: + - result.changed == false + +- ansible.builtin.debug: + msg: END common/lessthan.yaml on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/common/lessthanorequal.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/common/lessthanorequal.yaml new file mode 100644 index 00000000..04748f52 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/common/lessthanorequal.yaml @@ -0,0 +1,32 @@ +--- +- ansible.builtin.debug: + msg: START common/lessthanorequal.yaml on connection={{ ansible_connection }} + +- name: Test 'le' operator + register: result + cisco.nxos.nxos_command: + commands: + - show version + - show interface mgmt0 | json + wait_for: + - result[1].TABLE_interface.ROW_interface.eth_ip_mask le 32 + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Test <= operator + register: result + cisco.nxos.nxos_command: + commands: + - show version + - show interface mgmt0 | json + wait_for: + - result[1].TABLE_interface.ROW_interface.eth_ip_mask <= 32 + +- ansible.builtin.assert: + that: + - result.changed == false + +- ansible.builtin.debug: + msg: END common/lessthanorequal.yaml on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/common/not_comparison_operator.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/common/not_comparison_operator.yaml new file mode 100644 index 00000000..92e9e637 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/common/not_comparison_operator.yaml @@ -0,0 +1,20 @@ +--- +- ansible.builtin.debug: + msg: START common/not_comparison_operator.yaml on connection={{ ansible_connection }} + +- name: Test 'not' keyword in wait_for + register: result + cisco.nxos.nxos_command: + commands: + - show version + wait_for: + - result[0] not contains QWERTYQWERTYQWERTY + - result[0] == not QWERTYQWERTYQWERTY + - result[0] matches not QWERTYQWERTYQWERTY + +- ansible.builtin.assert: + that: + - result.changed == false + +- ansible.builtin.debug: + msg: END common/not_comparison_operator.yaml on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/common/notequal.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/common/notequal.yaml new file mode 100644 index 00000000..c2fe3957 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/common/notequal.yaml @@ -0,0 +1,34 @@ +--- +- ansible.builtin.debug: + msg: START common/notequal.yaml on connection={{ ansible_connection }} + +- name: Test 'neq' operator + register: result + cisco.nxos.nxos_command: + commands: + - show version + - show interface mgmt0 | json + wait_for: + - result[1].TABLE_interface.ROW_interface.state neq down + +- ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + +- name: Test != operator + register: result + cisco.nxos.nxos_command: + commands: + - show version + - show interface mgmt0 | json + wait_for: + - result[1].TABLE_interface.ROW_interface.state != down + +- ansible.builtin.assert: + that: + - result.changed == false + - result.stdout is defined + +- ansible.builtin.debug: + msg: END common/notequal.yaml on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/common/output.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/common/output.yaml new file mode 100644 index 00000000..117b06ed --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/common/output.yaml @@ -0,0 +1,27 @@ +--- +- ansible.builtin.debug: + msg: START common/output.yaml on connection={{ ansible_connection }} + +- name: Get output for single command + register: result + cisco.nxos.nxos_command: + commands: + - show version + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Get output for multiple commands + register: result + cisco.nxos.nxos_command: + commands: + - show version + - show interface + +- ansible.builtin.assert: + that: + - result.changed == false + +- ansible.builtin.debug: + msg: END common/output.yaml on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/common/timeout.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/common/timeout.yaml new file mode 100644 index 00000000..08f184bd --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/common/timeout.yaml @@ -0,0 +1,20 @@ +--- +- ansible.builtin.debug: + msg: START common/timeout.yaml on connection={{ ansible_connection }} + +- name: Test bad condition + register: result + ignore_errors: true + cisco.nxos.nxos_command: + commands: + - show version + wait_for: + - result[0] contains bad_value_string + +- ansible.builtin.assert: + that: + - result.failed == true + - result.msg is defined + +- ansible.builtin.debug: + msg: END common/timeout.yaml on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/nxapi/contains.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/nxapi/contains.yaml new file mode 100644 index 00000000..e2fa700e --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/nxapi/contains.yaml @@ -0,0 +1,23 @@ +--- +- ansible.builtin.debug: + msg: START common/contains.yaml on connection={{ ansible_connection }} + +- name: Test contains operator + register: result + cisco.nxos.nxos_command: + commands: + - command: show version + output: text + + - command: show interface mgmt0 + output: json + wait_for: + - result[0] contains NX-OS + - result[1].TABLE_interface.ROW_interface.interface contains mgmt + +- ansible.builtin.assert: + that: + - result.changed == false + +- ansible.builtin.debug: + msg: END common/contains.yaml on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/nxapi/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/nxapi/sanity.yaml new file mode 100644 index 00000000..e9f2f162 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_command/tests/nxapi/sanity.yaml @@ -0,0 +1,67 @@ +--- +- ansible.builtin.debug: + msg: START nxapi/sanity.yaml on connection={{ ansible_connection }} + +- name: Disable 'feature bgp' + cisco.nxos.nxos_feature: + feature: bgp + state: disabled + +- block: + - name: Run show running-config BGP - should fail + ignore_errors: true + register: result + cisco.nxos.nxos_command: + commands: + - sh running-config bgp + + - ansible.builtin.assert: &id001 + that: + - result.failed == true + + - name: Enable 'feature bgp' + cisco.nxos.nxos_feature: + feature: bgp + state: enabled + + - name: Configure BGP defaults + register: result + cisco.nxos.nxos_bgp: + asn: 65535 + router_id: 192.0.2.1 + state: present + + - ansible.builtin.assert: + that: + - result.changed == true + + - name: Run show running-config BGP - should pass + register: result + cisco.nxos.nxos_command: + commands: + - sh running-config bgp + + - ansible.builtin.assert: + that: + - result.failed == false + - "'65535' in result.stdout[0]|to_json" + + - name: Run an invalid command - should fail + ignore_errors: true + register: result + cisco.nxos.nxos_command: + commands: + - show interface bief + + - ansible.builtin.assert: *id001 + rescue: + - ansible.builtin.debug: + msg: nxos_command sanity test failure detected + always: + - name: Disable 'feature bgp' + cisco.nxos.nxos_feature: + feature: bgp + state: disabled + +- ansible.builtin.debug: + msg: END nxapi/sanity.yaml on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/defaults/main.yaml new file mode 100644 index 00000000..9ef5ba51 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "*" +test_items: [] diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tasks/cli_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tasks/cli_config.yaml new file mode 100644 index 00000000..4c960185 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tasks/cli_config.yaml @@ -0,0 +1,19 @@ +--- +- name: Collect all cli_config test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli_config" + patterns: "{{ testcase }}.yaml" + register: test_cases + delegate_to: localhost + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tasks/main.yaml new file mode 100644 index 00000000..641205bf --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tasks/main.yaml @@ -0,0 +1,27 @@ +--- +- name: Run the CLI and NX-API tests + block: + - name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + + - name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi + + - name: Run cli_config tests + ansible.builtin.include_tasks: cli_config.yaml + tags: + - cli_config + + - name: Run redirection tests + ansible.builtin.include_tasks: redirection.yaml + when: ansible_version.full is version('2.10.0', '>=') + always: + - name: Change hostname back to {{ inventory_hostname_short }} + cisco.nxos.nxos_config: + lines: + - hostname {{ inventory_hostname_short }} + match: none diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tasks/redirection.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tasks/redirection.yaml new file mode 100644 index 00000000..0ef757ae --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tasks/redirection.yaml @@ -0,0 +1,19 @@ +--- +- name: Collect all redirection CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/redirection/cli" + patterns: "{{ testcase }}.yaml" + register: shortname_test_cases + delegate_to: localhost + +- name: Set test_items for redirection + ansible.builtin.set_fact: + test_items: "{{ shortname_test_cases.files | map(attribute='path') | list }}" + +- name: Run test case (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/basic/base_running_config b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/basic/base_running_config new file mode 100644 index 00000000..563371d9 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/basic/base_running_config @@ -0,0 +1,10 @@ +version 7.0(3)I6(1) +hostname an-nxos9k-02.ansible.com +vdc an-nxos9k-02 id 1 + limit-resource vlan minimum 16 maximum 4094 + limit-resource vrf minimum 2 maximum 4096 + limit-resource port-channel minimum 0 maximum 511 + limit-resource u4route-mem minimum 96 maximum 96 + limit-resource u6route-mem minimum 24 maximum 24 + limit-resource m4route-mem minimum 58 maximum 58 + limit-resource m6route-mem minimum 8 maximum 8 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/basic/config.j2 b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/basic/config.j2 new file mode 100644 index 00000000..a286694a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/basic/config.j2 @@ -0,0 +1,3 @@ +interface loopback1 + description this is a test + shutdown diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/basic/configblock.j2 b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/basic/configblock.j2 new file mode 100644 index 00000000..ec03c24a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/basic/configblock.j2 @@ -0,0 +1,5 @@ +ip access-list test + 10 permit ip 192.0.2.1/32 any log + 20 permit ip 192.0.2.2/32 any log + 30 permit ip 192.0.2.3/32 any log + 40 permit ip 192.0.2.4/32 any log diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/basic/configexact1.j2 b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/basic/configexact1.j2 new file mode 100644 index 00000000..ec03c24a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/basic/configexact1.j2 @@ -0,0 +1,5 @@ +ip access-list test + 10 permit ip 192.0.2.1/32 any log + 20 permit ip 192.0.2.2/32 any log + 30 permit ip 192.0.2.3/32 any log + 40 permit ip 192.0.2.4/32 any log diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/basic/configexact2.j2 b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/basic/configexact2.j2 new file mode 100644 index 00000000..3fc6800d --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/basic/configexact2.j2 @@ -0,0 +1,6 @@ +ip access-list test + 10 permit ip 192.0.2.1/32 any log + 20 permit ip 192.0.2.2/32 any log + 30 permit ip 192.0.2.3/32 any log + 40 permit ip 192.0.2.4/32 any log + 50 permit ip 192.0.2.5/32 any log diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/basic/configstrict1.j2 b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/basic/configstrict1.j2 new file mode 100644 index 00000000..1e7e6f44 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/basic/configstrict1.j2 @@ -0,0 +1,6 @@ +no ip access-list test +ip access-list test + 10 permit ip 192.0.2.1/32 any log + 20 permit ip 192.0.2.2/32 any log + 30 permit ip 192.0.2.3/32 any log + 40 permit ip 192.0.2.4/32 any log diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/basic/intended_running_config b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/basic/intended_running_config new file mode 100644 index 00000000..ab96584b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/basic/intended_running_config @@ -0,0 +1,10 @@ +version 7.0(3)I6(1) +hostname an-nxos9k-01.ansible.com +vdc an-nxos9k-01 id 1 + limit-resource vlan minimum 16 maximum 4094 + limit-resource vrf minimum 2 maximum 4096 + limit-resource port-channel minimum 0 maximum 511 + limit-resource u4route-mem minimum 96 maximum 96 + limit-resource u6route-mem minimum 24 maximum 24 + limit-resource m4route-mem minimum 58 maximum 58 + limit-resource m6route-mem minimum 8 maximum 8 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/basic/setupexact.j2 b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/basic/setupexact.j2 new file mode 100644 index 00000000..815e003c --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/basic/setupexact.j2 @@ -0,0 +1,7 @@ +no ip access-list test +ip access-list test + 10 permit ip 192.0.2.1/32 any log + 20 permit ip 192.0.2.2/32 any log + 30 permit ip 192.0.2.3/32 any log + 40 permit ip 192.0.2.4/32 any log + 50 permit ip 192.0.2.5/32 any log diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/basic/setupstrict.j2 b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/basic/setupstrict.j2 new file mode 100644 index 00000000..815e003c --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/basic/setupstrict.j2 @@ -0,0 +1,7 @@ +no ip access-list test +ip access-list test + 10 permit ip 192.0.2.1/32 any log + 20 permit ip 192.0.2.2/32 any log + 30 permit ip 192.0.2.3/32 any log + 40 permit ip 192.0.2.4/32 any log + 50 permit ip 192.0.2.5/32 any log diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/config.js b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/config.js new file mode 100644 index 00000000..4655bcff --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/config.js @@ -0,0 +1,3 @@ +interface Ethernet2/5 + description test description from ansible + shutdown diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/defaults/config.j2 b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/defaults/config.j2 new file mode 100644 index 00000000..2a5ffad5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/defaults/config.j2 @@ -0,0 +1,3 @@ +interface Ethernet2/5 + description this is a test + no shutdown diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/defaults/test.j2 b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/defaults/test.j2 new file mode 100644 index 00000000..0e26ff50 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/templates/defaults/test.j2 @@ -0,0 +1,3 @@ +interface Ethernet2/5 + description this is a test + shutdown diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli/diff.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli/diff.yaml new file mode 100644 index 00000000..e8999c84 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli/diff.yaml @@ -0,0 +1,35 @@ +--- +- ansible.builtin.debug: + msg: START cli/diff.yaml on connection={{ ansible_connection }} + +- name: Setup hostname + cisco.nxos.nxos_config: + lines: hostname switch + +- name: Nxos_config diff against retrieved configuration + diff: true + register: result + cisco.nxos.nxos_config: + diff_against: intended + intended_config: "{{ lookup('file', '{{ role_path }}/templates/basic/intended_running_config') }}" + +- ansible.builtin.assert: + that: + - "'hostname an-nxos9k-01.ansible.com' in result['diff']['after']" + - "'hostname switch' in result['diff']['before']" + +- name: Nxos_config diff against provided running_config + diff: true + register: result + cisco.nxos.nxos_config: + diff_against: intended + intended_config: "{{ lookup('file', '{{ role_path }}/templates/basic/intended_running_config') }}" + running_config: "{{ lookup('file', '{{ role_path }}/templates/basic/base_running_config') }}" + +- ansible.builtin.assert: + that: + - "'hostname an-nxos9k-01.ansible.com' in result['diff']['after']" + - "'hostname an-nxos9k-02.ansible.com' in result['diff']['before']" + +- ansible.builtin.debug: + msg: END cli/diff.yaml on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli/multilevel.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli/multilevel.yaml new file mode 100644 index 00000000..277f10d5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli/multilevel.yaml @@ -0,0 +1,54 @@ +--- +- ansible.builtin.debug: + msg: START cli/mulitlevel.yaml + +- name: Get configuration + register: config + cisco.nxos.nxos_command: + commands: show running-config + +- name: Enable 'feature bgp' + when: "'feature bgp' not in config.stdout[0]" + cisco.nxos.nxos_config: + lines: feature bgp + +- name: Remove BGP + when: "'router bgp 1' in config.stdout[0]" + cisco.nxos.nxos_config: + lines: no router bgp 1 + +- name: Configure multi level command + register: result + cisco.nxos.nxos_config: + lines: maximum-paths 14 + parents: + - router bgp 1 + - address-family ipv4 unicast + +- ansible.builtin.assert: + that: + - result.changed == true + - "'router bgp 1' in result.updates" + - "'address-family ipv4 unicast' in result.updates" + - "'maximum-paths 14' in result.updates" + +- name: Check multi level command + register: result + cisco.nxos.nxos_config: + lines: maximum-paths 14 + parents: + - router bgp 1 + - address-family ipv4 unicast + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Teardown + cisco.nxos.nxos_config: + lines: + - no feature bgp + match: none + +- ansible.builtin.debug: + msg: END cli/mulitlevel.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli/sublevel.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli/sublevel.yaml new file mode 100644 index 00000000..b15a2dda --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli/sublevel.yaml @@ -0,0 +1,38 @@ +--- +- ansible.builtin.debug: + msg: START cli/sublevel.yaml + +- name: Setup + cisco.nxos.nxos_config: + lines: no ip access-list test + match: none + +- name: Configure sub level command + register: result + cisco.nxos.nxos_config: + lines: 10 permit ip any any log + parents: ip access-list test + +- ansible.builtin.assert: + that: + - result.changed == true + - "'ip access-list test' in result.updates" + - "'10 permit ip any any log' in result.updates" + +- name: Configure sub level command idempotent check + register: result + cisco.nxos.nxos_config: + lines: 10 permit ip any any log + parents: ip access-list test + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Teardown + cisco.nxos.nxos_config: + lines: no ip access-list test + match: none + +- ansible.builtin.debug: + msg: END cli/sublevel.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli/sublevel_exact.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli/sublevel_exact.yaml new file mode 100644 index 00000000..0b48c6d8 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli/sublevel_exact.yaml @@ -0,0 +1,60 @@ +--- +- ansible.builtin.debug: + msg: START cli/sublevel_exact.yaml + +- name: Setup + cisco.nxos.nxos_config: + commands: + - 10 permit ip 192.0.2.1/32 any log + - 20 permit ip 192.0.2.2/32 any log + - 30 permit ip 192.0.2.3/32 any log + - 40 permit ip 192.0.2.4/32 any log + - 50 permit ip 192.0.2.5/32 any log + parents: ip access-list test + before: no ip access-list test + match: none + +- name: Configure sub level command using exact match + register: result + cisco.nxos.nxos_config: + commands: + - 10 permit ip 192.0.2.1/32 any log + - 20 permit ip 192.0.2.2/32 any log + - 30 permit ip 192.0.2.3/32 any log + - 40 permit ip 192.0.2.4/32 any log + parents: ip access-list test + match: exact + +- ansible.builtin.assert: + that: + - result.changed == true + - "'ip access-list test' in result.updates" + - "'10 permit ip 192.0.2.1/32 any log' in result.updates" + - "'20 permit ip 192.0.2.2/32 any log' in result.updates" + - "'30 permit ip 192.0.2.3/32 any log' in result.updates" + - "'40 permit ip 192.0.2.4/32 any log' in result.updates" + - "'50 permit ip 192.0.2.5/32 any log' not in result.updates" + +- name: Check sub level command using exact match + register: result + cisco.nxos.nxos_config: + lines: + - 10 permit ip 192.0.2.1/32 any log + - 20 permit ip 192.0.2.2/32 any log + - 30 permit ip 192.0.2.3/32 any log + - 40 permit ip 192.0.2.4/32 any log + - 50 permit ip 192.0.2.5/32 any log + parents: ip access-list test + match: exact + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Teardown + cisco.nxos.nxos_config: + lines: no ip access-list test + match: none + +- ansible.builtin.debug: + msg: END cli/sublevel_exact.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli/sublevel_strict.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli/sublevel_strict.yaml new file mode 100644 index 00000000..10df9a99 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli/sublevel_strict.yaml @@ -0,0 +1,61 @@ +--- +- ansible.builtin.debug: + msg: START cli/sublevel_strict.yaml + +- name: Setup + cisco.nxos.nxos_config: + commands: + - 10 permit ip 192.0.2.1/32 any log + - 20 permit ip 192.0.2.2/32 any log + - 30 permit ip 192.0.2.3/32 any log + - 40 permit ip 192.0.2.4/32 any log + - 50 permit ip 192.0.2.5/32 any log + parents: ip access-list test + before: no ip access-list test + match: none + +- name: Configure sub level command using strict match + register: result + cisco.nxos.nxos_config: + lines: + - 10 permit ip 192.0.2.1/32 any log + - 30 permit ip 192.0.2.3/32 any log + - 20 permit ip 192.0.2.2/32 any log + - 40 permit ip 192.0.2.4/32 any log + parents: ip access-list test + before: no ip access-list test + match: strict + replace: block + +- ansible.builtin.assert: + that: + - result.changed == true + - "'ip access-list test' in result.updates" + - "'10 permit ip 192.0.2.1/32 any log' in result.updates" + - "'20 permit ip 192.0.2.2/32 any log' in result.updates" + - "'30 permit ip 192.0.2.3/32 any log' in result.updates" + - "'40 permit ip 192.0.2.4/32 any log' in result.updates" + - "'50 permit ip 192.0.2.5/32 any log' not in result.updates" + +- name: Check sub level command using strict match + register: result + cisco.nxos.nxos_config: + lines: + - 10 permit ip 192.0.2.1/32 any log + - 20 permit ip 192.0.2.2/32 any log + - 30 permit ip 192.0.2.3/32 any log + - 40 permit ip 192.0.2.4/32 any log + parents: ip access-list test + match: strict + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Teardown + cisco.nxos.nxos_config: + commands: no ip access-list test + match: none + +- ansible.builtin.debug: + msg: END cli/sublevel_strict.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli/toplevel_after.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli/toplevel_after.yaml new file mode 100644 index 00000000..7521f609 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli/toplevel_after.yaml @@ -0,0 +1,42 @@ +--- +- ansible.builtin.debug: + msg: START cli/toplevel_after.yaml + +- name: Setup + cisco.nxos.nxos_config: + lines: + - snmp-server contact ansible + - hostname switch + match: none + +- name: Configure top level command with before + register: result + cisco.nxos.nxos_config: + lines: hostname foo + after: snmp-server contact bar + +- ansible.builtin.assert: + that: + - result.changed == true + - "'hostname foo' in result.updates" + - "'snmp-server contact bar' in result.updates" + +- name: Configure top level command with before idempotent check + register: result + cisco.nxos.nxos_config: + lines: hostname foo + after: snmp-server contact foo + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Teardown + cisco.nxos.nxos_config: + lines: + - no snmp-server contact + - hostname switch + match: none + +- ansible.builtin.debug: + msg: END cli/toplevel_after.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli/toplevel_before.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli/toplevel_before.yaml new file mode 100644 index 00000000..4e8c5fbc --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli/toplevel_before.yaml @@ -0,0 +1,42 @@ +--- +- ansible.builtin.debug: + msg: START cli/toplevel_before.yaml + +- name: Setup + cisco.nxos.nxos_config: + lines: + - snmp-server contact ansible + - hostname switch + match: none + +- name: Configure top level command with before + register: result + cisco.nxos.nxos_config: + lines: hostname foo + before: snmp-server contact bar + +- ansible.builtin.assert: + that: + - result.changed == true + - "'hostname foo' in result.updates" + - "'snmp-server contact bar' in result.updates" + +- name: Configure top level command with before idempotent check + register: result + cisco.nxos.nxos_config: + lines: hostname foo + before: snmp-server contact foo + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Teardown + cisco.nxos.nxos_config: + lines: + - no snmp-server contact + - hostname switch + match: none + +- ansible.builtin.debug: + msg: END cli/toplevel_before.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli_config/cli_backup.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli_config/cli_backup.yaml new file mode 100644 index 00000000..8f21457e --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli_config/cli_backup.yaml @@ -0,0 +1,125 @@ +--- +- ansible.builtin.debug: + msg: END cli_config/backup.yaml on connection={{ ansible_connection }} + +- name: Set a fact for 'can_become' + ansible.builtin.set_fact: + can_become: true + +- name: Set a fact for 'can_become' + ansible.builtin.set_fact: + can_become: false + when: platform is search('N9K') and (major_version is version('10.', 'ge')) + +- name: Delete configurable backup file path + ansible.builtin.file: + path: "{{ item }}" + state: absent + with_items: + - "{{ role_path }}/backup_test_dir/" + - "{{ role_path }}/backup/backup.cfg" + +- name: Collect any backup files + ansible.builtin.find: + paths: "{{ role_path }}/backup" + pattern: "{{ inventory_hostname_short }}_config*" + register: backup_files + connection: local + +- name: Delete backup files + ansible.builtin.file: + path: "{{ item.path }}" + state: absent + with_items: "{{backup_files.files|default([])}}" + +- name: Take configuration backup + become: "{{ can_become }}" + register: result + ansible.netcommon.cli_config: + backup: true + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: Collect any backup files + ansible.builtin.find: + paths: "{{ role_path }}/backup" + pattern: "{{ inventory_hostname_short }}_config*" + register: backup_files + connection: local + +- ansible.builtin.assert: + that: + - backup_files.files is defined + +- name: Take configuration backup in custom filename and directory path + become: "{{ can_become }}" + register: result + ansible.netcommon.cli_config: + backup: true + backup_options: + filename: backup.cfg + dir_path: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}" + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: Check if the backup file-1 exist + ansible.builtin.find: + paths: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}/backup.cfg" + register: backup_file + connection: local + +- ansible.builtin.assert: + that: + - backup_file.files is defined + +- name: Take configuration backup in custom filename + become: "{{ can_become }}" + register: result + ansible.netcommon.cli_config: + backup: true + backup_options: + filename: backup.cfg + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: Check if the backup file-2 exist + ansible.builtin.find: + paths: "{{ role_path }}/backup/backup.cfg" + register: backup_file + connection: local + +- ansible.builtin.assert: + that: + - backup_file.files is defined + +- name: Take configuration backup in custom path and default filename + become: "{{ can_become }}" + register: result + ansible.netcommon.cli_config: + backup: true + backup_options: + dir_path: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}" + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: Check if the backup file-3 exist + ansible.builtin.find: + paths: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}" + pattern: "{{ inventory_hostname_short }}_config*" + register: backup_file + connection: local + +- ansible.builtin.assert: + that: + - backup_file.files is defined + +- ansible.builtin.debug: + msg: END cli_config/backup.yaml on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli_config/cli_basic.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli_config/cli_basic.yaml new file mode 100644 index 00000000..a2492af2 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli_config/cli_basic.yaml @@ -0,0 +1,44 @@ +--- +- ansible.builtin.debug: + msg: START cli_config/cli_basic.yaml on connection={{ ansible_connection }} + +- name: Setup + ansible.netcommon.cli_config: &id002 + config: "interface loopback1\nno description\nno shutdown\n" + diff_match: none + +- name: Configure device with configuration + register: result + ansible.netcommon.cli_config: &id001 + config: "{{ lookup('template', 'basic/config.j2') }}" + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: Idempotence + register: result + ansible.netcommon.cli_config: *id001 + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Remove configuration + ansible.netcommon.cli_config: *id002 + +- name: Configure device with configuration + register: result + ansible.netcommon.cli_config: + config: "{{ lookup('template', 'basic/config.j2') }}" + defaults: true + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: Teardown + ansible.netcommon.cli_config: *id002 + +- ansible.builtin.debug: + msg: END cli_config/cli_basic.yaml on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli_config/cli_block_replace.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli_config/cli_block_replace.yaml new file mode 100644 index 00000000..4f96600b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli_config/cli_block_replace.yaml @@ -0,0 +1,32 @@ +--- +- ansible.builtin.debug: + msg: START cli_config/cli_block_replace.yaml on connection={{ ansible_connection }} + +- name: Setup - remove configuration + ansible.netcommon.cli_config: &id002 + config: no ip access-list test + diff_match: none + +- name: Block replace + register: result + ansible.netcommon.cli_config: &id001 + config: "{{ lookup('template', 'basic/configblock.j2') }}" + diff_replace: block + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: Block replace (idempotence) + register: result + ansible.netcommon.cli_config: *id001 + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Teardown + ansible.netcommon.cli_config: *id002 + +- ansible.builtin.debug: + msg: END cli_config/cli_block_replace.yaml on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli_config/cli_exact_match.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli_config/cli_exact_match.yaml new file mode 100644 index 00000000..5b3d028d --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli_config/cli_exact_match.yaml @@ -0,0 +1,35 @@ +--- +- ansible.builtin.debug: + msg: START cli_config/cli_exact_match.yaml on connection={{ ansible_connection }} + +- name: Setup - remove configuration + ansible.netcommon.cli_config: + config: "{{ lookup('template', 'basic/setupexact.j2') }}" + diff_match: none + +- name: Configure using exact match + register: result + ansible.netcommon.cli_config: + config: "{{ lookup('template', 'basic/configexact1.j2') }}" + diff_match: exact + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: Check using exact match + register: result + ansible.netcommon.cli_config: + config: "{{ lookup('template', 'basic/configexact2.j2') }}" + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Teardown + ansible.netcommon.cli_config: + config: no ip access-list test + diff_match: none + +- ansible.builtin.debug: + msg: END cli_config/cli_exact_match.yaml on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli_config/cli_strict_match.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli_config/cli_strict_match.yaml new file mode 100644 index 00000000..f8285084 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/cli_config/cli_strict_match.yaml @@ -0,0 +1,27 @@ +--- +- ansible.builtin.debug: + msg: START cli_config/cli_strict_match.yaml on connection={{ ansible_connection }} + +- name: Setup - remove configuration + ansible.netcommon.cli_config: + config: "{{ lookup('template', 'basic/setupstrict.j2') }}" + diff_match: none + +- name: Configure using strict match + register: result + ansible.netcommon.cli_config: + config: "{{ lookup('template', 'basic/configstrict1.j2') }}" + diff_match: strict + diff_replace: block + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: Teardown + ansible.netcommon.cli_config: + config: no ip access-list test + diff_match: none + +- ansible.builtin.debug: + msg: END cli_config/cli_strict_match.yaml on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/common/backup.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/common/backup.yaml new file mode 100644 index 00000000..e1aecb6b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/common/backup.yaml @@ -0,0 +1,129 @@ +--- +- ansible.builtin.debug: + msg: START common/backup.yaml on connection={{ ansible_connection }} + +- name: Set a fact for 'intname' + ansible.builtin.set_fact: + intname: "{{ nxos_int1 }}" + +- name: Setup + cisco.nxos.nxos_config: + commands: + - no description + - no shutdown + parents: + - interface {{ intname }} + match: none + +- name: Collect any backup files + ansible.builtin.find: &id001 + paths: "{{ role_path }}/backup" + pattern: "{{ inventory_hostname_short }}_config*" + connection: local + register: backup_files + +- name: Delete backup files + ansible.builtin.file: + path: "{{ item.path }}" + state: absent + with_items: "{{backup_files.files|default([])}}" + +- name: Configure device with configuration + register: result + cisco.nxos.nxos_config: + commands: + - description this is a test + - shutdown + parents: + - interface {{ intname }} + backup: true + +- ansible.builtin.assert: + that: + - result.changed == true + - result.updates is defined + +- name: Collect any backup files + ansible.builtin.find: *id001 + connection: local + register: backup_files + +- ansible.builtin.assert: + that: + - backup_files.files is defined + +- name: Delete configurable backup file path + ansible.builtin.file: + path: "{{ item }}" + state: absent + with_items: + - "{{ role_path }}/backup_test_dir/" + - "{{ role_path }}/backup/backup.cfg" + +- name: Take configuration backup in custom filename and directory path + register: result + cisco.nxos.nxos_config: + backup: true + backup_options: + filename: backup.cfg + dir_path: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}" + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: Check if the backup file-1 exist + ansible.builtin.find: + paths: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}/backup.cfg" + register: backup_file + connection: local + +- ansible.builtin.assert: + that: + - backup_file.files is defined + +- name: Take configuration backup in custom filename + register: result + cisco.nxos.nxos_config: + backup: true + backup_options: + filename: backup.cfg + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: Check if the backup file-2 exist + ansible.builtin.find: + paths: "{{ role_path }}/backup/backup.cfg" + register: backup_file + connection: local + +- ansible.builtin.assert: + that: + - backup_file.files is defined + +- name: Take configuration backup in custom path and default filename + register: result + cisco.nxos.nxos_config: + backup: true + backup_options: + dir_path: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}" + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: Check if the backup file-3 exist + ansible.builtin.find: + paths: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}" + pattern: "{{ inventory_hostname_short }}_config*" + register: backup_file + connection: local + +- ansible.builtin.assert: + that: + - backup_file.files is defined + +- ansible.builtin.debug: + msg: END common/backup.yaml on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/common/defaults.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/common/defaults.yaml new file mode 100644 index 00000000..dd8a8e1a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/common/defaults.yaml @@ -0,0 +1,55 @@ +--- +- ansible.builtin.debug: + msg: START common/defaults.yaml on connection={{ ansible_connection }} + +- name: Set a fact for 'intname' + ansible.builtin.set_fact: + intname: "{{ nxos_int1 }}" + +- name: Setup + cisco.nxos.nxos_config: + commands: + - no description + - shutdown + parents: + - interface {{ intname }} + match: none + +- name: Configure device with defaults included + register: result + cisco.nxos.nxos_config: + commands: + - description this is a test + - no shutdown + parents: + - interface {{ intname }} + defaults: true + +- ansible.builtin.debug: + var: result + +- ansible.builtin.assert: + that: + - result.changed == true + - result.updates is defined + +- name: Check device with defaults included + register: result + cisco.nxos.nxos_config: + commands: + - description this is a test + - no shutdown + parents: + - interface {{ intname }} + defaults: true + +- ansible.builtin.debug: + var: result + +- ansible.builtin.assert: + that: + - result.changed == false + - result.updates is not defined + +- ansible.builtin.debug: + msg: END common/defaults.yaml on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/common/sanity.yaml new file mode 100644 index 00000000..e3d788b1 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/common/sanity.yaml @@ -0,0 +1,74 @@ +--- +- ansible.builtin.debug: + msg: START common/sanity.yaml on connection={{ ansible_connection }} + +- name: Setup + cisco.nxos.nxos_config: + lines: ip access-list test + match: none + +- name: Nxos_config sanity test + cisco.nxos.nxos_config: + lines: + - 10 permit ip 192.0.2.1/32 any log + - 20 permit ip 192.0.2.2/32 any log + - 30 permit ip 192.0.2.3/32 any log + - 40 permit ip 192.0.2.4/32 any log + - 50 permit ip 192.0.2.5/32 any log + parents: ip access-list test + before: no ip access-list test + match: exact + +- name: Nxos_config sanity test - replace block + cisco.nxos.nxos_config: + lines: + - 10 permit ip 192.0.2.1/32 any log + - 20 permit ip 192.0.2.2/32 any log + - 30 permit ip 192.0.2.3/32 any log + - 40 permit ip 192.0.2.4/32 any log + parents: ip access-list test + before: no ip access-list test + replace: block + +- name: Teardown + cisco.nxos.nxos_config: + lines: no ip access-list test + match: none + +- ansible.builtin.debug: + msg: Verify https://github.com/ansible/ansible/issues/50635 + +- name: Put interface into default state + cisco.nxos.nxos_config: + lines: + - default interface {{ nxos_int1 }} + +- name: Make interface a switchport + cisco.nxos.nxos_config: + lines: + - switchport + parents: interface {{ nxos_int1 }} + +- name: Configure edge trunk type + register: result + cisco.nxos.nxos_config: &id001 + lines: + - description foo + - switchport access vlan 3333 + - spanning-tree port type edge + parents: interface {{ nxos_int1 }} + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: Idempotence check + register: result + cisco.nxos.nxos_config: *id001 + +- ansible.builtin.assert: + that: + - result.changed == false + +- ansible.builtin.debug: + msg: END common/sanity.yaml on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/common/save.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/common/save.yaml new file mode 100644 index 00000000..9300247a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/common/save.yaml @@ -0,0 +1,37 @@ +--- +- ansible.builtin.debug: + msg: START common/save.yaml on connection={{ ansible_connection }} + +- name: Set a fact for 'intname' + ansible.builtin.set_fact: + intname: "{{ nxos_int1 }}" + +- name: Setup + cisco.nxos.nxos_config: + commands: + - no description + - no shutdown + parents: + - interface {{ intname }} + match: none + +- name: Save configuration + register: result + cisco.nxos.nxos_config: + save_when: always + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: Save should always run + register: result + cisco.nxos.nxos_config: + save_when: always + +- ansible.builtin.assert: + that: + - result.changed == true + +- ansible.builtin.debug: + msg: END common/save.yaml on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/common/src_basic.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/common/src_basic.yaml new file mode 100644 index 00000000..176b679c --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/common/src_basic.yaml @@ -0,0 +1,40 @@ +--- +- ansible.builtin.debug: + msg: START common/src_basic.yaml on connection={{ ansible_connection }} + +- name: Set a fact for 'intname' + ansible.builtin.set_fact: + intname: loopback1 + +- name: Setup + cisco.nxos.nxos_config: + commands: + - no description + - no shutdown + parents: + - interface {{ intname }} + match: none + +- name: Configure device with configuration + register: result + cisco.nxos.nxos_config: + src: basic/config.j2 + defaults: true + +- ansible.builtin.assert: + that: + - result.changed == true + - result.updates is defined + +- name: Check device with configuration + register: result + cisco.nxos.nxos_config: + src: basic/config.j2 + +- ansible.builtin.assert: + that: + - result.changed == false + - result.updates is not defined + +- ansible.builtin.debug: + msg: END common/src_basic.yaml on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/common/src_invalid.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/common/src_invalid.yaml new file mode 100644 index 00000000..22a4fc9f --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/common/src_invalid.yaml @@ -0,0 +1,17 @@ +--- +- ansible.builtin.debug: + msg: START common/src_invalid.yaml on connection={{ ansible_connection }} + +- name: Configure with invalid src + register: result + ignore_errors: true + cisco.nxos.nxos_config: + src: basic/foobar.j2 + +- ansible.builtin.assert: + that: + - result.failed == true + - result.msg == 'path specified in src not found' + +- ansible.builtin.debug: + msg: END common/src_invalid.yaml on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/common/src_match_none.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/common/src_match_none.yaml new file mode 100644 index 00000000..a9b94ac5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/common/src_match_none.yaml @@ -0,0 +1,50 @@ +--- +- ansible.builtin.debug: + msg: START common/src_match_none.yaml on connection={{ ansible_connection }} + +- name: Set a fact for 'intname' + ansible.builtin.set_fact: + intname: "{{ nxos_int1 }}" + +- name: Setup + cisco.nxos.nxos_config: + commands: + - no description + - no shutdown + parents: + - interface {{ intname }} + match: none + +- name: Configure device with configuration + register: result + cisco.nxos.nxos_config: + commands: + - description this is a test + - shutdown + parents: + - interface {{ intname }} + match: none + defaults: true + +- ansible.builtin.assert: + that: + - result.changed == true + - result.updates is defined + +- name: Check device with configuration + register: result + cisco.nxos.nxos_config: + commands: + - description this is a test + - shutdown + parents: + - interface {{ intname }} + defaults: true + +- ansible.builtin.assert: + that: + - result.changed == false + - result.updates is not defined + +- ansible.builtin.debug: + msg: END common/src_match_none.yaml on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/common/sublevel_block.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/common/sublevel_block.yaml new file mode 100644 index 00000000..b1854b86 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/common/sublevel_block.yaml @@ -0,0 +1,50 @@ +--- +- ansible.builtin.debug: + msg: START common/sublevel_block.yaml on connection={{ ansible_connection }} + +- name: Setup + ignore_errors: true + cisco.nxos.nxos_config: &id001 + lines: no ip access-list test + match: none + +- name: Configure sub level command using block replace + register: result + cisco.nxos.nxos_config: + lines: + - 10 permit ip 192.0.2.1/32 any log + - 20 permit ip 192.0.2.2/32 any log + - 30 permit ip 192.0.2.3/32 any log + - 40 permit ip 192.0.2.4/32 any log + parents: ip access-list test + replace: block + +- ansible.builtin.assert: + that: + - result.changed == true + - "'ip access-list test' in result.updates" + - "'10 permit ip 192.0.2.1/32 any log' in result.updates" + - "'20 permit ip 192.0.2.2/32 any log' in result.updates" + - "'30 permit ip 192.0.2.3/32 any log' in result.updates" + - "'40 permit ip 192.0.2.4/32 any log' in result.updates" + +- name: Check sub level command using block replace + register: result + cisco.nxos.nxos_config: + lines: + - 10 permit ip 192.0.2.1/32 any log + - 20 permit ip 192.0.2.2/32 any log + - 30 permit ip 192.0.2.3/32 any log + - 40 permit ip 192.0.2.4/32 any log + parents: ip access-list test + replace: block + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Teardown + cisco.nxos.nxos_config: *id001 + +- ansible.builtin.debug: + msg: END common/sublevel_block.yaml on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/common/toplevel.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/common/toplevel.yaml new file mode 100644 index 00000000..06038480 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/common/toplevel.yaml @@ -0,0 +1,35 @@ +--- +- ansible.builtin.debug: + msg: START common/toplevel.yaml on connection={{ ansible_connection }} + +- name: Setup + cisco.nxos.nxos_config: + lines: hostname switch + match: none + +- name: Configure top level command + register: result + cisco.nxos.nxos_config: + lines: hostname foo + +- ansible.builtin.assert: + that: + - result.changed == true + - "'hostname foo' in result.updates" + +- name: Configure top level command idempotent check + register: result + cisco.nxos.nxos_config: + lines: hostname foo + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Teardown + cisco.nxos.nxos_config: + lines: hostname switch + match: none + +- ansible.builtin.debug: + msg: END common/toplevel.yaml on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/common/toplevel_nonidempotent.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/common/toplevel_nonidempotent.yaml new file mode 100644 index 00000000..7903833c --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/common/toplevel_nonidempotent.yaml @@ -0,0 +1,37 @@ +--- +- ansible.builtin.debug: + msg: START common/nonidempotent.yaml on connection={{ ansible_connection }} + +- name: Setup + cisco.nxos.nxos_config: + lines: hostname switch + match: none + +- name: Configure top level command + register: result + cisco.nxos.nxos_config: + lines: hostname foo + match: strict + +- ansible.builtin.assert: + that: + - result.changed == true + - "'hostname foo' in result.updates" + +- name: Configure top level command idempotent check + register: result + cisco.nxos.nxos_config: + lines: hostname foo + match: strict + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: Teardown + cisco.nxos.nxos_config: + lines: hostname switch + match: none + +- ansible.builtin.debug: + msg: END common/nonidempotent.yaml on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/nxapi/multilevel.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/nxapi/multilevel.yaml new file mode 100644 index 00000000..4e0d62ac --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/nxapi/multilevel.yaml @@ -0,0 +1,43 @@ +--- +- ansible.builtin.debug: + msg: START nxapi/mulitlevel.yaml + +- name: Setup + cisco.nxos.nxos_config: + lines: feature bgp + match: none + +- name: Configure multi level command + register: result + cisco.nxos.nxos_config: + lines: maximum-paths 14 + parents: + - router bgp 1 + - address-family ipv4 unicast + +- ansible.builtin.assert: + that: + - result.changed == true + - "'router bgp 1' in result.updates" + - "'address-family ipv4 unicast' in result.updates" + - "'maximum-paths 14' in result.updates" + +- name: Test multi level command + register: result + cisco.nxos.nxos_config: + lines: maximum-paths 14 + parents: + - router bgp 1 + - address-family ipv4 unicast + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Teardown + cisco.nxos.nxos_config: + lines: no feature bgp + match: none + +- ansible.builtin.debug: + msg: END nxapi/mulitlevel.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/nxapi/sublevel.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/nxapi/sublevel.yaml new file mode 100644 index 00000000..77032d44 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/nxapi/sublevel.yaml @@ -0,0 +1,39 @@ +--- +- ansible.builtin.debug: + msg: START nxapi/sublevel.yaml + +- name: Setup + ignore_errors: true + cisco.nxos.nxos_config: + lines: no ip access-list test + match: none + +- name: Configure sub level command + register: result + cisco.nxos.nxos_config: + lines: 10 permit ip any any log + parents: ip access-list test + +- ansible.builtin.assert: + that: + - result.changed == true + - "'ip access-list test' in result.updates" + - "'10 permit ip any any log' in result.updates" + +- name: Configure sub level command idempotent check + register: result + cisco.nxos.nxos_config: + lines: 10 permit ip any any log + parents: ip access-list test + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Teardown + cisco.nxos.nxos_config: + lines: no ip access-list test + match: none + +- ansible.builtin.debug: + msg: END nxapi/sublevel.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/nxapi/sublevel_exact.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/nxapi/sublevel_exact.yaml new file mode 100644 index 00000000..f0b0357e --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/nxapi/sublevel_exact.yaml @@ -0,0 +1,61 @@ +--- +- ansible.builtin.debug: + msg: START nxapi/sublevel_exact.yaml + +- name: Setup + ignore_errors: true + cisco.nxos.nxos_config: + lines: + - 10 permit ip 192.0.2.1/32 any log + - 20 permit ip 192.0.2.2/32 any log + - 30 permit ip 192.0.2.3/32 any log + - 40 permit ip 192.0.2.4/32 any log + - 50 permit ip 192.0.2.5/32 any log + parents: ip access-list test + match: none + +- name: Configure sub level command using exact match + register: result + cisco.nxos.nxos_config: + lines: + - 10 permit ip 192.0.2.1/32 any log + - 20 permit ip 192.0.2.2/32 any log + - 30 permit ip 192.0.2.3/32 any log + - 40 permit ip 192.0.2.4/32 any log + parents: ip access-list test + before: no ip access-list test + match: exact + replace: block + +- ansible.builtin.assert: + that: + - result.changed == true + - "'ip access-list test' in result.updates" + - "'10 permit ip 192.0.2.1/32 any log' in result.updates" + - "'20 permit ip 192.0.2.2/32 any log' in result.updates" + - "'30 permit ip 192.0.2.3/32 any log' in result.updates" + - "'40 permit ip 192.0.2.4/32 any log' in result.updates" + - "'50 permit ip 192.0.2.5/32 any log' not in result.updates" + +- name: Check sub level command using exact match + register: result + cisco.nxos.nxos_config: + lines: + - 10 permit ip 192.0.2.1/32 any log + - 20 permit ip 192.0.2.2/32 any log + - 30 permit ip 192.0.2.3/32 any log + - 40 permit ip 192.0.2.4/32 any log + parents: ip access-list test + match: exact + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Teardown + cisco.nxos.nxos_config: + lines: no ip access-list test + match: none + +- ansible.builtin.debug: + msg: END nxapi/sublevel_exact.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/nxapi/sublevel_strict.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/nxapi/sublevel_strict.yaml new file mode 100644 index 00000000..d8538efd --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/nxapi/sublevel_strict.yaml @@ -0,0 +1,60 @@ +--- +- ansible.builtin.debug: + msg: START nxapi/sublevel_strict.yaml + +- name: Setup + cisco.nxos.nxos_config: + lines: + - 10 permit ip 192.0.2.1/32 any log + - 20 permit ip 192.0.2.2/32 any log + - 30 permit ip 192.0.2.3/32 any log + - 40 permit ip 192.0.2.4/32 any log + - 50 permit ip 192.0.2.5/32 any log + parents: ip access-list test + match: none + +- name: Configure sub level command using strict match + register: result + cisco.nxos.nxos_config: + lines: + - 10 permit ip 192.0.2.1/32 any log + - 30 permit ip 192.0.2.2/32 any log + - 20 permit ip 192.0.2.3/32 any log + - 40 permit ip 192.0.2.4/32 any log + parents: ip access-list test + before: no ip access-list test + match: strict + replace: block + +- ansible.builtin.assert: + that: + - result.changed == true + - "'ip access-list test' in result.updates" + - "'10 permit ip 192.0.2.1/32 any log' in result.updates" + - "'30 permit ip 192.0.2.2/32 any log' in result.updates" + - "'20 permit ip 192.0.2.3/32 any log' in result.updates" + - "'40 permit ip 192.0.2.4/32 any log' in result.updates" + - "'50 permit ip 192.0.2.5/32 any log' not in result.updates" + +- name: Check sub level command using strict match + register: result + cisco.nxos.nxos_config: + lines: + - 10 permit ip 192.0.2.1/32 any log + - 20 permit ip 192.0.2.3/32 any log + - 30 permit ip 192.0.2.2/32 any log + - 40 permit ip 192.0.2.4/32 any log + parents: ip access-list test + match: strict + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Teardown + cisco.nxos.nxos_config: + lines: no ip access-list test + match: none + +- ansible.builtin.debug: + msg: END nxapi/sublevel_strict.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/nxapi/toplevel_after.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/nxapi/toplevel_after.yaml new file mode 100644 index 00000000..6e30c43f --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/nxapi/toplevel_after.yaml @@ -0,0 +1,42 @@ +--- +- ansible.builtin.debug: + msg: START nxapi/toplevel_after.yaml + +- name: Setup + cisco.nxos.nxos_config: + lines: + - snmp-server contact ansible + - hostname switch + match: none + +- name: Configure top level command with before + register: result + cisco.nxos.nxos_config: + lines: hostname foo + after: snmp-server contact bar + +- ansible.builtin.assert: + that: + - result.changed == true + - "'hostname foo' in result.updates" + - "'snmp-server contact bar' in result.updates" + +- name: Configure top level command with before idempotent check + register: result + cisco.nxos.nxos_config: + lines: hostname foo + after: snmp-server contact foo + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Teardown + cisco.nxos.nxos_config: + lines: + - no snmp-server contact ansible + - hostname switch + match: none + +- ansible.builtin.debug: + msg: END nxapi/toplevel_after.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/nxapi/toplevel_before.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/nxapi/toplevel_before.yaml new file mode 100644 index 00000000..628bf5cd --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/nxapi/toplevel_before.yaml @@ -0,0 +1,42 @@ +--- +- ansible.builtin.debug: + msg: START nxapi/toplevel_before.yaml + +- name: Setup + cisco.nxos.nxos_config: + lines: + - snmp-server contact ansible + - hostname switch + match: none + +- name: Configure top level command with before + register: result + cisco.nxos.nxos_config: + lines: hostname foo + before: snmp-server contact bar + +- ansible.builtin.assert: + that: + - result.changed == true + - "'hostname foo' in result.updates" + - "'snmp-server contact bar' in result.updates" + +- name: Configure top level command with before idempotent check + register: result + cisco.nxos.nxos_config: + lines: hostname foo + before: snmp-server contact foo + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Teardown + cisco.nxos.nxos_config: + lines: + - no snmp-server contact ansible + - hostname switch + match: none + +- ansible.builtin.debug: + msg: END nxapi/toplevel_before.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/redirection/cli/shortname.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/redirection/cli/shortname.yaml new file mode 100644 index 00000000..5da3c02b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_config/tests/redirection/cli/shortname.yaml @@ -0,0 +1,39 @@ +--- +- ansible.builtin.debug: + msg: START cli/shortname.yaml on connection={{ ansible_connection }} + +- name: Use src with module alias + register: result + cisco.nxos.config: + src: basic/config.j2 + +- ansible.builtin.assert: + that: + # make sure that the template content was read and not the path + - result.changed == true + - result.updates is defined + +- name: Use module alias to take configuration backup + register: result + cisco.nxos.config: + backup: true + backup_options: + filename: backup_with_alias.cfg + dir_path: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}" + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: Check if the backup file-4 exist + ansible.builtin.find: + paths: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}/backup_with_alias.cfg" + register: backup_file + connection: local + +- ansible.builtin.assert: + that: + - backup_file.files is defined + +- ansible.builtin.debug: + msg: END cli/shortname.yaml on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_devicealias/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_devicealias/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_devicealias/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_devicealias/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_devicealias/meta/main.yml new file mode 100644 index 00000000..ed97d539 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_devicealias/meta/main.yml @@ -0,0 +1 @@ +--- diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_devicealias/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_devicealias/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_devicealias/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_devicealias/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_devicealias/tasks/main.yaml new file mode 100644 index 00000000..477fbd41 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_devicealias/tasks/main.yaml @@ -0,0 +1,19 @@ +--- +- name: Check platform type and skip if not MDS + register: result + cisco.nxos.nxos_command: + commands: show version | grep MDS + +- name: Set skip_test flag to false + ansible.builtin.set_fact: + skip_test: false + +- name: Set skip_test flag to true if not MDS + ansible.builtin.set_fact: + skip_test: true + when: result.stdout[0] is not search('MDS') + +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: cli + when: not skip_test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_devicealias/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_devicealias/tests/common/sanity.yaml new file mode 100644 index 00000000..61d8a02d --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_devicealias/tests/common/sanity.yaml @@ -0,0 +1,58 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_devicealias sanity test + +- name: Setup - remove device alias if configured + ignore_errors: true + cisco.nxos.nxos_devicealias: &id002 + da: + - name: ansible_test1_add + remove: true + + - name: ansible_test2_add + remove: true + +- block: + - name: Configure device alias + register: result + cisco.nxos.nxos_devicealias: &id001 + da: + - name: ansible_test1_add + pwwn: 57:bb:cc:dd:ee:ff:11:67 + + - name: ansible_test2_add + pwwn: 65:22:21:20:19:18:1a:0d + + - ansible.builtin.assert: + that: + - result.changed == true + + - ansible.builtin.assert: + that: + - result.commands == desired + vars: + desired: + - "terminal dont-ask" + - "device-alias database" + - "device-alias name ansible_test1_add pwwn 57:bb:cc:dd:ee:ff:11:67" + - "device-alias name ansible_test2_add pwwn 65:22:21:20:19:18:1a:0d" + - "device-alias commit" + - "no terminal dont-ask" + + - name: Idempotence check + register: result + cisco.nxos.nxos_devicealias: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + + - ansible.builtin.assert: + that: + - result.commands == [] + always: + - name: Remove device alias configuration + cisco.nxos.nxos_devicealias: *id002 + + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_devicealias sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_global/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_global/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_global/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_global/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_global/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_global/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_global/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_global/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_global/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_global/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_global/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_global/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_global/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_global/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_global/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_global/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_global/tests/common/sanity.yaml new file mode 100644 index 00000000..92feff4d --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_global/tests/common/sanity.yaml @@ -0,0 +1,67 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_evpn_global sanity test + +- name: Setup + ignore_errors: true + cisco.nxos.nxos_config: &id005 + lines: no nv overlay evpn + match: none + +- name: Disable 'feature nv overlay' + ignore_errors: true + cisco.nxos.nxos_feature: &id006 + feature: nv overlay + state: disabled + +- block: + - name: Enable 'feature nv overlay' + ignore_errors: true + cisco.nxos.nxos_feature: + feature: nv overlay + state: enabled + + - name: Enable NV overlay EVPN + register: result + cisco.nxos.nxos_evpn_global: &id001 + nv_overlay_evpn: true + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Check idempotence - enable NV overlay EVPN + register: result + cisco.nxos.nxos_evpn_global: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Disable NV overlay EVPN + register: result + cisco.nxos.nxos_evpn_global: &id003 + nv_overlay_evpn: false + + - ansible.builtin.assert: *id002 + + - name: Check dempotence - disable NV overlay EVPN + register: result + cisco.nxos.nxos_evpn_global: *id003 + + - ansible.builtin.assert: *id004 + when: not ( platform is search('N3K|N35|N3L')) + rescue: + - ansible.builtin.debug: + msg: connection={{ ansible_connection }} nxos_evpn_global sanity test - FALURE ENCOUNTERED + always: + - name: Cleanup - disable NV overlay EVPN + ignore_errors: true + cisco.nxos.nxos_config: *id005 + + - name: Cleanup - disable 'feature nv overlay' + ignore_errors: true + cisco.nxos.nxos_feature: *id006 + + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_evpn_global sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_vni/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_vni/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_vni/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_vni/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_vni/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_vni/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_vni/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_vni/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_vni/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_vni/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_vni/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_vni/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_vni/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_vni/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_vni/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_vni/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_vni/tests/common/sanity.yaml new file mode 100644 index 00000000..344fe374 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_evpn_vni/tests/common/sanity.yaml @@ -0,0 +1,113 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_evpn_vni sanity test + +- name: Set a fact for 'nvoe_supported' + ansible.builtin.set_fact: + nvoe_supported: "{{ platform is not search('N3K|N3L|N35')}}" + +- name: Setup + ignore_errors: true + when: nvoe_supported + cisco.nxos.nxos_config: &id007 + lines: no nv overlay evpn + match: none + +- block: + - name: Enable 'feature bgp' + cisco.nxos.nxos_feature: + feature: bgp + state: enabled + + - name: Enable NV overlay EVPN + cisco.nxos.nxos_config: + lines: nv overlay evpn + match: none + + - name: Configure nxos_evpn_vni + register: result + cisco.nxos.nxos_evpn_vni: &id001 + vni: 6000 + route_distinguisher: "60:10" + route_target_import: + - auto + - "5000:10" + - "4100:100" + route_target_export: + - auto + - "5000:10" + - "192.0.2.1:43" + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Check idempotence + register: result + cisco.nxos.nxos_evpn_vni: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Configure nxos_evpn_vni + register: result + cisco.nxos.nxos_evpn_vni: &id003 + vni: 6000 + route_distinguisher: "50:20" + route_target_import: auto + route_target_export: auto + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_evpn_vni: *id003 + + - ansible.builtin.assert: *id004 + + - name: Configure nxos_evpn_vni + register: result + cisco.nxos.nxos_evpn_vni: &id005 + vni: 6000 + route_distinguisher: default + route_target_import: default + route_target_export: default + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_evpn_vni: *id005 + + - ansible.builtin.assert: *id004 + + - name: Remove nxos_evpn_vni + register: result + cisco.nxos.nxos_evpn_vni: &id006 + vni: 6000 + state: absent + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_evpn_vni: *id006 + + - ansible.builtin.assert: *id004 + when: nvoe_supported + always: + - block: + - name: Remove nv overlay evpn + ignore_errors: true + cisco.nxos.nxos_config: *id007 + + - name: Disable 'feature bgp' + ignore_errors: true + cisco.nxos.nxos_feature: + feature: bgp + state: disabled + when: nvoe_supported + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_evpn_vni sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_facts/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_facts/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_facts/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_facts/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_facts/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_facts/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_facts/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_facts/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_facts/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_facts/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_facts/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_facts/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_facts/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_facts/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_facts/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_facts/tests/common/all_facts.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_facts/tests/common/all_facts.yaml new file mode 100644 index 00000000..cce7c66a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_facts/tests/common/all_facts.yaml @@ -0,0 +1,41 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }}/all_facts.yaml + +- name: Test getting all facts + register: result + cisco.nxos.nxos_facts: + gather_subset: + - all + +- ansible.builtin.assert: + that: + - result.changed == false + - "'config' in result.ansible_facts.ansible_net_gather_subset" + - "'hardware' in result.ansible_facts.ansible_net_gather_subset" + - "'default' in result.ansible_facts.ansible_net_gather_subset" + - "'interfaces' in result.ansible_facts.ansible_net_gather_subset" + - result.ansible_facts.ansible_net_filesystems is defined + - result.ansible_facts.ansible_net_interfaces is defined + - result.ansible_facts.ansible_net_config is defined + - result.ansible_facts.ansible_net_model is defined + - result.ansible_facts.ansible_net_memfree_mb > 1 + - result.ansible_facts.ansible_net_memtotal_mb > 1 + +- name: Collect list of available network resources for nxos + register: result + cisco.nxos.nxos_facts: + available_network_resources: true + gather_network_resources: all + +- name: Assert that correct available_network_resources returned + ansible.builtin.assert: + that: + - result.changed == false + - >- + {{ result['ansible_facts']['available_network_resources'] | + symmetric_difference(result['ansible_facts']['ansible_net_gather_network_resources']) | + length == 0 }} + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }}/all_facts.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_facts/tests/common/default_facts.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_facts/tests/common/default_facts.yaml new file mode 100644 index 00000000..3296fb4e --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_facts/tests/common/default_facts.yaml @@ -0,0 +1,26 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }}/default_facts.yaml + +- name: Test getting default facts + register: result + cisco.nxos.nxos_facts: + +- ansible.builtin.assert: + that: + - result.changed == false + - "'default' in result.ansible_facts.ansible_net_gather_subset" + - "'config' not in result.ansible_facts.ansible_net_gather_subset" + - result.ansible_facts.ansible_net_hostname is defined + - result.ansible_facts.ansible_net_image is defined + - result.ansible_facts.ansible_net_license_hostid is defined + - result.ansible_facts.ansible_net_model is defined + - result.ansible_facts.ansible_net_platform is defined + - result.ansible_facts.ansible_net_python_version is defined + - result.ansible_facts.ansible_net_serialnum is defined + - result.ansible_facts.ansible_net_system is defined + - result.ansible_facts.ansible_net_version is defined + - result.ansible_facts.ansible_network_resources == {} + +- ansible.builtin.debug: + msg: END cli/default.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_facts/tests/common/invalid_subset.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_facts/tests/common/invalid_subset.yaml new file mode 100644 index 00000000..5a620c12 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_facts/tests/common/invalid_subset.yaml @@ -0,0 +1,19 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }}/invalid_subset.yaml + +- name: Test invalid subset (foobar) + register: result + ignore_errors: true + cisco.nxos.nxos_facts: + gather_subset: + - foobar + +- ansible.builtin.assert: + that: + - result.changed == false + - result.failed == true + - "'Subset must be one of' in result.msg" + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }}/invalid_subset.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_facts/tests/common/not_hardware.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_facts/tests/common/not_hardware.yaml new file mode 100644 index 00000000..fc73bfcd --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_facts/tests/common/not_hardware.yaml @@ -0,0 +1,21 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }}/not_hardware_facts.yaml + +- name: Test not hardware + register: result + cisco.nxos.nxos_facts: + gather_subset: + - "!hardware" + +- ansible.builtin.assert: + that: + - result.changed == false + - "'config' in result.ansible_facts.ansible_net_gather_subset" + - "'default' in result.ansible_facts.ansible_net_gather_subset" + - "'interfaces' in result.ansible_facts.ansible_net_gather_subset" + - "'hardware' not in result.ansible_facts.ansible_net_gather_subset" + - result.ansible_facts.ansible_net_filesystems is not defined + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }}/not_hardware_facts.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_facts/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_facts/tests/common/sanity.yaml new file mode 100644 index 00000000..1861fa4a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_facts/tests/common/sanity.yaml @@ -0,0 +1,63 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_facts sanity test + +- name: Nxos_facts gather hardware facts + register: result + cisco.nxos.nxos_facts: + gather_subset: hardware + +- ansible.builtin.assert: + that: + - result.changed == false + - "'hardware' in result.ansible_facts.ansible_net_gather_subset" + - "'config' not in result.ansible_facts.ansible_net_gather_subset" + - "'interfaces' not in result.ansible_facts.ansible_net_gather_subset" + - result.ansible_facts.ansible_net_filesystems is defined + - result.ansible_facts.ansible_net_memfree_mb > 1 + - result.ansible_facts.ansible_net_memtotal_mb > 1 + +- name: Nxos_facts gather configuration facts + register: result + cisco.nxos.nxos_facts: + gather_subset: config + +- ansible.builtin.assert: + that: + - result.changed == false + - "'config' in result.ansible_facts.ansible_net_gather_subset" + - "'hardware' not in result.ansible_facts.ansible_net_gather_subset" + - "'interfaces' not in result.ansible_facts.ansible_net_gather_subset" + - result.ansible_facts.ansible_net_config is defined + +- name: Nxos_facts gather configuration and hardware facts + register: result + cisco.nxos.nxos_facts: + gather_subset: + - hardware + - config + +- ansible.builtin.assert: + that: + - result.changed == false + - "'hardware' in result.ansible_facts.ansible_net_gather_subset" + - "'config' in result.ansible_facts.ansible_net_gather_subset" + - "'interfaces' not in result.ansible_facts.ansible_net_gather_subset" + - result.ansible_facts.ansible_net_filesystems is defined + - result.ansible_facts.ansible_net_config is defined + - result.ansible_facts.ansible_net_memfree_mb > 1 + - result.ansible_facts.ansible_net_memtotal_mb > 1 + +- name: Nxos_facts gather features facts + register: result + cisco.nxos.nxos_facts: + gather_subset: features + +- ansible.builtin.assert: + that: + - result.changed == false + - "'features' in result.ansible_facts.ansible_net_gather_subset" + - result.ansible_facts.ansible_net_features_enabled is defined + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_facts sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_feature/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_feature/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_feature/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_feature/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_feature/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_feature/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_feature/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_feature/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_feature/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_feature/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_feature/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_feature/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_feature/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_feature/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_feature/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_feature/tests/common/configure.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_feature/tests/common/configure.yaml new file mode 100644 index 00000000..bc73f56e --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_feature/tests/common/configure.yaml @@ -0,0 +1,98 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }}/configure.yaml + +- name: Setup + cisco.nxos.nxos_config: &teardown + lines: + - no feature bgp + - no feature fabric forwarding + match: none + +- name: Enable BGP + register: result + cisco.nxos.nxos_feature: + feature: bgp + state: enabled + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: Verify BGP + register: result + cisco.nxos.nxos_feature: + feature: bgp + state: enabled + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Disable BGP + register: result + cisco.nxos.nxos_feature: + feature: bgp + state: disabled + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: Verify BGP + register: result + cisco.nxos.nxos_feature: + feature: bgp + state: disabled + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Verify fabric forwarding + register: result + cisco.nxos.nxos_feature: + feature: fabric forwarding + state: enabled + +- ansible.builtin.assert: + that: + - result.changed == True + - "'feature fabric forwarding' in result.commands" + +- name: Verify fabric forwarding (idempotent) + register: result + cisco.nxos.nxos_feature: + feature: fabric forwarding + state: enabled + +- ansible.builtin.assert: + that: + - result.changed == False + +- name: Verify fabric forwarding disable + register: result + cisco.nxos.nxos_feature: + feature: fabric forwarding + state: disabled + +- ansible.builtin.assert: + that: + - result.changed == True + - "'no feature fabric forwarding' in result.commands" + +- name: Verify fabric forwarding disabled (idempotent) + register: result + cisco.nxos.nxos_feature: + feature: fabric forwarding + state: disabled + +- ansible.builtin.assert: + that: + - result.changed == False + +- name: Teardown + cisco.nxos.nxos_config: *teardown + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }}/configure.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_feature/tests/common/invalid.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_feature/tests/common/invalid.yaml new file mode 100644 index 00000000..91d9581d --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_feature/tests/common/invalid.yaml @@ -0,0 +1,16 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }}/invalid.yaml + +- name: Configure invalid feature name + register: result + ignore_errors: true + cisco.nxos.nxos_feature: + feature: invalid + +- ansible.builtin.assert: + that: + - result.failed == true + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }}/invalid.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_file_copy/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_file_copy/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_file_copy/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_file_copy/fixtures/data.cfg b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_file_copy/fixtures/data.cfg new file mode 100644 index 00000000..fafd7451 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_file_copy/fixtures/data.cfg @@ -0,0 +1 @@ +TEST FILE diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_file_copy/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_file_copy/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_file_copy/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_file_copy/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_file_copy/tasks/cli.yaml new file mode 100644 index 00000000..311e3941 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_file_copy/tasks/cli.yaml @@ -0,0 +1,31 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_file_copy/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_file_copy/tasks/main.yaml new file mode 100644 index 00000000..33ba6cb9 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_file_copy/tasks/main.yaml @@ -0,0 +1,37 @@ +--- +- name: Fetch mgmt interface information + cisco.nxos.nxos_command: + commands: show interface mgmt 0 | json + register: result + +- name: Store mgmt interface IP address + ansible.builtin.set_fact: + mgmt0_ip: "{{ result['stdout'][0]['TABLE_interface']['ROW_interface']['eth_ip_addr'] }}" + +- name: Generate and store random password for temp user + ansible.builtin.set_fact: + temp_passwd: "{{ lookup('password', '/dev/null length=15 chars=ascii_letters') }}" + delegate_to: localhost + no_log: true + +- name: Configure temporary user for test + cisco.nxos.nxos_user: + name: temp_user + configured_password: "{{ temp_passwd }}" + +- name: Run the CLI and NX-API tests + block: + - name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + + - name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi + always: + - name: Remove temporary user + cisco.nxos.nxos_user: + name: temp_user + state: absent diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_file_copy/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_file_copy/tasks/nxapi.yaml new file mode 100644 index 00000000..18bf1b6e --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_file_copy/tasks/nxapi.yaml @@ -0,0 +1,31 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_file_copy/tests/cli/input_validation.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_file_copy/tests/cli/input_validation.yaml new file mode 100644 index 00000000..bcda7b4f --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_file_copy/tests/cli/input_validation.yaml @@ -0,0 +1,82 @@ +--- +- ansible.builtin.debug: + msg: START nxos_file_copy input_validation test + +- name: Input validation - param should be type <path> + register: result + ignore_errors: true + cisco.nxos.nxos_file_copy: + remote_file: 500 + file_pull: true + +- ansible.builtin.assert: + that: + - not result is search('argument remote_file is of type') + +- name: Input validation - param should be type <int> + register: result + ignore_errors: true + cisco.nxos.nxos_file_copy: + file_pull_timeout: foobar + +- ansible.builtin.assert: + that: + - result is search("argument 'file_pull_timeout' is of type .* and we were unable to convert to int") + +- name: Input validation - param should be type <bool> + register: result + ignore_errors: true + cisco.nxos.nxos_file_copy: + file_pull: foobar + +- ansible.builtin.assert: + that: + - result is search("argument 'file_pull' is of type .* and we were unable to convert to bool") + +- name: Input validation - param <file_pull> <remote_file> dependency + register: result + ignore_errors: true + cisco.nxos.nxos_file_copy: + file_pull: true + +- ansible.builtin.assert: + that: + - result is search("file_pull is True but all of the following are missing: remote_file, remote_scp_server") + +- name: Input validation - param <file_pull> <remote_scp_server> dependency + register: result + ignore_errors: true + cisco.nxos.nxos_file_copy: + file_pull: true + remote_file: /network-integration.cfg + +- ansible.builtin.assert: + that: + - result is search("file_pull is True but all of the following are missing: remote_file, remote_scp_server") + +- name: Input validation - remote_scp_server params together + register: result + ignore_errors: true + cisco.nxos.nxos_file_copy: + remote_scp_server: "{{ inventory_hostname_short }}" + +- ansible.builtin.assert: + that: + - result is search('parameters are required together: remote_scp_server, remote_scp_server_user') + +- name: Input validation - param <file_pull_protocol> should only accept strings, which are included in choices + register: result + ignore_errors: true + cisco.nxos.nxos_file_copy: + file_pull: true + file_pull_protocol: foobar + remote_file: /network-integration.cfg + remote_scp_server: foobar + remote_scp_server_user: foobar + +- ansible.builtin.assert: + that: + - result is search("'value of file_pull_protocol must be one of:' scp, sftp, http, https, tftp, ftp, got: foobar") + +- ansible.builtin.debug: + msg: END nxos_file_copy input_validation test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_file_copy/tests/cli/negative.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_file_copy/tests/cli/negative.yaml new file mode 100644 index 00000000..98d64eac --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_file_copy/tests/cli/negative.yaml @@ -0,0 +1,122 @@ +--- +- ansible.builtin.debug: + msg: START nxos_file_copy negative test + +- name: Set a fact for 'test_destination_file' and 'test_source_file' + ansible.builtin.set_fact: + test_source_file: "data.cfg" + test_destination_file: "test_destination_file" + +- name: Attempt to copy file to invalid file_system + register: result + ignore_errors: true + cisco.nxos.nxos_file_copy: + file_pull: false + local_file: "{{ role_path }}/fixtures/{{ test_source_file }}" + file_system: "invalid_media_type:" + connect_ssh_port: "{{ ansible_ssh_port|d(22) }}" + +- ansible.builtin.assert: + that: + - result is search('Invalid nxos filesystem invalid_media_type:') + +- name: Attempt to copy source file that does not exist on ansible controller + register: result + ignore_errors: true + cisco.nxos.nxos_file_copy: + file_pull: false + local_file: ./{{ test_source_file }}_does_not_exist + file_system: "bootflash:" + connect_ssh_port: "{{ ansible_ssh_port|d(22) }}" + +- ansible.builtin.assert: + that: + - result is search('Local file ./data.cfg_does_not_exist not found') + +- name: Try and copy file using an invalid remote scp server name + register: result + ignore_errors: true + cisco.nxos.nxos_file_copy: + file_pull: true + file_pull_timeout: 10 + remote_file: "{{ role_path }}/fixtures/{{ test_source_file }}" + local_file: "{{ test_destination_file }}_copy" + local_file_directory: dir1/dir2/dir3 + remote_scp_server: scp_server_gone.example.com + remote_scp_server_user: "{{ ansible_ssh_user }}" + remote_scp_server_password: "{{ temp_passwd }}" + connect_ssh_port: "{{ ansible_ssh_port|d(22) }}" + +- ansible.builtin.assert: + that: + - result.changed == false + - result.failed == True + - "'Could not resolve hostname' in result.module_stderr" + +# file_pull_timeout > 30s has no effect in this case, since the device +# shell gives up connecting to the bad IP after 30s and the response +# on the shell triggers a standard error regex. +- name: Try and copy file using an invalid remote scp server IP address + register: result + ignore_errors: true + cisco.nxos.nxos_file_copy: + file_pull: true + file_pull_timeout: 300 + remote_file: /{{ test_destination_file }} + local_file: "{{ test_destination_file }}_copy" + local_file_directory: dir1/dir2/dir3 + remote_scp_server: 192.168.55.55 + remote_scp_server_user: "{{ ansible_ssh_user }}" + remote_scp_server_password: "{{ temp_passwd }}" + connect_ssh_port: "{{ ansible_ssh_port|d(22) }}" + +- ansible.builtin.assert: + that: + - result.changed == false + - result.failed == True + +- ansible.builtin.pause: + seconds: 10 + +- name: Try and copy file using an invalid username + register: result + ignore_errors: true + cisco.nxos.nxos_file_copy: + file_pull: true + file_pull_timeout: 10 + remote_file: /{{ test_destination_file }} + local_file: "{{ test_destination_file }}_copy" + local_file_directory: dir1/dir2/dir3 + remote_scp_server: "{{ mgmt0_ip }}" + remote_scp_server_user: invalid_user_name + remote_scp_server_password: "{{ temp_passwd }}" + connect_ssh_port: "{{ ansible_ssh_port|d(22) }}" + +- ansible.builtin.assert: + that: + - result.changed == false + - result.failed == True + - "'Too many authentication failures' in result.module_stderr" + +- name: Try and copy file using an invalid password + register: result + ignore_errors: true + cisco.nxos.nxos_file_copy: + file_pull: true + file_pull_timeout: 10 + remote_file: /{{ test_destination_file }} + local_file: "{{ test_destination_file }}_copy" + local_file_directory: dir1/dir2/dir3 + remote_scp_server: "{{ mgmt0_ip }}" + remote_scp_server_user: "{{ ansible_ssh_user }}" + remote_scp_server_password: invalid_password + connect_ssh_port: "{{ ansible_ssh_port|d(22) }}" + +- ansible.builtin.assert: + that: + - result.changed == false + - result.failed == True + - "'Too many authentication failures' in result.module_stderr" + +- ansible.builtin.debug: + msg: END nxos_file_copy negative test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_file_copy/tests/cli/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_file_copy/tests/cli/sanity.yaml new file mode 100644 index 00000000..70c450c3 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_file_copy/tests/cli/sanity.yaml @@ -0,0 +1,201 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_file_copy sanity test + +- name: Set a fact for 'test_destination_file' and 'test_source_file' + ansible.builtin.set_fact: + test_source_file: "data.cfg" + test_destination_file: "test_destination_file" + +- name: Set a fact for 'sftp_root_dir' + ansible.builtin.set_fact: + sftp_root_dir: "{% if major_version is version('9.2', 'ge') %}/bootflash{% else %}/{% endif %}" + +- name: Setup - remove existing file + ignore_errors: true + cisco.nxos.nxos_command: &id002 + commands: + - terminal dont-ask + - delete {{ test_source_file }} + - delete {{ test_destination_file }} + - delete bootflash:/dir1/dir2/dir3/* + - rmdir dir1/dir2/dir3 + - rmdir dir1/dir2 + - rmdir dir1 + +- name: Setup - turn on 'feature scp-server' + cisco.nxos.nxos_feature: + feature: scp-server + state: enabled + +- name: Setup - turn on 'feature sftp-server' + cisco.nxos.nxos_feature: + feature: sftp-server + state: enabled + +- name: Setup - backup admin password if ansible_user is not admin + cisco.nxos.nxos_command: + commands: + - command: show running-config | include "username admin password" + register: nxos_admin_password + no_log: true + when: ansible_user != "admin" + +- name: Setup - change admin password if ansible_user is not admin + cisco.nxos.nxos_user: + name: admin + configured_password: "{{ temp_passwd }}" + when: ansible_user != "admin" + +- block: + - name: Copy {{ test_source_file }} file from ansible controller to bootflash + register: result + cisco.nxos.nxos_file_copy: &id001 + local_file: "{{ role_path }}/fixtures/{{ test_source_file }}" + file_system: "bootflash:" + connect_ssh_port: "{{ ansible_ssh_port|d(22) }}" + + - ansible.builtin.assert: + that: + - result.changed == true + - "'bootflash:' in result.file_system" + - "'/{{ test_source_file }}' in result.local_file" + - "'{{ test_source_file }}' in result.remote_file" + + - "'Sent: File copied to remote device.' in result.transfer_status" + + - name: Idempotence - copy {{ test_source_file }} file from ansible controller to bootflash + register: result + cisco.nxos.nxos_file_copy: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Setup - remove existing file + register: result + cisco.nxos.nxos_command: *id002 + + - name: Copy {{ test_source_file }} file from ansible controller to bootflash renamed as {{ test_destination_file }} + register: result + cisco.nxos.nxos_file_copy: &id003 + local_file: "{{ role_path }}/fixtures/{{ test_source_file }}" + remote_file: "{{ test_destination_file }}" + file_system: "bootflash:" + connect_ssh_port: "{{ ansible_ssh_port|d(22) }}" + + - ansible.builtin.assert: + that: + - result.changed == true + - "'bootflash:' in result.file_system" + - "'{{ test_source_file }}' in result.local_file" + - "'{{ test_destination_file }}' in result.remote_file" + - "'Sent: File copied to remote device.' in result.transfer_status" + + - name: Idempotence - copy {{ test_source_file }} file from ansible controller to bootflash renamed as {{ test_destination_file }} + register: result + cisco.nxos.nxos_file_copy: *id003 + + - name: Verify file_pull true options have no impact when file_pull is false + register: result + cisco.nxos.nxos_file_copy: + file_pull: false + file_pull_timeout: 1200 + file_pull_compact: true + file_pull_kstack: true + local_file_directory: dir1/dir2/dir3 + remote_scp_server: "{{ inventory_hostname_short }}" + remote_scp_server_user: temp_user + remote_scp_server_password: "{{ temp_passwd }}" + local_file: "{{ role_path }}/fixtures/{{ test_source_file }}" + remote_file: "{{ test_destination_file }}" + file_system: "bootflash:" + connect_ssh_port: "{{ ansible_ssh_port|d(22) }}" + + - ansible.builtin.assert: *id004 + + - name: Initiate copy from nxos device to copy {{ test_destination_file }} to bootflash:dir1/dir2/dir3/{{ test_destination_file }}_copy + register: result + cisco.nxos.nxos_file_copy: &id005 + file_pull: true + file_pull_timeout: 30 + remote_file: /{{ test_destination_file }} + local_file: "{{ test_destination_file }}_copy" + local_file_directory: dir1/dir2/dir3 + remote_scp_server: "{{ mgmt0_ip }}" + remote_scp_server_user: temp_user + remote_scp_server_password: "{{ temp_passwd }}" + connect_ssh_port: "{{ ansible_ssh_port|d(22) }}" + + - ansible.builtin.assert: &id006 + that: + - result.changed == true + - "'copy scp:' in result.copy_cmd" + - "'bootflash:' in result.file_system" + - "'bootflash:dir1/dir2/dir3/{{ test_destination_file }}_copy' in result.local_file" + - "'/{{ test_destination_file }}' in result.remote_file" + + - "'Received: File copied/pulled to nxos device from remote scp server.' in result.transfer_status" + - "'{{ mgmt0_ip }}' in result.remote_scp_server" + + - ansible.builtin.pause: + seconds: 60 + + - name: Overwrite the file + register: result + cisco.nxos.nxos_file_copy: *id005 + + - ansible.builtin.assert: *id006 + + - name: >- + Initiate copy with sftp from nxos device to copy + /bootflash/{{ test_destination_file }} to + bootflash:dir2/dir2/dir3/{{ test_destination_file }}_another_copy + register: result + cisco.nxos.nxos_file_copy: + file_pull: true + file_pull_protocol: sftp + file_pull_timeout: 60 + remote_file: "/bootflash/{{ test_destination_file }}" + local_file: "{{ test_destination_file }}_another_copy" + local_file_directory: dir1/dir2/dir3 + remote_scp_server: "{{ mgmt0_ip }}" + remote_scp_server_user: temp_user + remote_scp_server_password: "{{ temp_passwd }}" + connect_ssh_port: "{{ ansible_ssh_port|d(22) }}" + + - ansible.builtin.assert: + that: + - result.changed == true + - "'copy sftp:' in result.copy_cmd" + - "'bootflash:' in result.file_system" + - "'bootflash:dir1/dir2/dir3/{{ test_destination_file }}_another_copy' in result.local_file" + - "'/bootflash/{{ test_destination_file }}' in result.remote_file" + + - "'Received: File copied/pulled to nxos device from remote scp server.' in result.transfer_status" + - "'{{ mgmt0_ip }}' in result.remote_scp_server" + + always: + - name: Remove file + ignore_errors: true + cisco.nxos.nxos_command: *id002 + + - name: Recover the admin password if ansible_user is not admin + cisco.nxos.nxos_config: + lines: + - "{{ nxos_admin_password['stdout_lines'][0][0] }}" + no_log: true + when: ansible_user != "admin" + + - name: Turn off 'feature scp-server' + cisco.nxos.nxos_feature: + feature: scp-server + state: disabled + + - name: Turn off 'feature sftp-server' + cisco.nxos.nxos_feature: + feature: sftp-server + state: disabled + + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_file_copy sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_file_copy/tests/nxapi/badtransport.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_file_copy/tests/nxapi/badtransport.yaml new file mode 100644 index 00000000..aca1e195 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_file_copy/tests/nxapi/badtransport.yaml @@ -0,0 +1,18 @@ +--- +- ansible.builtin.debug: + msg: START nxapi/badtransport.yaml + +- name: Sending transport other than CLI should fail + register: result + ignore_errors: true + cisco.nxos.nxos_file_copy: + local_file: ./network-integration.cfg + file_system: "bootflash:" + connect_ssh_port: "{{ ansible_ssh_port|d(22) }}" + +- ansible.builtin.assert: + that: + - result.failed and result.msg is search('Connection type must be fully qualified name for network_cli connection type, got {{ ansible_connection }}') + +- ansible.builtin.debug: + msg: END nxapi/badtransport.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir/tests/common/sanity.yaml new file mode 100644 index 00000000..4da1bbbb --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir/tests/common/sanity.yaml @@ -0,0 +1,112 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_gir sanity test + +- name: Set a fact for 'gir_run' + ansible.builtin.set_fact: + gir_run: '{{ true if (platform is not search("N35")) else false }}' + +- name: Setup0 + ignore_errors: true + cisco.nxos.nxos_config: &id007 + lines: + - no system mode maintenance timeout 30 + - no configure maintenance profile normal-mode + - no configure maintenance profile maintenance-mode + match: none + +- name: Setup1 + ignore_errors: true + cisco.nxos.nxos_gir: + system_mode_maintenance: false + +- block: + - name: Put system in maintenance mode with reload reset reason + register: result + cisco.nxos.nxos_gir: &id001 + system_mode_maintenance_on_reload_reset_reason: manual_reload + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Check idempotence + register: result + cisco.nxos.nxos_gir: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Remove reload reason + register: result + cisco.nxos.nxos_gir: &id003 + system_mode_maintenance_on_reload_reset_reason: manual_reload + state: absent + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_gir: *id003 + + - ansible.builtin.assert: *id004 + + - name: Put system in maintenance mode with timeout + register: result + cisco.nxos.nxos_gir: &id005 + system_mode_maintenance_timeout: 30 + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_gir: *id005 + + - ansible.builtin.assert: *id004 + + - name: Remove maintenance mode timeout + register: result + cisco.nxos.nxos_gir: &id006 + system_mode_maintenance_timeout: 30 + state: absent + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_gir: *id006 + + - ansible.builtin.assert: *id004 + + - name: Put system in maintenance mode + register: result + cisco.nxos.nxos_gir: + system_mode_maintenance: true + + - ansible.builtin.assert: *id002 + when: gir_run + rescue: + - ansible.builtin.debug: + msg: connection={{ ansible_connection }} nxos_gir failure detected + always: + - name: Remove snapshots + ignore_errors: true + cisco.nxos.nxos_snapshot: + action: delete_all + + - name: Teardown0 + ignore_errors: true + cisco.nxos.nxos_config: *id007 + + - name: Put system back in normal mode + retries: 3 + delay: 30 + register: result + until: result is not failed + ignore_errors: true + cisco.nxos.nxos_gir: + system_mode_maintenance: false + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_gir sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir_profile_management/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir_profile_management/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir_profile_management/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir_profile_management/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir_profile_management/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir_profile_management/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir_profile_management/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir_profile_management/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir_profile_management/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir_profile_management/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir_profile_management/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir_profile_management/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir_profile_management/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir_profile_management/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir_profile_management/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir_profile_management/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir_profile_management/tests/common/sanity.yaml new file mode 100644 index 00000000..ae6c4b07 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_gir_profile_management/tests/common/sanity.yaml @@ -0,0 +1,102 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_gir_profile_management sanity test + +- name: Setup - remove maintenace mode profiles + ignore_errors: true + cisco.nxos.nxos_gir_profile_management: &id005 + mode: maintenance + state: absent + +- name: Setup - remove normal mode profiles + ignore_errors: true + cisco.nxos.nxos_gir_profile_management: &id006 + mode: normal + state: absent + +- name: Setup - turn on 'feature eigrp' + ignore_errors: true + cisco.nxos.nxos_feature: + feature: eigrp + state: enabled + +- block: + - name: Create maintenace mode profile + register: result + cisco.nxos.nxos_gir_profile_management: &id001 + mode: maintenance + commands: + - router eigrp 11 + - isolate + state: present + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Check idempotence - create maintenace mode profile + register: result + cisco.nxos.nxos_gir_profile_management: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Create normal mode profile + register: result + cisco.nxos.nxos_gir_profile_management: &id003 + mode: normal + commands: + - router eigrp 11 + - isolate + state: present + + - ansible.builtin.assert: *id002 + + - name: Check idempotence - create normal mode profile + register: result + cisco.nxos.nxos_gir_profile_management: *id003 + + - ansible.builtin.assert: *id004 + + - name: Remove maintenance mode profile + register: result + cisco.nxos.nxos_gir_profile_management: *id005 + + - ansible.builtin.assert: *id002 + + - name: Check idempotence - remove maintenance mode profile + register: result + cisco.nxos.nxos_gir_profile_management: *id005 + + - ansible.builtin.assert: *id004 + + - name: Remove normal mode profile + register: result + cisco.nxos.nxos_gir_profile_management: *id006 + + - ansible.builtin.assert: *id002 + + - name: Check idempotence - remove normal mode profile + register: result + cisco.nxos.nxos_gir_profile_management: *id006 + + - ansible.builtin.assert: *id004 + when: not ( platform is match('N35')) and not titanium + rescue: + - ansible.builtin.debug: + msg: connection={{ ansible_connection }} nxos_gir_profile_management failure detected + always: + - name: Remove normal mode profile + cisco.nxos.nxos_gir_profile_management: *id006 + + - name: Remove maintenance mode profile + cisco.nxos.nxos_gir_profile_management: *id005 + + - name: Turn off 'feature eigrp' + cisco.nxos.nxos_feature: + feature: eigrp + state: disabled + + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_gir_profile_management sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/defaults/main.yaml new file mode 100644 index 00000000..871ea460 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "[^_].*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tasks/cli.yaml new file mode 100644 index 00000000..9e4fb34b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tasks/main.yaml new file mode 100644 index 00000000..5d9d8222 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tasks/main.yaml @@ -0,0 +1,37 @@ +--- +- name: Fetch current hostname + cisco.nxos.nxos_command: + commands: show running-config | section ^hostname + register: hname_result + +- name: Set current hostname (default) + ansible.builtin.set_fact: + current_hostname: "switch" + +- name: Set current hostname + ansible.builtin.set_fact: + current_hostname: "{{ hname_result['stdout'][0].split(' ')[1] }}" + when: hname_result.stdout[0] != "" + +- name: Run the CLI and NX-API tests + block: + - name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli.yaml + + - name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi + always: + - name: Reset hostname + cisco.nxos.nxos_config: + lines: "hostname {{ current_hostname }}" + match: none + when: hname_result.stdout[0] != "" + + - name: Reset hostname (default) + cisco.nxos.nxos_config: + lines: "no hostname" + when: hname_result.stdout[0] == "" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tasks/nxapi.yaml new file mode 100644 index 00000000..5cb76e67 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tests/common/_populate_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tests/common/_populate_config.yaml new file mode 100644 index 00000000..67028c54 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tests/common/_populate_config.yaml @@ -0,0 +1,4 @@ +--- +- name: Populate configuration + cisco.nxos.nxos_config: + lines: "hostname {{ current_hostname }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tests/common/_remove_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tests/common/_remove_config.yaml new file mode 100644 index 00000000..78a488a5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tests/common/_remove_config.yaml @@ -0,0 +1,6 @@ +--- +- name: Reset hostname + cisco.nxos.nxos_config: + lines: "hostname {{ current_hostname }}" + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tests/common/deleted.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tests/common/deleted.yaml new file mode 100644 index 00000000..031feb05 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tests/common/deleted.yaml @@ -0,0 +1,38 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_hostname deleted integration tests connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Delete hostname configuration + cisco.nxos.nxos_hostname: &del + state: deleted + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ result['before'] == merged['before'] }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ deleted['commands'] == result['commands'] }}" + + - name: Assert that after dicts were correctly generated + ansible.builtin.assert: + that: + - result['after'] == {} + + - name: Delete hostname configuration (idempotent) + cisco.nxos.nxos_hostname: *del + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tests/common/empty_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tests/common/empty_config.yaml new file mode 100644 index 00000000..58ba1101 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tests/common/empty_config.yaml @@ -0,0 +1,61 @@ +--- +- ansible.builtin.debug: + msg: START nxos_hostname empty_config integration tests on connection={{ ansible_connection }} + +- name: Merged with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_hostname: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_hostname: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Overridden with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_hostname: + config: + state: overridden + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Rendered with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_hostname: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' + +- name: Parsed with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_hostname: + running_config: + state: parsed + +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state parsed' + +- ansible.builtin.debug: + msg: END nxos_hostname empty_config integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tests/common/fixtures/parsed.cfg b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tests/common/fixtures/parsed.cfg new file mode 100644 index 00000000..b72d4d30 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tests/common/fixtures/parsed.cfg @@ -0,0 +1 @@ +hostname NXOSv-9k diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tests/common/gathered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tests/common/gathered.yaml new file mode 100644 index 00000000..83bdb56f --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tests/common/gathered.yaml @@ -0,0 +1,19 @@ +--- +- ansible.builtin.debug: + msg: START nxos_hostname gathered integration tests on connection={{ ansible_connection }} + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Gather logging global facts using gathered + register: result + cisco.nxos.nxos_hostname: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: + - "{{ result['gathered'] == merged['before'] }}" + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tests/common/merged.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tests/common/merged.yaml new file mode 100644 index 00000000..d27561d2 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tests/common/merged.yaml @@ -0,0 +1,39 @@ +--- +- ansible.builtin.debug: + msg: "Start nxos_hostname merged integration tests connection={{ ansible_connection }}" + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Merge the provided configuration with the existing running configuration + cisco.nxos.nxos_hostname: &id001 + config: + hostname: NXOSv-9k + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: result['before'] == merged['before'] + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - merged['commands'] == result['commands'] + + - name: Assert that after dicts were correctly generated + ansible.builtin.assert: + that: + - merged['after'] == result['after'] + + - name: Merge the provided configuration with the existing running configuration (idempotent) + cisco.nxos.nxos_hostname: *id001 + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tests/common/overridden.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tests/common/overridden.yaml new file mode 100644 index 00000000..0a7b14f9 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tests/common/overridden.yaml @@ -0,0 +1,40 @@ +--- +- ansible.builtin.debug: + msg: "Start nxos_hostname overridden integration tests connection={{ ansible_connection }}" + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Override hostname configuration with provided configuration + cisco.nxos.nxos_hostname: &id001 + config: + hostname: NXOSv-9k + state: overridden + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: result['before'] == merged['before'] + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - merged['commands'] == result['commands'] + + - name: Assert that after dicts were correctly generated + ansible.builtin.assert: + that: + - merged['after'] == result['after'] + + - name: Override hostname configuration with provided configuration (idempotent) + cisco.nxos.nxos_hostname: *id001 + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tests/common/parsed.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tests/common/parsed.yaml new file mode 100644 index 00000000..b1ab1d99 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tests/common/parsed.yaml @@ -0,0 +1,14 @@ +--- +- ansible.builtin.debug: + msg: START nxos_hostname parsed integration tests on connection={{ ansible_connection }} + +- name: Parse externally provided logging configuration + register: result + cisco.nxos.nxos_hostname: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed + +- name: Assert that configuration was correctly parsed + ansible.builtin.assert: + that: + - "{{ merged['after'] == result['parsed'] }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tests/common/rendered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tests/common/rendered.yaml new file mode 100644 index 00000000..5e0a76c4 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tests/common/rendered.yaml @@ -0,0 +1,16 @@ +--- +- ansible.builtin.debug: + msg: START nxos_hostname rendered integration tests on connection={{ ansible_connection }} + +- name: Render platform specific configuration lines with state rendered (without connecting to the device) + cisco.nxos.nxos_hostname: + config: + hostname: NXOSv-9k + state: rendered + register: result + +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - merged['commands'] == result['rendered'] + - result.changed == False diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tests/common/replaced.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tests/common/replaced.yaml new file mode 100644 index 00000000..40857739 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/tests/common/replaced.yaml @@ -0,0 +1,40 @@ +--- +- ansible.builtin.debug: + msg: "Start nxos_hostname replaced integration tests connection={{ ansible_connection }}" + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Replace device configurations with provided configurations + cisco.nxos.nxos_hostname: &id001 + config: + hostname: NXOSv-9k + state: replaced + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: result['before'] == merged['before'] + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - merged['commands'] == result['commands'] + + - name: Assert that after dicts were correctly generated + ansible.builtin.assert: + that: + - merged['after'] == result['after'] + + - name: Replace device configurations with provided configurations (idempotent) + cisco.nxos.nxos_hostname: *id001 + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/vars/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/vars/main.yml new file mode 100644 index 00000000..14fdcf0d --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hostname/vars/main.yml @@ -0,0 +1,11 @@ +--- +merged: + before: + hostname: "{{ current_hostname }}" + commands: + - hostname NXOSv-9k + after: + hostname: NXOSv-9k +deleted: + commands: + - "no hostname {{ current_hostname }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp/tasks/main.yaml new file mode 100644 index 00000000..c9e70304 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp/tasks/main.yaml @@ -0,0 +1,12 @@ +--- +- name: Run the CLI and NX-API tests + block: + - name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + always: + - name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp/tests/common/sanity.yaml new file mode 100644 index 00000000..a4c77478 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp/tests/common/sanity.yaml @@ -0,0 +1,157 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_hsrp sanity test + +- name: Set a fact for 'intname1' + ansible.builtin.set_fact: + intname1: "{{ nxos_int1 }}" + +- name: Set a fact for 'intname2' + ansible.builtin.set_fact: + intname2: "{{ nxos_int2 }}" + +- block: + - name: Enable 'feature hsrp' + cisco.nxos.nxos_feature: + feature: hsrp + state: enabled + + - name: Change int1 mode + cisco.nxos.nxos_config: + commands: + - no switchport + parents: + - interface {{ intname1 }} + match: none + + - name: Change int2 mode + cisco.nxos.nxos_config: + commands: + - no switchport + parents: + - interface {{ intname2 }} + match: none + + - name: Configure nxos_hsrp + register: result + cisco.nxos.nxos_hsrp: &id001 + group: 1000 + version: 2 + vip: 10.1.1.1 + priority: 150 + interface: "{{ intname1 }}" + preempt: enabled + auth_type: md5 + auth_string: 7 1234 + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Configure idempotence + register: result + cisco.nxos.nxos_hsrp: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Configure group 100 + register: result + cisco.nxos.nxos_hsrp: &id003 + group: 100 + version: 2 + vip: 192.0.2.2 + priority: 25 + interface: "{{ intname1 }}" + preempt: enabled + auth_type: md5 + auth_string: 0 1234 + + - ansible.builtin.assert: *id002 + + - name: Configure idempotence + register: result + cisco.nxos.nxos_hsrp: *id003 + + - ansible.builtin.assert: *id004 + + - name: Change group 100 + register: result + cisco.nxos.nxos_hsrp: &id005 + group: 100 + version: 2 + vip: default + priority: default + interface: "{{ intname1 }}" + preempt: disabled + auth_type: md5 + auth_string: 0 1234 + + - ansible.builtin.assert: *id002 + + - name: Configure idempotence + register: result + cisco.nxos.nxos_hsrp: *id005 + + - ansible.builtin.assert: *id004 + + - name: Configure group 200 + register: result + cisco.nxos.nxos_hsrp: &id006 + group: 200 + vip: 192.0.2.3 + version: 1 + interface: "{{ intname2 }}" + auth_type: text + auth_string: "1234" + + - ansible.builtin.assert: *id002 + + - name: Configure idempotence + register: result + cisco.nxos.nxos_hsrp: *id006 + + - ansible.builtin.assert: *id004 + + - name: Change group 200 + register: result + cisco.nxos.nxos_hsrp: &id007 + group: 200 + vip: 192.0.2.3 + version: 2 + interface: "{{ intname2 }}" + auth_type: text + auth_string: default + + - ansible.builtin.assert: *id002 + + - name: Configure idempotence + register: result + cisco.nxos.nxos_hsrp: *id007 + + - ansible.builtin.assert: *id004 + + - name: Remove nxos_hsrp + register: result + cisco.nxos.nxos_hsrp: &id008 + group: 1000 + interface: "{{ intname1 }}" + state: absent + + - ansible.builtin.assert: *id002 + + - name: Remove idempotence + register: result + cisco.nxos.nxos_hsrp: *id008 + + - ansible.builtin.assert: *id004 + always: + - name: Disable 'feature hsrp' + ignore_errors: true + cisco.nxos.nxos_feature: + feature: hsrp + state: disabled + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_hsrp sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/defaults/main.yaml new file mode 100644 index 00000000..871ea460 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "[^_].*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tasks/cli.yaml new file mode 100644 index 00000000..9aa0d869 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tasks/cli.yaml @@ -0,0 +1,33 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tasks/nxapi.yaml new file mode 100644 index 00000000..5cb76e67 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tests/common/_populate_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tests/common/_populate_config.yaml new file mode 100644 index 00000000..40443023 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tests/common/_populate_config.yaml @@ -0,0 +1,16 @@ +--- +- name: Populate configuration - 1 + cisco.nxos.nxos_config: + lines: + - "feature hsrp" + - "feature bfd" + - "interface {{ nxos_int1 }}" + - " no switchport" + - " hsrp bfd" + +- name: Populate configuration - 2 + cisco.nxos.nxos_config: + lines: + - "interface {{ nxos_int2 }}" + - " no switchport" + - " hsrp bfd" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tests/common/_remove_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tests/common/_remove_config.yaml new file mode 100644 index 00000000..d55e828d --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tests/common/_remove_config.yaml @@ -0,0 +1,9 @@ +--- +- name: Remove configuration + cisco.nxos.nxos_config: + lines: + - "no feature bfd" + - "no feature hsrp" + - "default interface {{ nxos_int1 }}" + - "default interface {{ nxos_int2 }}" + ignore_errors: true diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tests/common/deleted.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tests/common/deleted.yaml new file mode 100644 index 00000000..ff8dec80 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tests/common/deleted.yaml @@ -0,0 +1,58 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_hsrp_interfaces deleted integration tests connection={{ ansible_connection }} + +- name: Set a fact for 'test_int1' and 'test_int2' + ansible.builtin.set_fact: + test_int1: "{{ nxos_int1 }}" + test_int2: "{{ nxos_int2 }}" + +- name: Set a fact for 'bfd_disable' and 'bfd_enable' + ansible.builtin.set_fact: + bfd_enable: enable + bfd_disable: disable + when: platform is not search('N35') + +- block: + - ansible.builtin.include_tasks: _remove_config.yaml + + - name: Setup2 + cisco.nxos.nxos_config: + lines: + - "feature bfd" + - "feature hsrp" + - "interface {{ test_int1 }}" + - " no switchport" + - " hsrp bfd" + + - name: Setup3 + cisco.nxos.nxos_config: + lines: + - "interface {{ test_int2 }}" + - " no switchport" + + - name: Deleted + register: result + cisco.nxos.nxos_hsrp_interfaces: &id001 + config: + - name: "{{ test_int1 }}" + bfd: "{{ bfd_disable|default(omit)}}" + state: deleted + + - ansible.builtin.assert: + that: + - result.changed == true + - "'no hsrp bfd' in result.commands" + msg: "Assert failed. 'result.commands': {{ result.commands }}" + + - name: Idempotence - deleted + register: result + cisco.nxos.nxos_hsrp_interfaces: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tests/common/empty_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tests/common/empty_config.yaml new file mode 100644 index 00000000..f80fd63b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tests/common/empty_config.yaml @@ -0,0 +1,61 @@ +--- +- ansible.builtin.debug: + msg: START nxos_hsrp_interfaces empty_config integration tests on connection={{ ansible_connection }} + +- name: Merged with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_hsrp_interfaces: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_hsrp_interfaces: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Overridden with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_hsrp_interfaces: + config: + state: overridden + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Rendered with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_hsrp_interfaces: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' + +- name: Parsed with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_hsrp_interfaces: + running_config: + state: parsed + +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state parsed' + +- ansible.builtin.debug: + msg: END nxos_hsrp_interfaces empty_config integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tests/common/gathered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tests/common/gathered.yaml new file mode 100644 index 00000000..138def68 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tests/common/gathered.yaml @@ -0,0 +1,21 @@ +--- +- ansible.builtin.debug: + msg: START nxos_hsrp_interfaces gathered integration tests on connection={{ ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Gather hsrp_interfaces facts from the device using nxos_hsrp_interfaces + register: result + cisco.nxos.nxos_hsrp_interfaces: + state: gathered + + - ansible.builtin.assert: + that: "{{ result['gathered'] | symmetric_difference(gathered) |length == 0 }}" + always: + - ansible.builtin.include_tasks: _remove_config.yaml + + - ansible.builtin.debug: + msg: END nxos_hsrp_interfaces gathered integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tests/common/merged.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tests/common/merged.yaml new file mode 100644 index 00000000..7daf36b6 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tests/common/merged.yaml @@ -0,0 +1,66 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_hsrp_interfaces merged integration tests connection={{ ansible_connection }} + +- name: Set a fact for 'test_int1' and 'test_int2' + ansible.builtin.set_fact: + test_int1: "{{ nxos_int1 }}" + test_int2: "{{ nxos_int2 }}" + +- name: Set a fact for 'bfd_disable' and 'bfd_enable' + ansible.builtin.set_fact: + bfd_enable: enable + bfd_disable: disable + when: platform is not search('N35') + +- block: + - ansible.builtin.include_tasks: _remove_config.yaml + + - name: Setup2 + cisco.nxos.nxos_config: + lines: + - "feature bfd" + - "feature hsrp" + - "interface {{ test_int1 }}" + - " no switchport" + - " hsrp bfd" + + - name: Setup3 + cisco.nxos.nxos_config: + lines: + - "interface {{ test_int2 }}" + - " no switchport" + + - name: Merged + register: result + cisco.nxos.nxos_hsrp_interfaces: &id001 + config: + - name: "{{ test_int1 }}" + bfd: "{{ bfd_disable|default(omit)}}" + state: merged + + - ansible.builtin.assert: + that: + - result.changed == true + - "'no hsrp bfd' in result.commands" + msg: "Assert failed. 'result.commands': {{ result.commands }}" + + - name: Gather hsrp_interfaces facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: hsrp_interfaces + + - name: Idempotence - merged + register: result + cisco.nxos.nxos_hsrp_interfaces: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + when: bfd_enable is defined + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tests/common/overridden.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tests/common/overridden.yaml new file mode 100644 index 00000000..5cef1e96 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tests/common/overridden.yaml @@ -0,0 +1,59 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_hsrp_interfaces overridden integration tests connection={{ ansible_connection }} + +- name: Set a fact for 'test_int1' and 'test_int2' + ansible.builtin.set_fact: + test_int1: "{{ nxos_int1 }}" + test_int2: "{{ nxos_int2 }}" + +- name: Set a fact for 'bfd_disable' and 'bfd_enable' + ansible.builtin.set_fact: + bfd_enable: enable + bfd_disable: disable + when: platform is not search('N35') + +- block: + - ansible.builtin.include_tasks: _remove_config.yaml + + - name: Setup2 + cisco.nxos.nxos_config: + lines: + - "feature bfd" + - "feature hsrp" + - "interface {{ test_int1 }}" + - " no switchport" + + - name: Setup3 + cisco.nxos.nxos_config: + lines: + - "interface {{ test_int2 }}" + - " no switchport" + - " hsrp bfd" + + - name: Overridden + register: result + cisco.nxos.nxos_hsrp_interfaces: &id001 + config: + - name: "{{ test_int1 }}" + bfd: "{{ bfd_enable|default(omit)}}" + state: overridden + + - ansible.builtin.assert: + that: + - result.changed == true + - result.commands[1] == 'no hsrp bfd' + - result.commands[3] == 'hsrp bfd' + msg: "Assert failed. 'result.commands': {{ result.commands }}" + + - name: Idempotence - overridden + register: result + cisco.nxos.nxos_hsrp_interfaces: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tests/common/parsed.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tests/common/parsed.yaml new file mode 100644 index 00000000..eeee8871 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tests/common/parsed.yaml @@ -0,0 +1,23 @@ +--- +- ansible.builtin.debug: + msg: START nxos_hsrp_interfaces parsed integration tests on connection={{ ansible_connection }} + +- block: + # Interfaces used in the task don't actually exist on the appliance + - name: Use parsed state to convert externally supplied configuration to structured format + register: result + cisco.nxos.nxos_hsrp_interfaces: + running_config: | + interface Ethernet1/800 + no switchport + hsrp bfd + interface Ethernet1/801 + no switchport + hsrp bfd + state: parsed + + - ansible.builtin.assert: + that: "{{ parsed | symmetric_difference(result['parsed']) |length==0 }}" + +- ansible.builtin.debug: + msg: END nxos_hsrp_interfaces parsed integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tests/common/rendered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tests/common/rendered.yaml new file mode 100644 index 00000000..2567ad5f --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tests/common/rendered.yaml @@ -0,0 +1,34 @@ +--- +- ansible.builtin.debug: + msg: START nxos_hsrp_interfaces rendered integration tests on connection={{ ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- block: + # Interfaces used here doesn't actually exist on the device + - name: Use rendered state to convert task input to device specific commands + register: result + cisco.nxos.nxos_hsrp_interfaces: + config: + - name: Ethernet1/800 + bfd: enable + - name: Ethernet1/801 + bfd: enable + state: rendered + + - ansible.builtin.assert: + that: "{{ rendered | symmetric_difference(result['rendered']) |length==0 }}" + + - name: Gather bfd_interfaces facts from the device and assert that its empty + register: result + cisco.nxos.nxos_hsrp_interfaces: + state: gathered + + - name: Make sure that rendered task actually did not make any changes to the device + ansible.builtin.assert: + that: "{{ result['gathered'] == [] }}" + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: END nxos_hsrp_interfaces rendered integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tests/common/replaced.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tests/common/replaced.yaml new file mode 100644 index 00000000..2761818b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/tests/common/replaced.yaml @@ -0,0 +1,58 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_hsrp_interfaces replaced integration tests connection={{ ansible_connection }} + +- name: Set a fact for 'test_int1' and 'test_int2' + ansible.builtin.set_fact: + test_int1: "{{ nxos_int1 }}" + test_int2: "{{ nxos_int2 }}" + +- name: Set a fact for 'bfd_disable' and 'bfd_enable' + ansible.builtin.set_fact: + bfd_enable: enable + bfd_disable: disable + when: platform is not search('N35') + +- block: + - ansible.builtin.include_tasks: _remove_config.yaml + + - name: Setup2 + cisco.nxos.nxos_config: + lines: + - "feature bfd" + - "feature hsrp" + - "interface {{ test_int1 }}" + - " no switchport" + - " hsrp bfd" + + - name: Setup3 + cisco.nxos.nxos_config: + lines: + - "interface {{ test_int2 }}" + - " no switchport" + + - name: Replaced + register: result + cisco.nxos.nxos_hsrp_interfaces: &id001 + config: + - name: "{{ test_int1 }}" + bfd: "{{ bfd_disable|default(omit)}}" + state: replaced + + - ansible.builtin.assert: + that: + - result.changed == true + - "'no hsrp bfd' in result.commands" + msg: "Assert failed. 'result.commands': {{ result.commands }}" + + - name: Idempotence - replaced + register: result + cisco.nxos.nxos_hsrp_interfaces: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/vars/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/vars/main.yml new file mode 100644 index 00000000..1a741272 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_hsrp_interfaces/vars/main.yml @@ -0,0 +1,18 @@ +--- +gathered: + - name: "{{ nxos_int1 }}" + bfd: enable + - name: "{{ nxos_int2 }}" + bfd: enable + +parsed: + - name: Ethernet1/800 + bfd: enable + - name: Ethernet1/801 + bfd: enable + +rendered: + - "interface Ethernet1/800" + - "hsrp bfd" + - "interface Ethernet1/801" + - "hsrp bfd" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp/tests/common/sanity.yaml new file mode 100644 index 00000000..7c8704ae --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp/tests/common/sanity.yaml @@ -0,0 +1,70 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_igmp sanity test + +- name: Set a fact for 'restart' + ansible.builtin.set_fact: + restart: true + when: platform is not match("N35") + +- block: + - name: Configure IGMP with non-default values + register: result + cisco.nxos.nxos_igmp: &id001 + flush_routes: true + enforce_rtr_alert: true + restart: false + state: present + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Check idempotence - configure IGMP interface with non-default values + register: result + cisco.nxos.nxos_igmp: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Configure IGMP defaults + register: result + cisco.nxos.nxos_igmp: &id003 + flush_routes: false + enforce_rtr_alert: false + restart: "{{restart|default(omit)}}" + state: present + + - ansible.builtin.assert: *id002 + + - name: Check idempotence - configure IGMP with defaults + register: result + cisco.nxos.nxos_igmp: *id003 + + - ansible.builtin.assert: *id004 + + - name: Configure IGMP non-defaults again + register: result + cisco.nxos.nxos_igmp: *id001 + + - name: Configure IGMP state as values + register: result + cisco.nxos.nxos_igmp: &id005 + state: default + + - ansible.builtin.assert: *id002 + + - name: Check idempotence - configure IGMP with state default + register: result + cisco.nxos.nxos_igmp: *id005 + + - ansible.builtin.assert: *id004 + always: + - name: Configure IGMP with default values + register: result + ignore_errors: true + cisco.nxos.nxos_igmp: *id005 + + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_igmp sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_interface/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_interface/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_interface/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_interface/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_interface/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_interface/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_interface/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_interface/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_interface/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_interface/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_interface/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_interface/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_interface/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_interface/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_interface/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_interface/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_interface/tests/common/sanity.yaml new file mode 100644 index 00000000..56b658af --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_interface/tests/common/sanity.yaml @@ -0,0 +1,185 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_igmp_interface sanity test + +- name: Set a fact for 'intname' + ansible.builtin.set_fact: + intname: "{{ nxos_int1 }}" + +- name: Set a fact for 'restart' + ansible.builtin.set_fact: + restart: true + when: platform is not match("N35") + +- name: Enable 'feature pim' + ignore_errors: true + cisco.nxos.nxos_feature: + feature: pim + state: enabled + +- name: Put interface in default mode + ignore_errors: true + cisco.nxos.nxos_config: + commands: + - default interface {{ intname }} + match: none + +- block: + - name: Put interface in layer 3 and enable PIM + cisco.nxos.nxos_config: + commands: + - no switchport + - ip pim sparse-mode + parents: + - interface {{ intname }} + match: none + + - name: Configure IGMP interface with non-default values + register: result + cisco.nxos.nxos_igmp_interface: &id001 + interface: "{{ intname }}" + version: 3 + startup_query_interval: 60 + startup_query_count: 5 + robustness: 6 + querier_timeout: 2000 + query_mrt: 12 + query_interval: 200 + last_member_qrt: 2 + last_member_query_count: 4 + report_llg: true + immediate_leave: true + group_timeout: 300 + oif_ps: + - source: 192.0.2.1 + prefix: 239.255.255.2 + state: present + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Check idempotence - configure IGMP interface with non-default values + register: result + cisco.nxos.nxos_igmp_interface: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Configure IGMP interface with some default values + register: result + cisco.nxos.nxos_igmp_interface: &id003 + interface: "{{ intname }}" + version: default + startup_query_interval: default + startup_query_count: default + robustness: default + querier_timeout: default + query_mrt: default + query_interval: default + last_member_qrt: default + last_member_query_count: default + group_timeout: default + oif_ps: + - prefix: 238.2.2.6 + + - prefix: 238.2.2.5 + + - source: 192.0.2.1 + prefix: 238.2.2.5 + state: present + + - ansible.builtin.assert: *id002 + + - name: Check idempotence - configure IGMP interface with some default values + register: result + cisco.nxos.nxos_igmp_interface: *id003 + + - ansible.builtin.assert: *id004 + + - name: Restart IGMP + cisco.nxos.nxos_igmp_interface: + interface: "{{ intname }}" + restart: "{{restart|default(omit)}}" + + - name: Configure IGMP interface with default oif_ps + register: result + cisco.nxos.nxos_igmp_interface: &id005 + interface: "{{ intname }}" + oif_ps: default + state: present + + - ansible.builtin.assert: *id002 + + - name: Check idempotence - configure IGMP interface with default oif_ps + register: result + cisco.nxos.nxos_igmp_interface: *id005 + + - ansible.builtin.assert: *id004 + + - name: Configure IGMP interface with oif_routemap + register: result + cisco.nxos.nxos_igmp_interface: &id006 + interface: "{{ intname }}" + version: 3 + startup_query_interval: 60 + startup_query_count: 5 + robustness: 6 + oif_routemap: abcd + state: present + + - ansible.builtin.assert: *id002 + + - name: Check idempotence - configure IGMP interface with oif_routemap + register: result + cisco.nxos.nxos_igmp_interface: *id006 + + - ansible.builtin.assert: *id004 + + - name: Configure IGMP interface with default state + register: result + cisco.nxos.nxos_igmp_interface: &id007 + interface: "{{ intname }}" + state: default + + - ansible.builtin.assert: *id002 + + - name: Check idempotence - configure IGMP interface with default state + register: result + cisco.nxos.nxos_igmp_interface: *id007 + + - ansible.builtin.assert: *id004 + + - name: Configure IGMP interface with absent state + register: result + cisco.nxos.nxos_igmp_interface: &id008 + interface: "{{ intname }}" + state: absent + + - ansible.builtin.assert: *id002 + + - name: Check idempotence - configure IGMP interface with absent state + register: result + cisco.nxos.nxos_igmp_interface: *id008 + + - ansible.builtin.assert: *id004 + always: + - name: Configure IGMP interface with absent state + register: result + cisco.nxos.nxos_igmp_interface: *id008 + + - name: Put interface in default mode + cisco.nxos.nxos_config: + commands: + - default interface {{ intname }} + match: none + + - name: Disable 'feature pim' + ignore_errors: true + cisco.nxos.nxos_feature: + feature: pim + state: disabled + + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_igmp_interface sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_snooping/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_snooping/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_snooping/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_snooping/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_snooping/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_snooping/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_snooping/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_snooping/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_snooping/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_snooping/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_snooping/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_snooping/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_snooping/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_snooping/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_snooping/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_snooping/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_snooping/tests/common/sanity.yaml new file mode 100644 index 00000000..e57fc978 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_igmp_snooping/tests/common/sanity.yaml @@ -0,0 +1,120 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_igmp_snooping sanity test + +- ansible.builtin.meta: end_host + when: platform is search('N6K') + +- name: Set a fact for 'gt_run' + ansible.builtin.set_fact: + gt_run: false + +- block: + - name: Set a fact for 'gt_run' + ansible.builtin.set_fact: + gt_run: true + + - name: Set a fact for 'group_timeout' + ansible.builtin.set_fact: + group_timeout: never + + - name: Set a fact for 'def_group_timeout' + ansible.builtin.set_fact: + def_group_timeout: default + when: platform is not search('N35|N5K|N6K') + +- name: Setup + cisco.nxos.nxos_igmp_snooping: &id006 + state: default + +- block: + - name: Configure IGMP snooping with non-default values + register: result + cisco.nxos.nxos_igmp_snooping: &id001 + snooping: false + link_local_grp_supp: false + report_supp: false + v3_report_supp: true + state: present + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - block: + - name: Check Idempotence - Configure igmp snooping with non-default values + register: result + cisco.nxos.nxos_igmp_snooping: *id001 + + - assert: &id004 + that: + - result.changed == false + when: (imagetag and imagetag is not search("D1")) + + - block: + - name: Negative Test config group-timeout when igmp snooping disabled + ignore_errors: true + register: result + cisco.nxos.nxos_igmp_snooping: + snooping: false + group_timeout: "{{group_timeout|default(omit)}}" + state: present + + - assert: + that: + - result.failed == true + - result.msg == 'group-timeout cannot be enabled or changed when ip igmp snooping is disabled' + + - name: Configure group-timeout non-default + register: result + cisco.nxos.nxos_igmp_snooping: &id003 + snooping: true + group_timeout: "{{group_timeout|default(omit)}}" + state: present + + - assert: *id002 + + - name: Check Idempotence + register: result + cisco.nxos.nxos_igmp_snooping: *id003 + + - assert: *id004 + when: gt_run + + - name: Configure IGMP snooping with default group timeout + register: result + cisco.nxos.nxos_igmp_snooping: &id005 + group_timeout: "{{def_group_timeout|default(omit)}}" + state: present + + - ansible.builtin.assert: *id002 + when: gt_run + + - block: + - name: Check Idempotence + register: result + cisco.nxos.nxos_igmp_snooping: *id005 + + - assert: *id004 + when: (imagetag and imagetag is not search("D1")) + + - name: Configure IGMP snooping with default values + register: result + cisco.nxos.nxos_igmp_snooping: *id006 + + - ansible.builtin.assert: *id002 + + - block: + - name: Check Idempotence - Configure igmp snooping with default values + register: result + cisco.nxos.nxos_igmp_snooping: *id006 + + - assert: *id004 + when: (imagetag and imagetag is not search("D1")) + always: + - name: Configure IGMP snooping with default values + register: result + cisco.nxos.nxos_igmp_snooping: *id006 + + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_igmp_snooping sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/defaults/main.yaml new file mode 100644 index 00000000..a5a07901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "" +test_items: [] diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/meta/main.yml new file mode 100644 index 00000000..7f867d73 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/meta/main.yml @@ -0,0 +1,2 @@ +--- +dependencies: diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tasks/httpapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tasks/httpapi.yaml new file mode 100644 index 00000000..555aa835 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tasks/httpapi.yaml @@ -0,0 +1,20 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (ansible_connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tasks/main.yaml new file mode 100644 index 00000000..30b50a39 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tasks/main.yaml @@ -0,0 +1,8 @@ +--- +- name: Run network_cli tests + ansible.builtin.include_tasks: network_cli.yaml + when: ansible_connection == 'ansible.netcommon.network_cli' + +- name: Run httpapi tests + ansible.builtin.include_tasks: httpapi.yaml + when: ansible_connection == 'ansible.netcommon.httpapi' diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tasks/network_cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tasks/network_cli.yaml new file mode 100644 index 00000000..47674535 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tasks/network_cli.yaml @@ -0,0 +1,20 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (ansible_connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tasks/upgrade/clear_persistent_sockets.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tasks/upgrade/clear_persistent_sockets.yaml new file mode 100644 index 00000000..9cb4efc3 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tasks/upgrade/clear_persistent_sockets.yaml @@ -0,0 +1,17 @@ +--- +- name: Clean up sockets with file module + ansible.builtin.file: + state: absent + path: "{{ home }}/.ansible/pc/" + delegate_to: 127.0.0.1 + +- name: Display socket info after delete + ansible.builtin.shell: /bin/ls {{ home }}/.ansible # noqa command-instead-of-shell no-changed-when + args: + executable: /bin/bash + delegate_to: 127.0.0.1 + register: output + +- name: Debug output the local socket information + ansible.builtin.debug: + msg: Local Socket Info {{ output['stdout_lines'] }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tasks/upgrade/copy_kick_system_images.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tasks/upgrade/copy_kick_system_images.yaml new file mode 100644 index 00000000..0ee795a8 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tasks/upgrade/copy_kick_system_images.yaml @@ -0,0 +1,49 @@ +--- +- name: Set a fact for 'ignore_errors_httpapi' + ansible.builtin.set_fact: + ignore_errors_httpapi: false + +- name: Set a fact for 'ignore_errors_httpapi' + ansible.builtin.set_fact: + ignore_errors_httpapi: true + when: ansible_connection == 'ansible.netcommon.httpapi' + +- name: Enable SCP server + ansible.builtin.include_tasks: enable_scp_server.yaml + +- name: Remove SSH known_hosts file before scp of image file + ignore_errors: true # noqa ignore-errors + cisco.nxos.nxos_command: + commands: run bash rm /var/home/admin/.ssh/known_hosts + +- name: Copy file to bootflash {{ si }} + register: result + cisco.nxos.nxos_file_copy: + file_pull: true + file_pull_timeout: 1200 + remote_file: "{{ image_dir }}{{ si }}" + remote_scp_server: "{{ remote_scp_server }}" + remote_scp_server_user: "{{ remote_scp_user }}" + remote_scp_server_password: "{{ remote_scp_password }}" + +- name: Debug output the result from the image copy + ansible.builtin.debug: + msg: "{{ item.key }} {{ item.value }}" + with_dict: "{{ result }}" + +- name: Copy file to bootflash {{ ki }} + when: ki is defined + register: result + cisco.nxos.nxos_file_copy: + file_pull: true + file_pull_timeout: 1200 + remote_file: "{{ image_dir }}{{ ki }}" + remote_scp_server: "{{ remote_scp_server }}" + remote_scp_server_user: "{{ remote_scp_user }}" + remote_scp_server_password: "{{ remote_scp_password }}" + +- name: Debug out the result from the image copy + ansible.builtin.debug: + msg: "{{ item.key }} {{ item.value }}" + with_dict: "{{ result }}" + when: ki is defined diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tasks/upgrade/delete_files.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tasks/upgrade/delete_files.yaml new file mode 100644 index 00000000..d382c3c0 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tasks/upgrade/delete_files.yaml @@ -0,0 +1,10 @@ +--- +- name: Delete files to make room on bootflash + ignore_errors: true # noqa ignore-errors + with_items: "{{ delete_image_list }}" + cisco.nxos.nxos_config: + lines: + - terminal dont-ask + - allow delete boot-image + - delete {{ item }} + match: none diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tasks/upgrade/enable_scp_server.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tasks/upgrade/enable_scp_server.yaml new file mode 100644 index 00000000..c429f33a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tasks/upgrade/enable_scp_server.yaml @@ -0,0 +1,5 @@ +--- +- name: Setup - turn on 'feature scp-server' + cisco.nxos.nxos_feature: + feature: scp-server + state: enabled diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tasks/upgrade/install_os.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tasks/upgrade/install_os.yaml new file mode 100644 index 00000000..e348d1e2 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tasks/upgrade/install_os.yaml @@ -0,0 +1,31 @@ +--- +- name: Run delete files tasks + ansible.builtin.include_tasks: delete_files.yaml + when: delete_files + +- name: Copy Kick System images + ansible.builtin.include_tasks: copy_kick_system_images.yaml + vars: + ansible_connection: ansible.netcommon.network_cli connection={{ cli }} + when: copy_images + +- name: Run install with kick tests + ansible.builtin.include_tasks: install_with_kick.yaml + when: ki is defined + +- name: Run install system + ansible.builtin.include_tasks: install_system.yaml + when: ki is undefined + +- name: Reset the connection + ansible.builtin.meta: reset_connection + +- name: Check installed OS for newly installed version {{ tv }} + register: output + cisco.nxos.nxos_command: + commands: + - show version | json + +- name: Debug output the version detected + ansible.builtin.debug: + msg: Version detected {{ output['stdout_lines'][0]['kickstart_ver_str'] }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tasks/upgrade/install_system.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tasks/upgrade/install_system.yaml new file mode 100644 index 00000000..fcc40387 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tasks/upgrade/install_system.yaml @@ -0,0 +1,58 @@ +--- +- name: Install OS image {{ si }} + check_mode: "{{ checkmode }}" + register: result + when: not force + cisco.nxos.nxos_install_os: + system_image_file: "{{ si }}" + issu: "{{ issu }}" + +- name: Remove old boot pointers if any + ignore_errors: true # noqa ignore-errors + when: force + cisco.nxos.nxos_config: + lines: + - no boot nxos + - no boot kickstart + - no boot system + match: line + +- name: "Set OS image boot pointers: {{ si }}" + when: force + cisco.nxos.nxos_config: + lines: + - boot nxos bootflash:{{ si }} + - copy run start + match: line + +- name: "Boot image using reload: {{ si }}" + ignore_errors: true # noqa ignore-errors + when: force + cisco.nxos.nxos_config: + lines: + - terminal dont-ask + - reload + +- name: Debug output the result from the image installation + ansible.builtin.debug: + msg: " {{ result['install_state'] }}" + when: not force + +- name: Wait for device to come back up with new image + ansible.builtin.wait_for: + port: 22 + state: started + timeout: 500 + delay: 60 + host: "{{ inventory_hostname }}" + when: result.changed and not checkmode + +- name: Debug output a warning about the 5 minute wait + ansible.builtin.debug: + msg: Wait 5 mins to allow system to stabilize + when: result.changed and not checkmode + +- name: Wait for device to come back up with new image + ansible.builtin.pause: + seconds: 300 + when: result.changed and not checkmode diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tasks/upgrade/install_with_kick.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tasks/upgrade/install_with_kick.yaml new file mode 100644 index 00000000..3a5af124 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tasks/upgrade/install_with_kick.yaml @@ -0,0 +1,50 @@ +--- +- name: Install OS image {{ si }} + check_mode: "{{ checkmode }}" + register: result + when: not force + cisco.nxos.nxos_install_os: + system_image_file: "{{ si }}" + kickstart_image_file: "{{ ki }}" + issu: "{{ issu }}" + +- name: Set boot pointers for OS image {{ si }} + when: force + cisco.nxos.nxos_config: + lines: + - no boot kickstart + - no boot system + - boot kickstart bootflash:{{ ki }} + - boot system bootflash:{{ si }} + - copy run start + match: line + +- name: "Boot image using reload {{ si }}" + ignore_errors: true # noqa ignore-errors + when: force + cisco.nxos.nxos_command: + commands: terminal dont-ask ; reload + +- name: Debug output the result from the image installation + ansible.builtin.debug: + msg: " {{ result['install_state'] }}" + when: not force + +- name: Wait for device to come back up with new image + ansible.builtin.wait_for: + port: 22 + state: started + timeout: 500 + delay: 60 + host: "{{ inventory_hostname }}" + when: result.changed and not checkmode + +- name: Debug output a warning about the 5 minute wait + ansible.builtin.debug: + msg: Wait 5 mins to allow system to stabilize + when: result.changed and not checkmode + +- name: Wait for device to come back up with new image + ansible.builtin.pause: + seconds: 300 + when: result.changed and not checkmode diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tasks/upgrade/main_os_install.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tasks/upgrade/main_os_install.yaml new file mode 100644 index 00000000..acbf45a5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tasks/upgrade/main_os_install.yaml @@ -0,0 +1,10 @@ +--- +- name: Debug output a warning about meta endplay + ansible.builtin.debug: + msg: "***WARNING*** Remove meta end_play to verify this module ***WARNING***" + +- name: End the play + ansible.builtin.meta: end_play + +- name: Run Install OS + ansible.builtin.include_tasks: install_os.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade.yaml new file mode 100644 index 00000000..e4f02dd8 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade.yaml @@ -0,0 +1,77 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_os_install upgrade + when: connection is defined + +- name: Set a fact for 'image_dir' + ansible.builtin.set_fact: + image_dir: /Users/mwiebe/Projects/nxos_ansible/images/ + +- name: Set a fact for 'checkmode' + ansible.builtin.set_fact: + checkmode: false + +- name: Set a fact for 'issu' + ansible.builtin.set_fact: + issu: desired + +- name: Set a fact for 'copy_images' + ansible.builtin.set_fact: + copy_images: true + +- name: Set a fact for 'force' + ansible.builtin.set_fact: + force: false + +- name: Set a fact for 'delete_files' + ansible.builtin.set_fact: + delete_files: true + +- name: Set a fact for 'delete_image_list' + ansible.builtin.set_fact: + delete_image_list: + - nxos.7.0.3.I7.2.bin + - nxos.7.0.3.I7.3.bin + +- name: Set a fact for 'si' + ansible.builtin.set_fact: + si: n3000-uk9.6.0.2.U6.1a.bin + +- name: Set a fact for 'ki' + ansible.builtin.set_fact: + ki: n3000-uk9-kickstart.6.0.2.U6.1a.bin + +- name: Upgrade to u6.1a + ansible.builtin.include_tasks: targets/nxos_install_os/tasks/upgrade/main_os_install.yaml + +- name: Set a fact for 'si' + ansible.builtin.set_fact: + si: n3000-uk9.6.0.2.U6.2a.bin + +- name: Set a fact for 'ki' + ansible.builtin.set_fact: + ki: n3000-uk9-kickstart.6.0.2.U6.2a.bin + +- name: Upgrade to u6.2a + ansible.builtin.include_tasks: targets/nxos_install_os/tasks/upgrade/main_os_install.yaml + +- name: Set a fact for 'si' + ansible.builtin.set_fact: + si: n3000-s2-dk9.8.0.1.bin + +- name: Set a fact for 'ki' + ansible.builtin.set_fact: + ki: n3000-s2-kickstart.8.0.1.bin + +- name: Upgrade to u6.3a + ansible.builtin.include_tasks: targets/nxos_install_os/tasks/upgrade/main_os_install.yaml + +- name: Set a fact for 'si' + ansible.builtin.set_fact: + si: nxos.7.0.3.I7.2.bin + +- name: Upgrade to 7.0.3.i7.2 + ansible.builtin.include_tasks: targets/nxos_install_os/tasks/upgrade/main_os_install.yaml + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_os_install upgrade diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n3172_greensboro.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n3172_greensboro.yaml new file mode 100644 index 00000000..15c6748b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n3172_greensboro.yaml @@ -0,0 +1,41 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_os_install upgrade + when: connection is defined + +- name: Set a fact for 'image_dir' + ansible.builtin.set_fact: + image_dir: /auto/fe_ssr/agents-ci/agents_images/release_images/greensboro/REL_7_0_3_I7_4/ + +- name: Set a fact for 'checkmode' + ansible.builtin.set_fact: + checkmode: false + +- name: Set a fact for 'issu' + ansible.builtin.set_fact: + issu: false + +- name: Set a fact for 'copy_images' + ansible.builtin.set_fact: + copy_images: true + +- name: Set a fact for 'force' + ansible.builtin.set_fact: + force: false + +- name: Set a fact for 'delete_files' + ansible.builtin.set_fact: + delete_files: true + +- name: Set a fact for 'delete_image_list' + ansible.builtin.set_fact: + delete_image_list: + - nxos*.bin + - n3000*.bin + +- name: Set a fact for 'si' + ansible.builtin.set_fact: + si: nxos.7.0.3.I7.4.bin + +- name: Upgrade n3172 device to greensboro release image + ansible.builtin.include_tasks: targets/nxos_install_os/tasks/upgrade/main_os_install.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n3172_u61a.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n3172_u61a.yaml new file mode 100644 index 00000000..b32be6e3 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n3172_u61a.yaml @@ -0,0 +1,45 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_os_install upgrade + when: connection is defined + +- name: Set a fact for 'image_dir' + ansible.builtin.set_fact: + image_dir: /auto/fe_ssr/agents-ci/agents_images/release_images/602U6_1/ + +- name: Set a fact for 'checkmode' + ansible.builtin.set_fact: + checkmode: false + +- name: Set a fact for 'issu' + ansible.builtin.set_fact: + issu: desired + +- name: Set a fact for 'copy_images' + ansible.builtin.set_fact: + copy_images: true + +- name: Set a fact for 'force' + ansible.builtin.set_fact: + force: false + +- name: Set a fact for 'delete_files' + ansible.builtin.set_fact: + delete_files: true + +- name: Set a fact for 'delete_image_list' + ansible.builtin.set_fact: + delete_image_list: + - n3000*.bin + - nxos*.bin + +- name: Set a fact for 'si' + ansible.builtin.set_fact: + si: n3000-uk9.6.0.2.U6.1a.bin + +- name: Set a fact for 'ki' + ansible.builtin.set_fact: + ki: n3000-uk9-kickstart.6.0.2.U6.1a.bin + +- name: Upgrade n3500 device to u61a release image + ansible.builtin.include_tasks: targets/nxos_install_os/tasks/upgrade/main_os_install.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n3172_u62a.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n3172_u62a.yaml new file mode 100644 index 00000000..3db45b71 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n3172_u62a.yaml @@ -0,0 +1,45 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_os_install upgrade + when: connection is defined + +- name: Set a fact for 'image_dir' + ansible.builtin.set_fact: + image_dir: /auto/fe_ssr/agents-ci/agents_images/release_images/602U6_2/ + +- name: Set a fact for 'checkmode' + ansible.builtin.set_fact: + checkmode: false + +- name: Set a fact for 'issu' + ansible.builtin.set_fact: + issu: false + +- name: Set a fact for 'copy_images' + ansible.builtin.set_fact: + copy_images: true + +- name: Set a fact for 'force' + ansible.builtin.set_fact: + force: false + +- name: Set a fact for 'delete_files' + ansible.builtin.set_fact: + delete_files: true + +- name: Set a fact for 'delete_image_list' + ansible.builtin.set_fact: + delete_image_list: + - n3000*.bin + - nxos*.bin + +- name: Set a fact for 'si' + ansible.builtin.set_fact: + si: n3000-uk9.6.0.2.U6.2a.bin + +- name: Set a fact for 'ki' + ansible.builtin.set_fact: + ki: n3000-uk9-kickstart.6.0.2.U6.2a.bin + +- name: Upgrade n3500 device to u62a release image + ansible.builtin.include_tasks: targets/nxos_install_os/tasks/upgrade/main_os_install.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n3172_u63a.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n3172_u63a.yaml new file mode 100644 index 00000000..12c246fd --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n3172_u63a.yaml @@ -0,0 +1,45 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_os_install upgrade + when: connection is defined + +- name: Set a fact for 'image_dir' + ansible.builtin.set_fact: + image_dir: /auto/fe_ssr/agents-ci/agents_images/release_images/602U6_3/ + +- name: Set a fact for 'checkmode' + ansible.builtin.set_fact: + checkmode: false + +- name: Set a fact for 'issu' + ansible.builtin.set_fact: + issu: desired + +- name: Set a fact for 'copy_images' + ansible.builtin.set_fact: + copy_images: true + +- name: Set a fact for 'force' + ansible.builtin.set_fact: + force: false + +- name: Set a fact for 'delete_files' + ansible.builtin.set_fact: + delete_files: true + +- name: Set a fact for 'delete_image_list' + ansible.builtin.set_fact: + delete_image_list: + - n3000*.bin + - nxos*.bin + +- name: Set a fact for 'si' + ansible.builtin.set_fact: + si: n3000-uk9.6.0.2.U6.3a.bin + +- name: Set a fact for 'ki' + ansible.builtin.set_fact: + ki: n3000-uk9-kickstart.6.0.2.U6.3a.bin + +- name: Upgrade n3500 device to u63a release image + ansible.builtin.include_tasks: targets/nxos_install_os/tasks/upgrade/main_os_install.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n35_62a88.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n35_62a88.yaml new file mode 100644 index 00000000..7ee9f0c6 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n35_62a88.yaml @@ -0,0 +1,45 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_os_install upgrade + when: connection is defined + +- name: Set a fact for 'image_dir' + ansible.builtin.set_fact: + image_dir: /auto/fe_ssr/agents-ci/agents_images/release_images/602A8_8/ + +- name: Set a fact for 'checkmode' + ansible.builtin.set_fact: + checkmode: false + +- name: Set a fact for 'issu' + ansible.builtin.set_fact: + issu: desired + +- name: Set a fact for 'copy_images' + ansible.builtin.set_fact: + copy_images: true + +- name: Set a fact for 'force' + ansible.builtin.set_fact: + force: false + +- name: Set a fact for 'delete_files' + ansible.builtin.set_fact: + delete_files: true + +- name: Set a fact for 'delete_image_list' + ansible.builtin.set_fact: + delete_image_list: + - n3000*.bin + - n3500*.bin + +- name: Set a fact for 'si' + ansible.builtin.set_fact: + si: n3500-uk9.6.0.2.A8.8.bin + +- name: Set a fact for 'ki' + ansible.builtin.set_fact: + ki: n3500-uk9-kickstart.6.0.2.A8.8.bin + +- name: Upgrade n3500 device to a8_8 release image + ansible.builtin.include_tasks: targets/nxos_install_os/tasks/upgrade/main_os_install.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n35_greensboro.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n35_greensboro.yaml new file mode 100644 index 00000000..4b997c8b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n35_greensboro.yaml @@ -0,0 +1,41 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_os_install upgrade + when: connection is defined + +- name: Set a fact for 'image_dir' + ansible.builtin.set_fact: + image_dir: /auto/fe_ssr/agents-ci/agents_images/release_images/greensboro/REL_7_0_3_I7_4/ + +- name: Set a fact for 'checkmode' + ansible.builtin.set_fact: + checkmode: false + +- name: Set a fact for 'issu' + ansible.builtin.set_fact: + issu: desired + +- name: Set a fact for 'copy_images' + ansible.builtin.set_fact: + copy_images: false + +- name: Set a fact for 'force' + ansible.builtin.set_fact: + force: false + +- name: Set a fact for 'delete_files' + ansible.builtin.set_fact: + delete_files: false + +- name: Set a fact for 'delete_image_list' + ansible.builtin.set_fact: + delete_image_list: + - nxos*.bin + - n3500*.bin + +- name: Set a fact for 'si' + ansible.builtin.set_fact: + si: nxos.7.0.3.I7.4.bin + +- name: Upgrade n3500 device to greensboro release image + ansible.builtin.include_tasks: targets/nxos_install_os/tasks/upgrade/main_os_install.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n5k_730_N11.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n5k_730_N11.yaml new file mode 100644 index 00000000..b7405ec2 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n5k_730_N11.yaml @@ -0,0 +1,44 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_os_install upgrade + when: connection is defined + +- name: Set a fact for 'image_dir' + ansible.builtin.set_fact: + image_dir: /auto/fe_ssr/agents-ci/agents_images/release_images/730_N11/ + +- name: Set a fact for 'checkmode' + ansible.builtin.set_fact: + checkmode: false + +- name: Set a fact for 'issu' + ansible.builtin.set_fact: + issu: false + +- name: Set a fact for 'copy_images' + ansible.builtin.set_fact: + copy_images: true + +- name: Set a fact for 'force' + ansible.builtin.set_fact: + force: false + +- name: Set a fact for 'delete_files' + ansible.builtin.set_fact: + delete_files: true + +- name: Set a fact for 'delete_image_list' + ansible.builtin.set_fact: + delete_image_list: + - n6000*.bin + +- name: Set a fact for 'si' + ansible.builtin.set_fact: + si: n6000-uk9.7.3.0.N1.1.bin + +- name: Set a fact for 'ki' + ansible.builtin.set_fact: + ki: n6000-uk9-kickstart.7.3.0.N1.1.bin + +- name: Upgrade N5K device to 7.3(0)n1(1) release image + ansible.builtin.include_tasks: targets/nxos_install_os/tasks/upgrade/main_os_install.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n5k_733_N11.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n5k_733_N11.yaml new file mode 100644 index 00000000..03e27f52 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n5k_733_N11.yaml @@ -0,0 +1,44 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_os_install upgrade + when: connection is defined + +- name: Set a fact for 'image_dir' + ansible.builtin.set_fact: + image_dir: /auto/fe_ssr/agents-ci/agents_images/release_images/733_N11/ + +- name: Set a fact for 'checkmode' + ansible.builtin.set_fact: + checkmode: false + +- name: Set a fact for 'issu' + ansible.builtin.set_fact: + issu: false + +- name: Set a fact for 'copy_images' + ansible.builtin.set_fact: + copy_images: false + +- name: Set a fact for 'force' + ansible.builtin.set_fact: + force: false + +- name: Set a fact for 'delete_files' + ansible.builtin.set_fact: + delete_files: false + +- name: Set a fact for 'delete_image_list' + ansible.builtin.set_fact: + delete_image_list: + - n6000*.bin + +- name: Set a fact for 'si' + ansible.builtin.set_fact: + si: n6000-uk9.7.3.3.N1.1.bin + +- name: Set a fact for 'ki' + ansible.builtin.set_fact: + ki: n6000-uk9-kickstart.7.3.3.N1.1.bin + +- name: Upgrade N5K device to 7.3(3)n1(1) release image + ansible.builtin.include_tasks: targets/nxos_install_os/tasks/upgrade/main_os_install.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n7k_atherton.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n7k_atherton.yaml new file mode 100644 index 00000000..62507228 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n7k_atherton.yaml @@ -0,0 +1,44 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_os_install upgrade + when: connection is defined + +- name: Set a fact for 'image_dir' + ansible.builtin.set_fact: + image_dir: /auto/fe_ssr/agents-ci/agents_images/release_images/atherton/REL_8_0_1/ + +- name: Set a fact for 'checkmode' + ansible.builtin.set_fact: + checkmode: false + +- name: Set a fact for 'issu' + ansible.builtin.set_fact: + issu: false + +- name: Set a fact for 'copy_images' + ansible.builtin.set_fact: + copy_images: true + +- name: Set a fact for 'force' + ansible.builtin.set_fact: + force: false + +- name: Set a fact for 'delete_files' + ansible.builtin.set_fact: + delete_files: true + +- name: Set a fact for 'delete_image_list' + ansible.builtin.set_fact: + delete_image_list: + - n7000*.bin + +- name: Set a fact for 'si' + ansible.builtin.set_fact: + si: n7000-s2-dk9.8.0.1.bin + +- name: Set a fact for 'ki' + ansible.builtin.set_fact: + ki: n7000-s2-kickstart.8.0.1.bin + +- name: Upgrade N7K device to atherton release image + ansible.builtin.include_tasks: targets/nxos_install_os/tasks/upgrade/main_os_install.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n7k_helsinki.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n7k_helsinki.yaml new file mode 100644 index 00000000..b8660ea1 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n7k_helsinki.yaml @@ -0,0 +1,44 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_os_install upgrade + when: connection is defined + +- name: Set a fact for 'image_dir' + ansible.builtin.set_fact: + image_dir: /auto/fe_ssr/agents-ci/agents_images/release_images/helsinki/REL_7_3_0_D1_1/ + +- name: Set a fact for 'checkmode' + ansible.builtin.set_fact: + checkmode: false + +- name: Set a fact for 'issu' + ansible.builtin.set_fact: + issu: false + +- name: Set a fact for 'copy_images' + ansible.builtin.set_fact: + copy_images: true + +- name: Set a fact for 'force' + ansible.builtin.set_fact: + force: true + +- name: Set a fact for 'delete_files' + ansible.builtin.set_fact: + delete_files: true + +- name: Set a fact for 'delete_image_list' + ansible.builtin.set_fact: + delete_image_list: + - n7000*.bin + +- name: Set a fact for 'si' + ansible.builtin.set_fact: + si: n7000-s2-dk9.7.3.0.D1.1.bin + +- name: Set a fact for 'ki' + ansible.builtin.set_fact: + ki: n7000-s2-kickstart.7.3.0.D1.1.bin + +- name: Upgrade N7K device to helsinki release image + ansible.builtin.include_tasks: targets/nxos_install_os/tasks/upgrade/main_os_install.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n9k_greensboro.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n9k_greensboro.yaml new file mode 100644 index 00000000..3da1fe5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n9k_greensboro.yaml @@ -0,0 +1,50 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_os_install upgrade + when: connection is defined + +- name: Set a fact for 'image_dir' + ansible.builtin.set_fact: + image_dir: /auto/fe_ssr/agents-ci/agents_images/release_images/greensboro/REL_7_0_3_I7_4/ + +- name: Set a fact for 'checkmode' + ansible.builtin.set_fact: + checkmode: false + +- name: Set a fact for 'issu' + ansible.builtin.set_fact: + issu: desired + +- name: Set a fact for 'copy_images' + ansible.builtin.set_fact: + copy_images: true + +- name: Set a fact for 'force' + ansible.builtin.set_fact: + force: false + +- name: Set a fact for 'delete_files' + ansible.builtin.set_fact: + delete_files: true + +- name: Set a fact for 'delete_image_list' + ansible.builtin.set_fact: + delete_image_list: + - nxos*.bin + +- name: Unconfigure features that will conflict with upgrade + ignore_errors: true + cisco.nxos.nxos_config: + lines: + - terminal dont-ask + - no feature nv overlay + - no nxapi ssl protocols + - no nxapi ssl ciphers weak + match: none + +- name: Set a fact for 'si' + ansible.builtin.set_fact: + si: nxos.7.0.3.I7.4.bin + +- name: Upgrade N9K device to greensboro release image + ansible.builtin.include_tasks: targets/nxos_install_os/tasks/upgrade/main_os_install.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n9k_greensboro_force.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n9k_greensboro_force.yaml new file mode 100644 index 00000000..3d8599c9 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n9k_greensboro_force.yaml @@ -0,0 +1,50 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_os_install upgrade + when: connection is defined + +- name: Set a fact for 'image_dir' + ansible.builtin.set_fact: + image_dir: /auto/fe_ssr/agents-ci/agents_images/release_images/greensboro/REL_7_0_3_I7_4/ + +- name: Set a fact for 'checkmode' + ansible.builtin.set_fact: + checkmode: false + +- name: Set a fact for 'issu' + ansible.builtin.set_fact: + issu: desired + +- name: Set a fact for 'copy_images' + ansible.builtin.set_fact: + copy_images: true + +- name: Set a fact for 'force' + ansible.builtin.set_fact: + force: true + +- name: Set a fact for 'delete_files' + ansible.builtin.set_fact: + delete_files: true + +- name: Set a fact for 'delete_image_list' + ansible.builtin.set_fact: + delete_image_list: + - nxos*.bin + +- name: Unconfigure features that will conflict with upgrade + ignore_errors: true + cisco.nxos.nxos_config: + lines: + - terminal dont-ask + - no feature nv overlay + - no nxapi ssl protocols + - no nxapi ssl ciphers weak + match: none + +- name: Set a fact for 'si' + ansible.builtin.set_fact: + si: nxos.7.0.3.I7.4.bin + +- name: Upgrade N9K device to greensboro release image + ansible.builtin.include_tasks: targets/nxos_install_os/tasks/upgrade/main_os_install.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n9k_hamilton.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n9k_hamilton.yaml new file mode 100644 index 00000000..304e2669 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_install_os/tests/common/upgrade_n9k_hamilton.yaml @@ -0,0 +1,48 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_os_install upgrade + when: connection is defined + +- name: Set a fact for 'image_dir' + ansible.builtin.set_fact: + image_dir: /auto/fe_ssr/agents-ci/agents_images/release_images/hamilton/REL_9_2_1/ + +- name: Set a fact for 'checkmode' + ansible.builtin.set_fact: + checkmode: false + +- name: Set a fact for 'issu' + ansible.builtin.set_fact: + issu: desired + +- name: Set a fact for 'copy_images' + ansible.builtin.set_fact: + copy_images: true + +- name: Set a fact for 'force' + ansible.builtin.set_fact: + force: false + +- name: Set a fact for 'delete_files' + ansible.builtin.set_fact: + delete_files: true + +- name: Set a fact for 'delete_image_list' + ansible.builtin.set_fact: + delete_image_list: + - nxos*.bin + +- name: Unconfigure features that will conflict with upgrade + ignore_errors: true + cisco.nxos.nxos_config: + lines: + - terminal dont-ask + - no feature ngmvpn + match: none + +- name: Set a fact for 'si' + ansible.builtin.set_fact: + si: nxos.9.2.1.bin + +- name: Upgrade N9K device to hamilton release image + ansible.builtin.include_tasks: targets/nxos_install_os/tasks/upgrade/main_os_install.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/defaults/main.yaml new file mode 100644 index 00000000..871ea460 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "[^_].*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tasks/cli.yaml new file mode 100644 index 00000000..9e4fb34b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tasks/main.yaml new file mode 100644 index 00000000..926add4d --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tasks/main.yaml @@ -0,0 +1,15 @@ +--- +- name: Set system defaults for switchports + cisco.nxos.nxos_config: + lines: "no system default switchport\nsystem default switchport shutdown\n" + connection: ansible.netcommon.network_cli + +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tasks/nxapi.yaml new file mode 100644 index 00000000..5cb76e67 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/_populate_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/_populate_config.yaml new file mode 100644 index 00000000..15c559f7 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/_populate_config.yaml @@ -0,0 +1,16 @@ +--- +- name: "Populate configuration - {{ nxos_int1 }}" + cisco.nxos.nxos_config: + lines: + - "description outbound-intf" + - "switchport" + - "no shutdown" + parents: "interface {{ nxos_int1 }}" + +- name: "Populate configuration - {{ nxos_int2 }}" + cisco.nxos.nxos_config: + lines: + - "description intf-l3" + - "no switchport" + - "speed 1000" + parents: "interface {{ nxos_int2 }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/_remove_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/_remove_config.yaml new file mode 100644 index 00000000..7ff47cc7 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/_remove_config.yaml @@ -0,0 +1,10 @@ +--- +- name: Remove configuration + cisco.nxos.nxos_config: + lines: + - "default interface {{ nxos_int1 }}" + - "default interface {{ nxos_int2 }}" + - "default interface {{ nxos_int3 }}" + - "no interface loopback1" + - "no interface loopback8" + ignore_errors: true diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/deleted.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/deleted.yaml new file mode 100644 index 00000000..bf7f11b0 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/deleted.yaml @@ -0,0 +1,66 @@ +--- +- ansible.builtin.debug: + msg: "Start nxos_interfaces deleted integration tests connection={{ ansible_connection }}" + +- name: Set a fact for 'test_int1' and 'test_int2' + ansible.builtin.set_fact: + test_int1: "{{ nxos_int1 }}" + test_int2: "{{ nxos_int2 }}" + +- name: Set a fact for 'test_shutdown' + ansible.builtin.set_fact: + test_shutdown: "{{ platform is search('N3[5KL]|N[56]K|titanium') }}" + +- name: "Setup0: clean up (interfaces) attributes on all interfaces" + cisco.nxos.nxos_interfaces: + state: deleted + +- name: Setup1 + cisco.nxos.nxos_config: &id002 + lines: "default interface {{ test_int1 }}" + +- block: + - name: Setup2 + cisco.nxos.nxos_config: + lines: + - "interface {{ test_int1 }}" + - " description Test-interface1" + - " no shutdown" + + - name: Gather interfaces facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: interfaces + + - name: Deleted + register: result + cisco.nxos.nxos_interfaces: &id001 + state: deleted + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.interfaces|symmetric_difference(result.before) == [] + - result.changed == true + - "'interface {{ test_int1 }}' in result.commands" + - "'no description' in result.commands" + + - ansible.builtin.assert: + that: + - result.after|length == 0 + - "'shutdown' in result.commands" + when: test_shutdown + + - name: Idempotence - deleted + register: result + cisco.nxos.nxos_interfaces: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + when: test_shutdown + always: + - name: Teardown + cisco.nxos.nxos_config: *id002 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/empty_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/empty_config.yaml new file mode 100644 index 00000000..2e1311f9 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/empty_config.yaml @@ -0,0 +1,61 @@ +--- +- ansible.builtin.debug: + msg: START nxos_interfaces empty_config integration tests on connection={{ ansible_connection }} + +- name: Merged with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_interfaces: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_interfaces: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Overridden with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_interfaces: + config: + state: overridden + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Rendered with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_interfaces: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' + +- name: Parsed with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_interfaces: + running_config: + state: parsed + +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state parsed' + +- ansible.builtin.debug: + msg: END nxos_interfaces empty_config integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/gathered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/gathered.yaml new file mode 100644 index 00000000..a3ac9d3a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/gathered.yaml @@ -0,0 +1,21 @@ +--- +- ansible.builtin.debug: + msg: START nxos_interfaces gathered integration tests on connection={{ ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Gather interfaces facts from the device using nxos_interfaces + register: result + cisco.nxos.nxos_interfaces: + state: gathered + + - ansible.builtin.assert: + that: "{{ result['gathered'][:2] | symmetric_difference(gathered) |length == 0 }}" + always: + - ansible.builtin.include_tasks: _remove_config.yaml + + - ansible.builtin.debug: + msg: END nxos_interfaces gathered integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/merged.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/merged.yaml new file mode 100644 index 00000000..f880f89c --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/merged.yaml @@ -0,0 +1,89 @@ +--- +- ansible.builtin.debug: + msg: "Start nxos_interfaces merged integration tests connection={{ ansible_connection }}" + +- name: Set a fact for 'test_int1' and 'test_int2' + ansible.builtin.set_fact: + test_int1: "{{ nxos_int1 }}" + test_int2: "{{ nxos_int2 }}" + +- name: Set a fact for 'enabled' + ansible.builtin.set_fact: + enabled: true + when: platform is not search('N3[5KL]|N[56]K|titanium') + +- block: + - name: Setup + cisco.nxos.nxos_config: &id002 + lines: + - "default interface {{ test_int1 }}" + - "default interface {{ test_int2 }}" + + - name: Merged + register: result + cisco.nxos.nxos_interfaces: &id001 + config: + - name: "{{ test_int1 }}" + description: Configured by Ansible + enabled: "{{ enabled|default(omit)}}" + state: merged + + - ansible.builtin.assert: + that: + - result.changed == true + - "'interface {{ test_int1 }}' in result.commands" + - "'description Configured by Ansible' in result.commands" + + - ansible.builtin.assert: + that: + - "'no shutdown' in result.commands" + when: enabled is defined + + - name: Gather interfaces facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: interfaces + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.interfaces|symmetric_difference(result.after)|length == 0 + + - name: Idempotence - merged + register: result + cisco.nxos.nxos_interfaces: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + + - name: "Populate {{ test_int2 }}" + cisco.nxos.nxos_config: + lines: + - "description Test" + - "switchport" + - "no shutdown" + parents: "interface {{ test_int2 }}" + + - name: Update interface state + cisco.nxos.nxos_interfaces: + config: + - name: "{{ test_int2 }}" + enabled: false + mode: layer2 + description: Test + state: merged + register: result + + - ansible.builtin.assert: + that: + - "'interface {{ test_int2 }}' in result.commands" + - "'shutdown' in result.commands" + - result.changed == True + - result.commands|length == 2 + + always: + - name: Teardown + cisco.nxos.nxos_config: *id002 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/overridden.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/overridden.yaml new file mode 100644 index 00000000..61b80ecd --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/overridden.yaml @@ -0,0 +1,67 @@ +--- +- ansible.builtin.debug: + msg: "Start nxos_interfaces overridden integration tests connection={{ ansible_connection }}" + +- name: Set a fact for 'test_int1' and 'test_int2' + ansible.builtin.set_fact: + test_int1: "{{ nxos_int1 }}" + test_int2: "{{ nxos_int2 }}" + +- block: + - name: Setup1 + cisco.nxos.nxos_config: &id003 + lines: + - "default interface {{ test_int1 }}" + - "default interface {{ test_int2 }}" + + - block: + - name: setup2 + cisco.nxos.nxos_config: + lines: + - "interface {{ test_int1 }}" + - " description Test-interface1" + - " no shutdown" + + - name: Gather interfaces facts + cisco.nxos.nxos_facts: &id001 + gather_subset: + - "!all" + - "!min" + gather_network_resources: interfaces + + - name: Overridden + register: result + cisco.nxos.nxos_interfaces: &id002 + config: + - name: "{{ test_int2 }}" + description: Configured by Ansible + state: overridden + + - assert: + that: + - ansible_facts.network_resources.interfaces|symmetric_difference(result.before)|length == 0 + - result.changed == true + - "'interface {{ test_int1 }}' in result.commands" + - "'shutdown' in result.commands" + - "'interface {{ test_int2 }}' in result.commands" + - "'description Configured by Ansible' in result.commands" + + - name: Gather interfaces post facts + cisco.nxos.nxos_facts: *id001 + + - assert: + that: + - ansible_facts.network_resources.interfaces|symmetric_difference(result.after)|length == 0 + + - name: Idempotence - Overridden + register: result + cisco.nxos.nxos_interfaces: *id002 + + - assert: + that: + - result.changed == false + - result.commands|length == 0 + always: + - name: teardown + cisco.nxos.nxos_config: *id003 + when: platform is not search('N3[5KL]|N[56]K|titanium') diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/parsed.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/parsed.yaml new file mode 100644 index 00000000..b228595b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/parsed.yaml @@ -0,0 +1,28 @@ +--- +- ansible.builtin.debug: + msg: START nxos_interfaces parsed integration tests on connection={{ ansible_connection }} + +- block: + # Interfaces used in the task don't actually exist on the appliance + - name: Use parsed state to convert externally supplied configuration to structured format + register: result + cisco.nxos.nxos_interfaces: + running_config: | + interface Ethernet1/800 + description test-1 + speed 1000 + shutdown + no switchport + duplex half + interface Ethernet1/801 + description test-2 + switchport + no shutdown + mtu 1800 + state: parsed + + - ansible.builtin.assert: + that: "{{ parsed | symmetric_difference(result['parsed']) |length==0 }}" + +- ansible.builtin.debug: + msg: END nxos_interfaces parsed integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/purged.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/purged.yaml new file mode 100644 index 00000000..86273ad8 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/purged.yaml @@ -0,0 +1,46 @@ +--- +- ansible.builtin.debug: + msg: "Start nxos_interfaces purged integration tests connection={{ ansible_connection }}" + +- block: + - name: Setup2 + cisco.nxos.nxos_config: + lines: + - "interface {{ nxos_int1 }}.100" + - " description test-sub-interface" + - "interface port-channel10" + - " description test-port-channel-10" + - "interface port-channel11" + - " description test-port-channel-11" + + - name: Purge virtual interfaces from running-config + cisco.nxos.nxos_interfaces: &purged + config: + - name: "{{ nxos_int1 }}.100" + - name: port-channel10 + state: purged + register: result + + - ansible.builtin.assert: + that: + - '"no interface {{ nxos_int1 }}.100" in result.commands' + - '"no interface port-channel10" in result.commands' + - result.commands|length == 2 + - result.changed == True + + - name: Purge virtual interfaces from running-config (idempotent) + cisco.nxos.nxos_interfaces: *purged + register: result + + - ansible.builtin.assert: + that: + - result.changed == False + always: + - name: Teardown + cisco.nxos.nxos_config: + lines: "{{ item }}" + loop: + - "no interface {{ nxos_int1 }}.100" + - "no interface port-channel10" + - "no interface port-channel11" + ignore_errors: true diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/rendered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/rendered.yaml new file mode 100644 index 00000000..911ca405 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/rendered.yaml @@ -0,0 +1,45 @@ +--- +- ansible.builtin.debug: + msg: START nxos_interfaces rendered integration tests on connection={{ ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- name: Gather pre-facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: + - "interfaces" + +- block: + - name: Use rendered state to convert task input to device specific commands + register: result + cisco.nxos.nxos_interfaces: + config: + - name: Ethernet1/1 + description: outbound-intf + mode: layer3 # Sys Default for rendered is assumed to be Layer3 - so no command should be sent + speed: 1000 + - name: Ethernet1/2 + mode: layer2 + enabled: true # Sys Default for rendered is assumed to be disabled - so command should be sent + duplex: full + state: rendered + + - ansible.builtin.assert: + that: "{{ rendered | symmetric_difference(result['rendered']) |length==0 }}" + + - name: Gather interfaces facts from the device and assert that nothing changed + register: result + cisco.nxos.nxos_interfaces: + state: gathered + + - name: Make sure that rendered task actually did not make any changes to the device + ansible.builtin.assert: + that: "{{ result['gathered']|symmetric_difference(ansible_facts.network_resources.interfaces)|length == 0}}" + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: END nxos_interfaces rendered integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/replaced.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/replaced.yaml new file mode 100644 index 00000000..8afe45ba --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/replaced.yaml @@ -0,0 +1,96 @@ +--- +- ansible.builtin.debug: + msg: "Start nxos_interfaces replaced integration tests connection={{ ansible_connection }}" + +- name: Set a fact for 'test_int1' and 'test_int2' + ansible.builtin.set_fact: + test_int1: "{{ nxos_int1 }}" + test_int2: "{{ nxos_int2 }}" + +- block: + - name: Setup1 + cisco.nxos.nxos_config: &id003 + lines: + - "default interface {{ test_int1 }}" + + - block: + - name: setup2 + cisco.nxos.nxos_config: + lines: + - "interface {{ test_int1 }}" + - " description Test-interface1" + + - name: Gather interfaces facts + cisco.nxos.nxos_facts: &id001 + gather_subset: + - "!all" + - "!min" + gather_network_resources: interfaces + + - name: Replaced + register: result + cisco.nxos.nxos_interfaces: &id002 + config: + - name: "{{ test_int1 }}" + description: Configured by Ansible + enabled: true + state: replaced + + - assert: + that: + - ansible_facts.network_resources.interfaces|symmetric_difference(result.before)|length == 0 + - result.changed == true + - "'interface {{ test_int1 }}' in result.commands" + - "'description Configured by Ansible' in result.commands" + - "'no shutdown' in result.commands" + + - name: Gather interfaces post facts + cisco.nxos.nxos_facts: *id001 + + - assert: + that: + - ansible_facts.network_resources.interfaces|symmetric_difference(result.after)|length == 0 + + - name: Idempotence - Replaced + register: result + cisco.nxos.nxos_interfaces: *id002 + + - assert: + that: + - result.changed == false + - result.commands|length == 0 + + - name: Reset interfaces + cisco.nxos.nxos_config: + lines: + - "default interface {{ test_int1 }}" + - "default interface {{ test_int2 }}" + - "interface {{ test_int1 }}" + - " description TEST-INTF-1" + - " speed 1000" + + - name: Replace (default existing and add new attributes) + cisco.nxos.nxos_interfaces: + config: + - name: "{{ test_int1 }}" + enabled: false + - name: "{{ test_int2 }}" + description: TEST-INTF-2 + enabled: true + state: replaced + register: result + + - assert: + that: + - "'interface {{ test_int1 }}' in result.commands" + - "'no description' in result.commands" + - "'no speed' in result.commands" + - "'interface {{ test_int2 }}' in result.commands" + - "'description TEST-INTF-2' in result.commands" + - "'no shutdown' in result.commands" + - result.commands|length == 6 + + always: + - name: teardown + cisco.nxos.nxos_config: *id003 + when: platform is not search('N3[5KL]|N[56]K|titanium') diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/rtt.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/rtt.yaml new file mode 100644 index 00000000..98b70b4b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/tests/common/rtt.yaml @@ -0,0 +1,77 @@ +--- +- ansible.builtin.debug: + msg: START nxos_interfaces round trip integration tests on connection={{ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- block: + - name: Apply the provided configuration (base config) + register: base_config + cisco.nxos.nxos_interfaces: + config: + - name: "{{ nxos_int1 }}" + description: TEST-INTF-1 + speed: 1000 + + - name: "{{ nxos_int2 }}" + description: TEST-INTF-2 + mode: layer2 + + - name: "{{ nxos_int3 }}" + description: TEST-INTF-3 + mtu: 9216 + state: merged + tags: base_config + + - name: Gather interfaces facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: + - interfaces + + - name: Apply the provided configuration (config to be reverted) + register: result + cisco.nxos.nxos_interfaces: + config: + - name: "{{ nxos_int1 }}" + description: WRONG-TEST-INTF-1 + speed: 10000 + + - name: "{{ nxos_int2 }}" + description: WRONG-TEST-INTF-2 + + - name: "{{ nxos_int3 }}" + description: WRONG-TEST-INTF-3 + enabled: false + state: overridden + + - ansible.builtin.assert: + that: + - '"interface Ethernet1/1" in result.commands' + - '"description WRONG-TEST-INTF-1" in result.commands' + - '"speed 10000" in result.commands' + - '"interface Ethernet1/2" in result.commands' + - '"no switchport" in result.commands' + - '"description WRONG-TEST-INTF-2" in result.commands' + - '"interface Ethernet1/3" in result.commands' + - '"no mtu" in result.commands' + - '"description WRONG-TEST-INTF-3" in result.commands' + - result.commands|length == 9 + - result.changed == true + + - name: Revert back to base configuration using facts round trip + register: revert + cisco.nxos.nxos_interfaces: + config: "{{ ansible_facts['network_resources']['interfaces'] }}" + state: overridden + + - ansible.builtin.assert: + that: + - "{{ base_config['after'] == revert['after'] }}" + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: END nxos_interfaces round trip integration tests on connection={{ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/vars/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/vars/main.yml new file mode 100644 index 00000000..bba0dd5c --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_interfaces/vars/main.yml @@ -0,0 +1,32 @@ +--- +gathered: + - name: "{{ nxos_int1 }}" + description: outbound-intf + mode: layer2 + enabled: true + - name: "{{ nxos_int2 }}" + description: intf-l3 + speed: "1000" + +rendered: + - "interface Ethernet1/1" + - "description outbound-intf" + - "speed 1000" + - "interface Ethernet1/2" + - "switchport" + - "duplex full" + - "no shutdown" + +parsed: + - description: "test-1" + duplex: "half" + enabled: false + mode: "layer3" + name: "Ethernet1/800" + speed: "1000" + + - description: "test-2" + enabled: true + mode: "layer2" + mtu: "1800" + name: "Ethernet1/801" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/defaults/main.yaml new file mode 100644 index 00000000..871ea460 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "[^_].*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tasks/cli.yaml new file mode 100644 index 00000000..9e4fb34b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tasks/main.yaml new file mode 100644 index 00000000..8d0b9433 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tasks/main.yaml @@ -0,0 +1,9 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tasks/nxapi.yaml new file mode 100644 index 00000000..5cb76e67 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tests/common/_populate_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tests/common/_populate_config.yaml new file mode 100644 index 00000000..7f2724c9 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tests/common/_populate_config.yaml @@ -0,0 +1,19 @@ +--- +- name: Populate interface - 1 + cisco.nxos.nxos_config: + lines: + - "switchport" + - "switchport access vlan 6" + - "switchport trunk allowed vlan 200" + parents: "interface {{ nxos_int1 }}" + vars: + ansible_connection: ansible.netcommon.network_cli + +- name: Populate interface - 2 + cisco.nxos.nxos_config: + lines: + - "switchport" + - "switchport trunk native vlan 10" + parents: "interface {{ nxos_int2 }}" + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tests/common/_remove_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tests/common/_remove_config.yaml new file mode 100644 index 00000000..37d46165 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tests/common/_remove_config.yaml @@ -0,0 +1,9 @@ +--- +- name: Cleanup + ignore_errors: true + cisco.nxos.nxos_config: + lines: + - "default interface {{ nxos_int1 }}" + - "default interface {{ nxos_int2 }}" + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tests/common/deleted.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tests/common/deleted.yaml new file mode 100644 index 00000000..b60c4a5c --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tests/common/deleted.yaml @@ -0,0 +1,67 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_l2_interfaces deleted integration tests connection={{ ansible_connection }} + +- name: Set a fact for 'test_int1' and 'test_int2' + ansible.builtin.set_fact: + test_int1: "{{ nxos_int1 }}" + test_int2: "{{ nxos_int2 }}" + +- name: Setup1 + ignore_errors: true + cisco.nxos.nxos_config: &id002 + lines: + - "default interface {{ test_int1 }}" + - "default interface {{ test_int2 }}" + +- block: + - name: Setup2 + cisco.nxos.nxos_config: + lines: + - "switchport" + - "switchport trunk native vlan 10" + parents: "interface {{ test_int1 }}" + + - name: Setup3 + cisco.nxos.nxos_config: + lines: + - "switchport" + - "switchport mode trunk" + - "switchport trunk allowed vlan 20" + parents: "interface {{ test_int2 }}" + + - name: Gather l2_interfaces facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: l2_interfaces + + - name: Deleted + register: result + cisco.nxos.nxos_l2_interfaces: &id001 + state: deleted + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.l2_interfaces|symmetric_difference(result.before)|length == 0 + - result.changed == true + - "'interface {{ test_int1 }}' in result.commands" + - "'no switchport trunk native vlan' in result.commands" + - "'interface {{ test_int2 }}' in result.commands" + - "'no switchport mode' in result.commands" + - "'no switchport trunk allowed vlan' in result.commands" + - result.commands|length == 5 + + - name: Idempotence - deleted + register: result + cisco.nxos.nxos_l2_interfaces: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + always: + - name: Teardown + ignore_errors: true + cisco.nxos.nxos_config: *id002 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tests/common/empty_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tests/common/empty_config.yaml new file mode 100644 index 00000000..0f222dbb --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tests/common/empty_config.yaml @@ -0,0 +1,61 @@ +--- +- ansible.builtin.debug: + msg: START nxos_lacp empty_config integration tests on connection={{ ansible_connection }} + +- name: Merged with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_l2_interfaces: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_l2_interfaces: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Overridden with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_l2_interfaces: + config: + state: overridden + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Rendered with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_l2_interfaces: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' + +- name: Parsed with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_l2_interfaces: + running_config: + state: parsed + +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state parsed' + +- ansible.builtin.debug: + msg: END nxos_lacp empty_config integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tests/common/gathered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tests/common/gathered.yaml new file mode 100644 index 00000000..4f99181d --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tests/common/gathered.yaml @@ -0,0 +1,21 @@ +--- +- ansible.builtin.debug: + msg: START nxos_l2_interfaces gathered integration tests on connection={{ ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Gather l2_interfaces facts from the device using nxos_l2_interfaces + register: result + cisco.nxos.nxos_l2_interfaces: + state: gathered + + - ansible.builtin.assert: + that: "{{ result['gathered'][:2] | symmetric_difference(gathered) |length == 0 }}" + always: + - ansible.builtin.include_tasks: _remove_config.yaml + + - ansible.builtin.debug: + msg: END nxos_l2_interfaces gathered integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tests/common/merged.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tests/common/merged.yaml new file mode 100644 index 00000000..04056254 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tests/common/merged.yaml @@ -0,0 +1,101 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_l2_interfaces merged integration tests connection={{ ansible_connection }} + +- name: Set a fact for 'test_int1' + ansible.builtin.set_fact: + test_int1: "{{ nxos_int1 }}" + +- name: Setup1 + ignore_errors: true + cisco.nxos.nxos_config: &id003 + lines: + - "default interface {{ test_int1 }}" + +- block: + - name: Setup2 + cisco.nxos.nxos_config: + lines: + - "interface {{ test_int1 }}" + - " switchport" + + - name: Merged + register: result + cisco.nxos.nxos_l2_interfaces: &id001 + config: + - name: "{{ test_int1 }}" + access: + vlan: 6 + trunk: + allowed_vlans: 200 + state: merged + + - ansible.builtin.assert: + that: + - result.changed == true + - "'interface {{ test_int1 }}' in result.commands" + - "'switchport access vlan 6' in result.commands" + - "'switchport trunk allowed vlan 200' in result.commands" + - result.commands|length == 3 + + - name: Gather l2_interfaces facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: l2_interfaces + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.l2_interfaces|symmetric_difference(result.after) == [] + + - name: Idempotence - merged + register: result + cisco.nxos.nxos_l2_interfaces: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + + - name: Merge with existing vlans + register: result + cisco.nxos.nxos_l2_interfaces: &id002 + config: + - name: "{{ test_int1 }}" + mode: trunk + trunk: + allowed_vlans: 10-12 + state: merged + + - ansible.builtin.assert: + that: + - result.changed == true + - "'interface {{ test_int1 }}' in result.commands" + - "'switchport mode trunk' in result.commands" + - "'switchport trunk allowed vlan add 10-12' in result.commands" + - result.commands|length == 3 + + - name: Gather l2_interfaces facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: l2_interfaces + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.l2_interfaces|symmetric_difference(result.after) == [] + + - name: Idempotence - with newly added vlans + register: result + cisco.nxos.nxos_l2_interfaces: *id002 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + always: + - name: Teardown + ignore_errors: true + cisco.nxos.nxos_config: *id003 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tests/common/overridden.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tests/common/overridden.yaml new file mode 100644 index 00000000..077914d2 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tests/common/overridden.yaml @@ -0,0 +1,77 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_l2_interfaces overridden integration tests connection={{ ansible_connection }} + +- name: Set a fact for 'test_int1' and 'test_int2' + ansible.builtin.set_fact: + test_int1: "{{ nxos_int1 }}" + test_int2: "{{ nxos_int2 }}" + +- name: Setup1 + ignore_errors: true + cisco.nxos.nxos_config: &id003 + lines: + - "default interface {{ test_int1 }}" + - "default interface {{ test_int2 }}" + +- block: + - name: Setup2 + cisco.nxos.nxos_config: + lines: + - "switchport" + - "switchport trunk allowed vlan 11" + parents: "interface {{ test_int1 }}" + + - name: Setup3 + cisco.nxos.nxos_config: + lines: + - "switchport" + parents: "interface {{ test_int2 }}" + + - name: Gather l2_interfaces facts + cisco.nxos.nxos_facts: &id001 + gather_subset: + - "!all" + - "!min" + gather_network_resources: l2_interfaces + + - name: Overridden + register: result + cisco.nxos.nxos_l2_interfaces: &id002 + config: + - name: "{{ test_int2 }}" + access: + vlan: 6 + trunk: + allowed_vlans: 10-12 + state: overridden + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.l2_interfaces|symmetric_difference(result.before) == [] + - result.changed == true + - "'interface {{ test_int1 }}' in result.commands" + - "'no switchport trunk allowed vlan' in result.commands" + - "'interface {{ test_int2 }}' in result.commands" + - "'switchport access vlan 6' in result.commands" + - "'switchport trunk allowed vlan 10-12' in result.commands" + + - name: Gather l2_interfaces post facts + cisco.nxos.nxos_facts: *id001 + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.l2_interfaces|symmetric_difference(result.after) == [] + + - name: Idempotence - overridden + register: result + cisco.nxos.nxos_l2_interfaces: *id002 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + always: + - name: Teardown + ignore_errors: true + cisco.nxos.nxos_config: *id003 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tests/common/parsed.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tests/common/parsed.yaml new file mode 100644 index 00000000..023049ee --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tests/common/parsed.yaml @@ -0,0 +1,34 @@ +--- +- ansible.builtin.debug: + msg: START nxos_l2_interfaces parsed integration tests on connection={{ ansible_connection }} + +- block: + # Interfaces used in the task don't actually exist on the appliance + - name: Use parsed state to convert externally supplied configuration to structured format + register: result + cisco.nxos.nxos_l2_interfaces: + running_config: | + interface nve1 + no shutdown + host-reachability protocol bgp + advertise virtual-rmac + source-interface loopback1 + interface Ethernet1/799 + switchport mode dot1q-tunnel + interface Ethernet1/800 + switchport access vlan 18 + switchport trunk allowed vlan 210 + interface Ethernet1/801 + switchport trunk allowed vlan 2,4,15 + interface Ethernet1/802 + switchport mode fex-fabric + interface Ethernet1/803 + switchport mode fabricpath + interface loopback1 + state: parsed + + - ansible.builtin.assert: + that: "{{ parsed | symmetric_difference(result['parsed']) |length==0 }}" + +- ansible.builtin.debug: + msg: END nxos_l2_interfaces parsed integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tests/common/rendered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tests/common/rendered.yaml new file mode 100644 index 00000000..64723dcb --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tests/common/rendered.yaml @@ -0,0 +1,51 @@ +--- +- ansible.builtin.debug: + msg: START nxos_l2_interfaces rendered integration tests on connection={{ ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- name: Gather pre-facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: l2_interfaces + +- block: + - name: Use rendered state to convert task input to device specific commands + register: result + cisco.nxos.nxos_l2_interfaces: + config: + - name: Ethernet1/1 + trunk: + native_vlan: 10 + allowed_vlans: 2,4,15 + - name: Ethernet1/2 + access: + vlan: 30 + - name: Ethernet1/3 + trunk: + native_vlan: 20 + allowed_vlans: 5-10, 15 + - name: Ethernet1/4 + mode: fex-fabric + - name: Ethernet1/5 + mode: fabricpath + state: rendered + + - ansible.builtin.assert: + that: "{{ rendered | symmetric_difference(result['rendered']) |length==0 }}" + + - name: Gather l2_interfaces facts from the device and assert that its empty + register: result + cisco.nxos.nxos_l2_interfaces: + state: gathered + + - name: Make sure that rendered task actually did not make any changes to the device + ansible.builtin.assert: + that: "{{ result['gathered']|symmetric_difference(ansible_facts.network_resources.l2_interfaces) == [] }}" + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: END nxos_l2_interfaces rendered integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tests/common/replaced.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tests/common/replaced.yaml new file mode 100644 index 00000000..c37061c0 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tests/common/replaced.yaml @@ -0,0 +1,83 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_l2_interfaces replaced integration tests connection={{ ansible_connection }} + +- name: Set a fact for 'test_int1' and 'test_int2' + ansible.builtin.set_fact: + test_int1: "{{ nxos_int1 }}" + test_int2: "{{ nxos_int2 }}" + +- name: Setup1 + ignore_errors: true + cisco.nxos.nxos_config: &id003 + lines: + - "default interface {{ test_int1 }}" + - "default interface {{ test_int2 }}" + +- block: + - name: Setup2 + cisco.nxos.nxos_config: + lines: + - "switchport" + - "switchport access vlan 5" + parents: "interface {{ test_int1 }}" + + - name: Setup3 + cisco.nxos.nxos_config: + lines: + - "switchport" + - "switchport trunk native vlan 15" + - "switchport trunk allowed vlan 25-27" + parents: "interface {{ test_int2 }}" + + - name: Gather l2_interfaces facts + cisco.nxos.nxos_facts: &id001 + gather_subset: + - "!all" + - "!min" + gather_network_resources: l2_interfaces + + - name: Replaced + register: result + cisco.nxos.nxos_l2_interfaces: &id002 + config: + - name: "{{ test_int1 }}" + access: + vlan: 8 + trunk: + allowed_vlans: 10-12 + + - name: "{{ test_int2 }}" + trunk: + allowed_vlans: 25-27 + state: replaced + + - ansible.builtin.assert: + that: + - result.changed == true + - "'interface {{ test_int1 }}' in result.commands" + - "'switchport access vlan 8' in result.commands" + - "'switchport trunk allowed vlan 10-12' in result.commands" + - "'interface {{ test_int2 }}' in result.commands" + - "'no switchport trunk native vlan' in result.commands" + - result.commands|length == 5 + + - name: Gather l2_interfaces post facts + cisco.nxos.nxos_facts: *id001 + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.l2_interfaces|symmetric_difference(result.after) == [] + + - name: Idempotence - replaced + register: result + cisco.nxos.nxos_l2_interfaces: *id002 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + always: + - name: Teardown + ignore_errors: true + cisco.nxos.nxos_config: *id003 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tests/common/rtt.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tests/common/rtt.yaml new file mode 100644 index 00000000..5ef0b101 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/tests/common/rtt.yaml @@ -0,0 +1,74 @@ +--- +- ansible.builtin.debug: + msg: START nxos_l2_interfaces round trip integration tests on connection={{ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- block: + - name: Prepare interfaces (switch to l2) + cisco.nxos.nxos_interfaces: + config: + - name: "{{ nxos_int1 }}" + mode: layer2 + - name: "{{ nxos_int2 }}" + mode: layer2 + - name: "{{ nxos_int3 }}" + mode: layer2 + state: merged + + - name: Apply the provided configuration (base config) + register: base_config + cisco.nxos.nxos_l2_interfaces: + config: + - name: "{{ nxos_int1 }}" + trunk: + native_vlan: 10 + allowed_vlans: 2,4,15 + - name: "{{ nxos_int2 }}" + access: + vlan: 30 + state: merged + tags: base_config + + - name: Gather interfaces facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: + - l2_interfaces + + - name: Apply the provided configuration (config to be reverted) + register: result + cisco.nxos.nxos_l2_interfaces: + config: + - name: "{{ nxos_int1 }}" + trunk: + native_vlan: 20 + - name: "{{ nxos_int2 }}" + access: + vlan: 31 + - name: "{{ nxos_int3 }}" + trunk: + native_vlan: 20 + allowed_vlans: 5-10, 15 + state: overridden + + - ansible.builtin.assert: + that: + - result.changed == true + + - name: Revert back to base configuration using facts round trip + register: revert + cisco.nxos.nxos_l2_interfaces: + config: "{{ ansible_facts['network_resources']['l2_interfaces'] }}" + state: overridden + + - ansible.builtin.assert: + that: + - "{{ base_config['after'] == revert['after'] }}" + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: END nxos_l2_interfaces round trip integration tests on connection={{ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/vars/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/vars/main.yml new file mode 100644 index 00000000..71d7f0b5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l2_interfaces/vars/main.yml @@ -0,0 +1,43 @@ +--- +gathered: + - name: "{{ nxos_int1 }}" + access: + vlan: 6 + trunk: + allowed_vlans: "200" + + - name: "{{ nxos_int2 }}" + trunk: + native_vlan: 10 + +parsed: + - name: nve1 + - name: Ethernet1/799 + mode: dot1q-tunnel + - name: Ethernet1/800 + access: + vlan: 18 + trunk: + allowed_vlans: "210" + - name: Ethernet1/801 + trunk: + allowed_vlans: "2,4,15" + - name: Ethernet1/802 + mode: fex-fabric + - name: Ethernet1/803 + mode: fabricpath + - name: loopback1 + +rendered: + - "interface Ethernet1/1" + - "switchport trunk allowed vlan 2,4,15" + - "switchport trunk native vlan 10" + - "interface Ethernet1/2" + - "switchport access vlan 30" + - "interface Ethernet1/3" + - "switchport trunk allowed vlan 5-10,15" + - "switchport trunk native vlan 20" + - "interface Ethernet1/4" + - "switchport mode fex-fabric" + - "interface Ethernet1/5" + - "switchport mode fabricpath" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/defaults/main.yaml new file mode 100644 index 00000000..871ea460 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "[^_].*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tasks/cli.yaml new file mode 100644 index 00000000..9e4fb34b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tasks/main.yaml new file mode 100644 index 00000000..4ef02263 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tasks/main.yaml @@ -0,0 +1,15 @@ +--- +- name: Set a fact for 'rsvd_intf' + ansible.builtin.set_fact: + rsvd_intf: "{{ rsvd_intf | default('mgmt0') }}" + +- name: Run the CLI and NX-API tests + block: + - name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + - name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tasks/nxapi.yaml new file mode 100644 index 00000000..5cb76e67 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/_populate_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/_populate_config.yaml new file mode 100644 index 00000000..d0a29340 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/_populate_config.yaml @@ -0,0 +1,18 @@ +--- +- name: Populate configuration - 1 + cisco.nxos.nxos_config: + lines: + - "interface {{ nxos_int1 }}" + - " no switchport" + - " ip redirects" + - " ip address 192.0.2.100/24" + +- name: Populate configuration - 2 + cisco.nxos.nxos_config: + lines: + - "interface {{ nxos_int2 }}" + - " no switchport" + - " no ip redirects" + - " ip unreachables" + - " ip address 203.0.113.10/24" + - " ipv6 address 2001:db8::1/32" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/_remove_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/_remove_config.yaml new file mode 100644 index 00000000..d7e66224 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/_remove_config.yaml @@ -0,0 +1,8 @@ +--- +- name: Remove configuration + cisco.nxos.nxos_config: + lines: + - "default interface {{ nxos_int1 }}" + - "default interface {{ nxos_int2 }}" + - "default interface {{ nxos_int3 }}" + ignore_errors: true diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/deleted.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/deleted.yaml new file mode 100644 index 00000000..c4d63a3a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/deleted.yaml @@ -0,0 +1,69 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_l3_interfaces deleted integration tests connection={{ ansible_connection }} + +- name: Set a fact for 'subint3' and 'test_int3' + ansible.builtin.set_fact: + test_int3: "{{ nxos_int3 }}" + subint3: "{{ nxos_int3 }}.42" + +- ansible.builtin.include_tasks: _remove_config.yaml + +- name: Setup1 + ignore_errors: true + cisco.nxos.nxos_config: + lines: + - "no system default switchport" + - "default interface {{ test_int3 }}" + - "interface {{ test_int3 }}" + - " no switchport" + +- block: + - name: Setup3 + cisco.nxos.nxos_config: + lines: + - "interface {{ subint3 }}" + - " encapsulation dot1q 42" + - " ip address 192.168.10.2/24" + - " no ip redirects" + - " ip unreachables" + + - name: Gather l3_interfaces facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: l3_interfaces + + - name: Deleted + register: result + cisco.nxos.nxos_l3_interfaces: &id001 + config: + - name: "{{ subint3 }}" + state: deleted + + - ansible.builtin.assert: + that: + - result.before|symmetric_difference(ansible_facts.network_resources.l3_interfaces) == [] + - result.changed == true + - "'interface {{ subint3 }}' in result.commands" + - "'no encapsulation dot1q' in result.commands" + - "'ip redirects' in result.commands" + - "'no ip unreachables' in result.commands" + - "'no ip address' in result.commands" + - result.commands|length == 5 + + - name: Idempotence - deleted + register: result + cisco.nxos.nxos_l3_interfaces: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + always: + - name: Teardown + ignore_errors: true + cisco.nxos.nxos_config: + lines: + - "no interface {{ subint3 }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/empty_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/empty_config.yaml new file mode 100644 index 00000000..4c2d37d7 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/empty_config.yaml @@ -0,0 +1,61 @@ +--- +- ansible.builtin.debug: + msg: START nxos_l3_interfaces empty_config integration tests on connection={{ ansible_connection }} + +- name: Merged with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_l3_interfaces: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_l3_interfaces: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Overridden with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_l3_interfaces: + config: + state: overridden + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Rendered with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_l3_interfaces: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' + +- name: Parsed with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_l3_interfaces: + running_config: + state: parsed + +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state parsed' + +- ansible.builtin.debug: + msg: END nxos_l3_interfaces empty_config integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/gathered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/gathered.yaml new file mode 100644 index 00000000..bb82b6ca --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/gathered.yaml @@ -0,0 +1,22 @@ +--- +- ansible.builtin.debug: + msg: START nxos_l3_interfaces gathered integration tests on connection={{ ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Gather l3_interfaces facts from the device using nxos_l3_interfaces + register: result + cisco.nxos.nxos_l3_interfaces: + state: gathered + + - ansible.builtin.assert: + that: "{{ result['gathered'][:2] | symmetric_difference(gathered) |length == 0 }}" + + always: + - ansible.builtin.include_tasks: _remove_config.yaml + + - ansible.builtin.debug: + msg: END nxos_l3_interfaces gathered integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/merged.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/merged.yaml new file mode 100644 index 00000000..637a0bce --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/merged.yaml @@ -0,0 +1,70 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_l3_interfaces merged integration tests connection={{ ansible_connection }} + +- name: Set a fact for 'subint3' and 'test_int3' + ansible.builtin.set_fact: + test_int3: "{{ nxos_int3 }}" + subint3: "{{ nxos_int3 }}.42" + +- ansible.builtin.include_tasks: _remove_config.yaml + +- name: Setup1 + ignore_errors: true + cisco.nxos.nxos_config: + lines: + - "no system default switchport" + - "default interface {{ test_int3 }}" + - "interface {{ test_int3 }}" + - " no switchport" + +- block: + - name: Merged + register: result + cisco.nxos.nxos_l3_interfaces: &id001 + config: + - name: "{{ subint3 }}" + dot1q: 42 + redirects: false + unreachables: true + ipv4: + - address: 192.168.10.2/24 + state: merged + + - ansible.builtin.assert: + that: + - result.changed == true + - "'interface {{ subint3 }}' in result.commands" + - "'encapsulation dot1q 42' in result.commands" + - "'no ip redirects' in result.commands" + - "'ip unreachables' in result.commands" + - "'ip address 192.168.10.2/24' in result.commands" + - result.commands|length == 5 + + - name: Gather l3_interfaces facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: l3_interfaces + + - ansible.builtin.assert: + that: + - result.after|symmetric_difference(ansible_facts.network_resources.l3_interfaces) == [] + + - name: Idempotence - merged + register: result + cisco.nxos.nxos_l3_interfaces: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + always: + - name: Teardown sub-interface + ignore_errors: true + cisco.nxos.nxos_config: + lines: + - "no interface {{ subint3 }}" + + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/multisite.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/multisite.yaml new file mode 100644 index 00000000..c361da1e --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/multisite.yaml @@ -0,0 +1,376 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_l3_interfaces multisite integration tests connection={{ ansible_connection }} + +- name: Set a fact for 'test_int1', 'test_int2', and 'test_int3' + ansible.builtin.set_fact: + test_int1: "{{ nxos_int1 }}" + test_int2: "{{ nxos_int2 }}" + test_int3: "{{ nxos_int3 }}" + +- ansible.builtin.include_tasks: _remove_config.yaml + +- name: Enable 'feature nv overlay' - multisite + cisco.nxos.nxos_config: + commands: + - no feature nv overlay + - feature nv overlay + match: none + +- name: Enable NV overlay EVPN - multisite + when: platform is search('N9K') + ignore_errors: true + cisco.nxos.nxos_config: + lines: + - nv overlay evpn + +- name: Enable multisite border gateway - multisite + ignore_errors: true + register: multiout + cisco.nxos.nxos_config: + lines: + - evpn multisite border-gateway 10 + +- block: + - name: Setup1 - deleted + ignore_errors: true + cisco.nxos.nxos_config: + lines: + - "no system default switchport" + - "default interface {{ test_int3 }}" + - "interface {{ test_int3 }}" + - " no switchport" + + - name: Setup3 - deleted + cisco.nxos.nxos_config: + lines: + - "interface {{ test_int3 }}" + - " ip address 192.168.10.2/24" + - " no ip redirects" + - " ip unreachables" + - " evpn multisite dci-tracking" + + - name: Gather l3_interfaces facts deleted + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: l3_interfaces + + - name: Deleted + register: result + cisco.nxos.nxos_l3_interfaces: &id001 + config: + - name: "{{ test_int3 }}" + state: deleted + + - ansible.builtin.assert: + that: + - result.before|symmetric_difference(ansible_facts.network_resources.l3_interfaces) == [] + - result.changed == true + - "'interface {{ test_int3 }}' in result.commands" + - "'ip redirects' in result.commands" + - "'no ip unreachables' in result.commands" + - "'no ip address' in result.commands" + - "'no evpn multisite dci-tracking' in result.commands" + - result.commands|length == 5 + + - name: Idempotence - deleted + register: result + cisco.nxos.nxos_l3_interfaces: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + + - ansible.builtin.include_tasks: _remove_config.yaml + + - name: Setup1 - merged + ignore_errors: true + cisco.nxos.nxos_config: + lines: + - "no system default switchport" + - "default interface {{ test_int3 }}" + - "interface {{ test_int3 }}" + - " no switchport" + + - name: Merged + register: result + cisco.nxos.nxos_l3_interfaces: &id002 + config: + - name: "{{ test_int3 }}" + redirects: false + unreachables: true + evpn_multisite_tracking: fabric-tracking + ipv4: + - address: 192.168.10.2/24 + state: merged + + - ansible.builtin.assert: + that: + - result.changed == true + - "'interface {{ test_int3 }}' in result.commands" + - "'no ip redirects' in result.commands" + - "'ip unreachables' in result.commands" + - "'ip address 192.168.10.2/24' in result.commands" + - "'evpn multisite fabric-tracking' in result.commands" + - result.commands|length == 5 + + - name: Gather l3_interfaces facts - merged + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: l3_interfaces + + - ansible.builtin.assert: + that: + - result.after|symmetric_difference(ansible_facts.network_resources.l3_interfaces) == [] + + - name: Idempotence - merged + register: result + cisco.nxos.nxos_l3_interfaces: *id002 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + + - ansible.builtin.include_tasks: _remove_config.yaml + + - name: Setup1 - replaced + ignore_errors: true + cisco.nxos.nxos_config: + lines: + - "no system default switchport" + - "default interface {{ test_int3 }}" + - "interface {{ test_int3 }}" + - " no switchport" + + - name: Setup3 - replaced + cisco.nxos.nxos_config: + lines: + - "interface {{ test_int3 }}" + - " ip address 192.168.10.2/24" + - " no ip redirects" + - " ip unreachables" + - " evpn multisite dci-tracking" + + - name: Gather l3_interfaces facts + cisco.nxos.nxos_facts: &id003 + gather_subset: + - "!all" + - "!min" + gather_network_resources: l3_interfaces + + - name: Replaced + register: result + cisco.nxos.nxos_l3_interfaces: &id004 + config: + - name: "{{ test_int3 }}" + redirects: false + unreachables: false + evpn_multisite_tracking: fabric-tracking + ipv4: + - address: 192.168.20.2/24 + tag: 5 + + - address: 192.168.200.2/24 + secondary: true + state: replaced + + - ansible.builtin.assert: + that: + - result.before|symmetric_difference(ansible_facts.network_resources.l3_interfaces) == [] + - result.changed == true + - "'interface {{ test_int3 }}' in result.commands" + - "'no ip unreachables' in result.commands" + - "'ip address 192.168.20.2/24 tag 5' in result.commands" + - "'ip address 192.168.200.2/24 secondary' in result.commands" + - "'evpn multisite fabric-tracking' in result.commands" + - result.commands|length == 5 + + - name: Gather l3_interfaces post facts + cisco.nxos.nxos_facts: *id003 + + - ansible.builtin.assert: + that: + - result.after|symmetric_difference(ansible_facts.network_resources.l3_interfaces) == [] + + - name: Idempotence - replaced + register: result + cisco.nxos.nxos_l3_interfaces: *id004 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + + - ansible.builtin.include_tasks: _remove_config.yaml + + - name: Setup1 - overidden + ignore_errors: true + cisco.nxos.nxos_config: &id007 + lines: + - "no system default switchport" + - "default interface {{ item }}" + - "interface {{ item }}" + - " no switchport" + loop: + - "{{ test_int1 }}" + - "{{ test_int2 }}" + - "{{ test_int3 }}" + + - name: Setup3 - overidden + cisco.nxos.nxos_config: + lines: + - "interface {{ test_int1 }}" + - " ip address 192.168.10.2/24 tag 5" + - " evpn multisite fabric-tracking" + - "interface {{ test_int2 }}" + - " ip address 10.1.1.1/24" + - " evpn multisite dci-tracking" + + - name: Gather l3_interfaces facts + cisco.nxos.nxos_facts: &id005 + gather_subset: + - "!all" + - "!min" + gather_network_resources: l3_interfaces + + - name: Store reserved interface IP configuration + ansible.builtin.set_fact: + mgmt: "{{ ansible_facts.network_resources.l3_interfaces|selectattr('name', 'equalto', rsvd_intf)|list }}" + overriden_config: + - name: "{{ test_int3 }}" + ipv4: + - address: 10.1.1.3/24 + evpn_multisite_tracking: dci-tracking + + - name: Overridden + register: result + cisco.nxos.nxos_l3_interfaces: &id006 + config: "{{ overriden_config + mgmt }}" + state: overridden + + - ansible.builtin.assert: + that: + - result.before|symmetric_difference(ansible_facts.network_resources.l3_interfaces) == [] + - result.changed == true + - "'interface {{ test_int1 }}' in result.commands" + - "'no ip address' in result.commands" + - "'no evpn multisite fabric-tracking' in result.commands" + - "'interface {{ test_int2 }}' in result.commands" + - "'no ip address' in result.commands" + - "'no evpn multisite dci-tracking' in result.commands" + - "'interface {{ test_int3 }}' in result.commands" + - "'ip address 10.1.1.3/24' in result.commands" + - "'evpn multisite dci-tracking' in result.commands" + - result.commands|length == 9 + + - name: Gather l3_interfaces post facts + cisco.nxos.nxos_facts: *id005 + + - ansible.builtin.assert: + that: + - result.after|symmetric_difference(ansible_facts.network_resources.l3_interfaces) == [] + + - name: Idempotence - overridden + register: result + cisco.nxos.nxos_l3_interfaces: *id006 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + + - name: Teardown - overdidden + ignore_errors: true + cisco.nxos.nxos_config: *id007 + loop: + - "{{ test_int1 }}" + - "{{ test_int2 }}" + - "{{ test_int3 }}" + + - name: Gather pre-facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: l3_interfaces + + # Interfaces used here doesn't actually exist on the device + - name: Use rendered state to convert task input to device specific commands + register: result + cisco.nxos.nxos_l3_interfaces: + config: + - name: Ethernet1/800 + ipv4: + - address: 192.168.1.100/24 + tag: 5 + - address: 10.1.1.1/24 + secondary: true + tag: 10 + evpn_multisite_tracking: fabric-tracking + - name: Ethernet1/800 + ipv6: + - address: fd5d:12c9:2201:2::1/64 + tag: 6 + evpn_multisite_tracking: dci-tracking + state: rendered + + - ansible.builtin.assert: + that: "{{ rendered_multi | symmetric_difference(result['rendered']) |length==0 }}" + + - name: Gather l3_interfaces facts from the device and assert that its empty + register: result + cisco.nxos.nxos_l3_interfaces: + state: gathered + + - name: Make sure that rendered task actually did not make any changes to the device + ansible.builtin.assert: + that: "{{ result['gathered']|symmetric_difference(ansible_facts.network_resources.l3_interfaces) == [] }}" + + - ansible.builtin.include_tasks: _remove_config.yaml + + # Interfaces used in the task don't actually exist on the appliance + - name: Use parsed state to convert externally supplied configuration to structured format + register: result + cisco.nxos.nxos_l3_interfaces: + running_config: | + interface Ethernet1/800 + ip address 192.168.1.100/24 tag 5 + ip address 10.1.1.1/24 secondary tag 10 + no ip redirects + evpn multisite fabric-tracking + interface Ethernet1/801 + ipv6 address fd5d:12c9:2201:2::1/64 tag 6 + ip unreachables + evpn multisite dci-tracking + interface mgmt0 + ip address dhcp + vrf member management + state: parsed + + - ansible.builtin.assert: + that: "{{ parsed_multi | symmetric_difference(result['parsed']) |length==0 }}" + + when: multiout is not search("Invalid command") + +- name: Disable NV overlay EVPN + when: platform is search('N9K') + ignore_errors: true + cisco.nxos.nxos_config: + commands: + - no nv overlay evpn + match: none + +- name: Disable 'feature nv overlay' + ignore_errors: true + cisco.nxos.nxos_feature: + feature: nve + state: disabled + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_l3_interfaces multisite test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/overridden.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/overridden.yaml new file mode 100644 index 00000000..c716b5c4 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/overridden.yaml @@ -0,0 +1,90 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_l3_interfaces overridden integration tests connection={{ ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- name: Set a fact for 'test_int1', 'test_int2', and 'test_int3' + ansible.builtin.set_fact: + test_int1: "{{ nxos_int1 }}" + test_int2: "{{ nxos_int2 }}" + test_int3: "{{ nxos_int3 }}" + +- name: Setup1 + ignore_errors: true + cisco.nxos.nxos_config: &id003 + lines: + - "no system default switchport" + - "default interface {{ item }}" + - "interface {{ item }}" + - " no switchport" + loop: + - "{{ test_int1 }}" + - "{{ test_int2 }}" + - "{{ test_int3 }}" + +- block: + - name: Setup3 + cisco.nxos.nxos_config: + lines: + - "interface {{ test_int1 }}" + - " ip address 192.168.10.2/24 tag 5" + - "interface {{ test_int2 }}" + - " ip address 10.1.1.1/24" + + - name: Gather l3_interfaces facts + cisco.nxos.nxos_facts: &id001 + gather_subset: + - "!all" + - "!min" + gather_network_resources: l3_interfaces + + - name: Store reserved interface IP configuration + ansible.builtin.set_fact: + mgmt: "{{ ansible_facts.network_resources.l3_interfaces|selectattr('name', 'equalto', rsvd_intf)|list }}" + overriden_config: + - name: "{{ test_int3 }}" + ipv4: + - address: 10.1.1.3/24 + + - name: Overridden + register: result + cisco.nxos.nxos_l3_interfaces: &id002 + config: "{{ overriden_config + mgmt }}" + state: overridden + + - ansible.builtin.assert: + that: + - result.before|symmetric_difference(ansible_facts.network_resources.l3_interfaces) == [] + - result.changed == true + - "'interface {{ test_int1 }}' in result.commands" + - "'no ip address' in result.commands" + - "'interface {{ test_int2 }}' in result.commands" + - "'no ip address' in result.commands" + - "'interface {{ test_int3 }}' in result.commands" + - "'ip address 10.1.1.3/24' in result.commands" + - result.commands|length == 6 + + - name: Gather l3_interfaces post facts + cisco.nxos.nxos_facts: *id001 + + - ansible.builtin.assert: + that: + - result.after|symmetric_difference(ansible_facts.network_resources.l3_interfaces) == [] + + - name: Idempotence - overridden + register: result + cisco.nxos.nxos_l3_interfaces: *id002 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + always: + - name: Teardown + ignore_errors: true + cisco.nxos.nxos_config: *id003 + loop: + - "{{ test_int1 }}" + - "{{ test_int2 }}" + - "{{ test_int3 }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/parsed.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/parsed.yaml new file mode 100644 index 00000000..ecf23ce0 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/parsed.yaml @@ -0,0 +1,27 @@ +--- +- ansible.builtin.debug: + msg: START nxos_l3_interfaces parsed integration tests on connection={{ ansible_connection }} + +- block: + # Interfaces used in the task don't actually exist on the appliance + - name: Use parsed state to convert externally supplied configuration to structured format + register: result + cisco.nxos.nxos_l3_interfaces: + running_config: | + interface Ethernet1/800 + ip address 192.168.1.100/24 tag 5 + ip address 10.1.1.1/24 secondary tag 10 + no ip redirects + interface Ethernet1/801 + ipv6 address fd5d:12c9:2201:2::1/64 tag 6 + ip unreachables + interface mgmt0 + ip address dhcp + vrf member management + state: parsed + + - ansible.builtin.assert: + that: "{{ parsed | symmetric_difference(result['parsed']) |length==0 }}" + +- ansible.builtin.debug: + msg: END nxos_l3_interface parsed integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/rendered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/rendered.yaml new file mode 100644 index 00000000..c217eb41 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/rendered.yaml @@ -0,0 +1,49 @@ +--- +- ansible.builtin.debug: + msg: START nxos_l3_interfaces rendered integration tests on connection={{ ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- name: Gather pre-facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: l3_interfaces + +- block: + # Interfaces used here doesn't actually exist on the device + - name: Use rendered state to convert task input to device specific commands + register: result + cisco.nxos.nxos_l3_interfaces: + config: + - name: Ethernet1/800 + ipv4: + - address: 192.168.1.100/24 + tag: 5 + - address: 10.1.1.1/24 + secondary: true + tag: 10 + - name: Ethernet1/800 + ipv6: + - address: fd5d:12c9:2201:2::1/64 + tag: 6 + state: rendered + + - ansible.builtin.assert: + that: "{{ rendered | symmetric_difference(result['rendered']) |length==0 }}" + + - name: Gather l3_interfaces facts from the device and assert that its empty + register: result + cisco.nxos.nxos_l3_interfaces: + state: gathered + + - name: Make sure that rendered task actually did not make any changes to the device + ansible.builtin.assert: + that: "{{ result['gathered']|symmetric_difference(ansible_facts.network_resources.l3_interfaces) == [] }}" + + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: END nxos_l3_interfaces rendered integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/replaced.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/replaced.yaml new file mode 100644 index 00000000..d593fac5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/replaced.yaml @@ -0,0 +1,115 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_l3_interfaces replaced integration tests connection={{ ansible_connection }} + +- name: Set a fact for 'subint3' and 'test_int3' + ansible.builtin.set_fact: + test_int3: "{{ nxos_int3 }}" + subint3: "{{ nxos_int3 }}.42" + +- ansible.builtin.include_tasks: _remove_config.yaml + +- name: Setup1 + ignore_errors: true + cisco.nxos.nxos_config: + lines: + - "no system default switchport" + - "default interface {{ test_int3 }}" + - "interface {{ test_int3 }}" + - " no switchport" + +- block: + - name: Setup3 + cisco.nxos.nxos_config: + lines: + - "interface {{ subint3 }}" + - " encapsulation dot1q 42" + - " ip address 192.168.10.2/24" + - " no ip redirects" + - " ip unreachables" + + - name: Gather l3_interfaces facts + cisco.nxos.nxos_facts: &id001 + gather_subset: + - "!all" + - "!min" + gather_network_resources: l3_interfaces + + - name: Replaced + register: result + cisco.nxos.nxos_l3_interfaces: &id002 + config: + - name: "{{ subint3 }}" + dot1q: 442 + redirects: false + unreachables: false + ipv4: + - address: 192.168.20.2/24 + tag: 5 + + - address: 192.168.200.2/24 + secondary: true + state: replaced + + - ansible.builtin.assert: + that: + - result.before|symmetric_difference(ansible_facts.network_resources.l3_interfaces) == [] + - result.changed == true + - "'interface {{ subint3 }}' in result.commands" + - "'encapsulation dot1q 442' in result.commands" + - "'no ip unreachables' in result.commands" + - "'ip address 192.168.20.2/24 tag 5' in result.commands" + - "'ip address 192.168.200.2/24 secondary' in result.commands" + - result.commands|length == 5 + + - name: Gather l3_interfaces post facts + cisco.nxos.nxos_facts: *id001 + + - ansible.builtin.assert: + that: + - result.after|symmetric_difference(ansible_facts.network_resources.l3_interfaces) == [] + + - name: Idempotence - replaced + register: result + cisco.nxos.nxos_l3_interfaces: *id002 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + + - name: Replaced with no optional attrs specified + register: result + cisco.nxos.nxos_l3_interfaces: &id003 + config: + - name: "{{ subint3 }}" + state: replaced + + - ansible.builtin.assert: + that: + - result.changed == true + - "'interface {{ subint3 }}' in result.commands" + - "'no encapsulation dot1q' in result.commands" + - "'no ip address' in result.commands" + + - ansible.builtin.assert: + that: + - "'ip redirects' in result.commands" + when: platform is match('N[3567]') + + - name: Idempotence - replaced with no attrs specified + register: result + cisco.nxos.nxos_l3_interfaces: *id003 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + always: + - name: Teardown sub-interface + ignore_errors: true + cisco.nxos.nxos_config: + lines: + - "no interface {{ subint3 }}" + + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/rtt.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/rtt.yaml new file mode 100644 index 00000000..887876f0 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/tests/common/rtt.yaml @@ -0,0 +1,89 @@ +--- +- ansible.builtin.debug: + msg: START nxos_l3_interfaces round trip integration tests on connection={{ ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- block: + - name: Prepare interfaces (switch to l3) + cisco.nxos.nxos_interfaces: + config: + - name: "{{ nxos_int1 }}" + mode: layer3 + - name: "{{ nxos_int2 }}" + mode: layer3 + - name: "{{ nxos_int3 }}" + mode: layer3 + state: merged + + - name: Apply the provided configuration (base config) + register: base_config + cisco.nxos.nxos_l3_interfaces: + config: + - name: "{{ nxos_int1 }}" + ipv4: + - address: 192.0.2.49/28 + tag: 5 + - address: 198.51.100.65/27 + secondary: true + tag: 10 + ipv6: + - address: 2001:db8:2000::1/32 + tag: 6 + - name: "{{ nxos_int2 }}" + ipv4: + - address: 192.0.2.81/28 + state: merged + tags: base_config + + - name: Gather interfaces facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: + - l3_interfaces + + - name: Set reserved interface IP configuration and configuration to revert + ansible.builtin.set_fact: + mgmt: "{{ ansible_facts.network_resources.l3_interfaces|selectattr('name', 'equalto', rsvd_intf)|list }}" + config_to_revert: + - name: "{{ nxos_int1 }}" + ipv4: + - address: 203.0.113.67/26 + - name: "{{ nxos_int2 }}" + ipv4: + - address: 198.51.100.10/24 + tag: 7 + - address: 198.51.100.130/25 + secondary: true + tag: 11 + - name: "{{ nxos_int3 }}" + ipv6: + - address: 2001:db8::20/32 + tag: 6 + + - name: Apply the provided configuration (config to be reverted) + register: result + cisco.nxos.nxos_l3_interfaces: + config: "{{ config_to_revert + mgmt }}" + state: overridden + + - ansible.builtin.assert: + that: + - result.changed == true + + - name: Revert back to base configuration using facts round trip + register: revert + cisco.nxos.nxos_l3_interfaces: + config: "{{ ansible_facts['network_resources']['l3_interfaces'] }}" + state: overridden + + - ansible.builtin.assert: + that: + - base_config['after'] == revert['after'] + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: END nxos_l3_interfaces round trip integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/vars/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/vars/main.yml new file mode 100644 index 00000000..db2e9700 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_l3_interfaces/vars/main.yml @@ -0,0 +1,66 @@ +--- +gathered: + - name: "{{ nxos_int1 }}" + ipv4: + - address: 192.0.2.100/24 + - name: "{{ nxos_int2 }}" + ipv4: + - address: 203.0.113.10/24 + ipv6: + - address: 2001:db8::1/32 + redirects: false + unreachables: true + +rendered: + - "interface Ethernet1/800" + - "ip address 192.168.1.100/24 tag 5" + - "ip address 10.1.1.1/24 secondary tag 10" + - "interface Ethernet1/800" + - "ipv6 address fd5d:12c9:2201:2::1/64 tag 6" + +parsed: + - name: Ethernet1/800 + ipv4: + - address: 192.168.1.100/24 + tag: 5 + - address: 10.1.1.1/24 + secondary: true + tag: 10 + redirects: false + - name: Ethernet1/801 + ipv6: + - address: fd5d:12c9:2201:2::1/64 + tag: 6 + unreachables: true + - name: mgmt0 + ipv4: + - address: dhcp + +rendered_multi: + - "interface Ethernet1/800" + - "ip address 192.168.1.100/24 tag 5" + - "ip address 10.1.1.1/24 secondary tag 10" + - "evpn multisite fabric-tracking" + - "interface Ethernet1/800" + - "ipv6 address fd5d:12c9:2201:2::1/64 tag 6" + - "evpn multisite dci-tracking" + +parsed_multi: + - name: Ethernet1/800 + ipv4: + - address: 192.168.1.100/24 + tag: 5 + - address: 10.1.1.1/24 + secondary: true + tag: 10 + redirects: false + evpn_multisite_tracking: fabric-tracking + - name: Ethernet1/801 + ipv6: + - address: fd5d:12c9:2201:2::1/64 + tag: 6 + unreachables: true + evpn_multisite_tracking: dci-tracking + - name: mgmt0 + ipv4: + - address: dhcp diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/defaults/main.yaml new file mode 100644 index 00000000..871ea460 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "[^_].*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tasks/cli.yaml new file mode 100644 index 00000000..9e4fb34b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tasks/main.yaml new file mode 100644 index 00000000..8d0b9433 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tasks/main.yaml @@ -0,0 +1,9 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tasks/nxapi.yaml new file mode 100644 index 00000000..5cb76e67 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tests/common/_populate_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tests/common/_populate_config.yaml new file mode 100644 index 00000000..cd6aa0b7 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tests/common/_populate_config.yaml @@ -0,0 +1,6 @@ +--- +# The CI NX-OS image doesn't support `lacp system-mac` +- name: Setup + cisco.nxos.nxos_config: + lines: + - "lacp system-priority 10" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tests/common/_remove_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tests/common/_remove_config.yaml new file mode 100644 index 00000000..47b88045 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tests/common/_remove_config.yaml @@ -0,0 +1,6 @@ +--- +- name: Remove existing lacp configuration + cisco.nxos.nxos_config: + lines: + - "no lacp system-priority" + ignore_errors: true diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tests/common/deleted.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tests/common/deleted.yaml new file mode 100644 index 00000000..b2183ea0 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tests/common/deleted.yaml @@ -0,0 +1,71 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_lacp deleted integration tests connection={{ ansible_connection }} + +- name: Enable 'feature lacp' + cisco.nxos.nxos_feature: + feature: lacp + +- name: Set a fact for 'mac' + ansible.builtin.set_fact: + mac: lacp system-mac 00c1.4c00.bd15 role primary + when: platform is search('N9K') and imagetag is not search('I[2-6]') + +- block: + - name: Setup + cisco.nxos.nxos_config: + lines: lacp system-priority 11 + + - name: Setup + cisco.nxos.nxos_config: + lines: "{{ mac|default(omit) }}" + + - name: Gather lacp facts + cisco.nxos.nxos_facts: &id001 + gather_subset: + - "!all" + - "!min" + gather_network_resources: lacp + + - name: Deleted + register: result + cisco.nxos.nxos_lacp: &id002 + state: deleted + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.lacp == result.before + - "'no lacp system-priority' in result.commands" + - result.changed == true + - result.commands|length == 1 + when: platform is not search('N9K') + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.lacp == result.before + - "'no lacp system-priority' in result.commands" + - "'no lacp system-mac' in result.commands" + - result.changed == true + - result.commands|length == 2 + when: platform is search('N9K') and imagetag is not search('I[2-6]') + + - name: Gather lacp post facts + cisco.nxos.nxos_facts: *id001 + + - ansible.builtin.assert: + that: + - result.after|length == 0 + + - name: Idempotence - deleted + register: result + cisco.nxos.nxos_lacp: *id002 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + always: + - name: Teardown + cisco.nxos.nxos_feature: + feature: lacp + state: disabled diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tests/common/empty_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tests/common/empty_config.yaml new file mode 100644 index 00000000..04f9a86a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tests/common/empty_config.yaml @@ -0,0 +1,50 @@ +--- +- ansible.builtin.debug: + msg: START nxos_lacp empty_config integration tests on connection={{ ansible_connection }} + +- name: Merged with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_lacp: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_lacp: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Rendered with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_lacp: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' + +- name: Parsed with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_lacp: + running_config: + state: parsed + +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state parsed' + +- ansible.builtin.debug: + msg: END nxos_lacp empty_config integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tests/common/gathered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tests/common/gathered.yaml new file mode 100644 index 00000000..a4367890 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tests/common/gathered.yaml @@ -0,0 +1,30 @@ +--- +- ansible.builtin.debug: + msg: START nxos_lacp gathered integration tests on connection={{ ansible_connection }} + +- name: Enable lacp + cisco.nxos.nxos_feature: + feature: lacp + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Gather lacp facts from the device using nxos_lacp + register: result + cisco.nxos.nxos_lacp: + state: gathered + + - ansible.builtin.assert: + that: "{{ result['gathered'] == gathered }}" + always: + - ansible.builtin.include_tasks: _remove_config.yaml + + - name: Teardown + cisco.nxos.nxos_feature: + feature: lacp + state: disabled + + - ansible.builtin.debug: + msg: END nxos_lacp gathered integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tests/common/merged.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tests/common/merged.yaml new file mode 100644 index 00000000..06587a28 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tests/common/merged.yaml @@ -0,0 +1,66 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_lacp merged integration tests connection={{ ansible_connection }} + +- name: Enable lacp + cisco.nxos.nxos_feature: + feature: lacp + +- name: Set a fact for 'mac' + ansible.builtin.set_fact: + mac: + address: 00c1.4c00.bd15 + role: primary + when: platform is search('N9K') and imagetag is not search('I[2-6]') + +- block: + - name: Merged + register: result + cisco.nxos.nxos_lacp: &id001 + config: + system: + priority: 11 + mac: "{{ mac|default(omit) }}" + state: merged + + - ansible.builtin.assert: + that: + - result.before|length == 0 + - result.changed == true + - "'lacp system-priority 11' in result.commands" + - "'lacp system-mac 00c1.4c00.bd15 role primary' in result.commands" + - result.commands|length == 2 + when: platform is search('N9K') and imagetag is not search('I[2-6]') + + - ansible.builtin.assert: + that: + - result.before|length == 0 + - result.changed == true + - "'lacp system-priority 11' in result.commands" + - result.commands|length == 1 + when: platform is not search('N9K') + + - name: Gather lacp facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: lacp + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.lacp == result.after + + - name: Idempotence - merged + register: result + cisco.nxos.nxos_lacp: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + always: + - name: Teardown + cisco.nxos.nxos_feature: + feature: lacp + state: disabled diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tests/common/parsed.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tests/common/parsed.yaml new file mode 100644 index 00000000..b7514176 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tests/common/parsed.yaml @@ -0,0 +1,18 @@ +--- +- ansible.builtin.debug: + msg: START nxos_lacp parsed integration tests on connection={{ ansible_connection }} + +- block: + - name: Use parsed state to convert externally supplied configuration to structured format + register: result + cisco.nxos.nxos_lacp: + running_config: | + lacp system-priority 10 + lacp system-mac 00c1.4c00.bd15 role secondary + state: parsed + + - ansible.builtin.assert: + that: "{{ parsed == result['parsed'] }}" + +- ansible.builtin.debug: + msg: END nxos_lacp parsed integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tests/common/rendered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tests/common/rendered.yaml new file mode 100644 index 00000000..a05e5e47 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tests/common/rendered.yaml @@ -0,0 +1,34 @@ +--- +- ansible.builtin.debug: + msg: START nxos_lacp rendered integration tests on connection={{ ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- block: + - name: Use rendered state to convert task input to device specific commands + register: result + cisco.nxos.nxos_lacp: + config: + system: + priority: 10 + mac: + address: 00c1.4c00.bd15 + role: secondary + state: rendered + + - ansible.builtin.assert: + that: "{{ rendered | symmetric_difference(result['rendered']) |length==0 }}" + + - name: Gather lacp facts from the device and assert that its empty + register: result + cisco.nxos.nxos_lacp: + state: gathered + + - name: Make sure that rendered task actually did not make any changes to the device + ansible.builtin.assert: + that: "{{ result['gathered'] == {} }}" + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: END nxos_lacp rendered integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tests/common/replaced.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tests/common/replaced.yaml new file mode 100644 index 00000000..d48d2d85 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/tests/common/replaced.yaml @@ -0,0 +1,104 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_lacp replaced integration tests connection={{ ansible_connection }} + +- name: Enable 'feature lacp' + cisco.nxos.nxos_feature: + feature: lacp + +- name: Set a fact for 'mac1' and 'mac2' + ansible.builtin.set_fact: + mac1: lacp system-mac 00c1.4c00.bd20 role primary + mac2: + address: 00c1.4c00.bd15 + role: secondary + when: platform is search('N9K') and imagetag is not search('I[2-6]') + +- block: + - name: Setup1 + cisco.nxos.nxos_config: + lines: lacp system-priority 11 + + - name: Setup2 + cisco.nxos.nxos_config: + lines: "{{ mac1|default(omit) }}" + + - name: Gather lacp facts + cisco.nxos.nxos_facts: &id001 + gather_subset: + - "!all" + - "!min" + gather_network_resources: lacp + + - name: Replaced + register: result + cisco.nxos.nxos_lacp: &id002 + config: + system: + priority: 12 + mac: "{{ mac2|default(omit) }}" + state: replaced + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.lacp == result.before + - result.changed == true + - result.commands|length == 2 + - "'no lacp system-priority' in result.commands" + - "'lacp system-priority 12' in result.commands" + when: platform is not search('N9K') + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.lacp == result.before + - result.changed == true + - "'no lacp system-priority' in result.commands" + - "'no lacp system-mac' in result.commands" + - "'lacp system-priority 12' in result.commands" + - "'lacp system-mac 00c1.4c00.bd15 role secondary' in result.commands" + - result.commands|length == 4 + when: platform is search('N9K') and imagetag is not search('I[2-6]') + + - name: Gather lacp interfaces post facts + cisco.nxos.nxos_facts: *id001 + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.lacp == result.after + when: platform is search('N9K') and imagetag is not search('I[2-6]') + + - name: Idempotence - replaced + register: result + cisco.nxos.nxos_lacp: *id002 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + + - name: Setup3 + cisco.nxos.nxos_config: + lines: "{{ mac1|default(omit) }}" + + - name: Replaced + register: result + when: platform is search('N9K') and imagetag is not search('I[2-6]') + cisco.nxos.nxos_lacp: + config: + system: + priority: 1 + state: replaced + + - ansible.builtin.assert: + that: + - result.changed == true + - result.commands|length == 3 + - "'no lacp system-mac' in result.commands" + - "'no lacp system-priority' in result.commands" + - "'lacp system-priority 1' in result.commands" + when: platform is search('N9K') and imagetag is not search('I[2-6]') + always: + - name: Teardown + cisco.nxos.nxos_feature: + feature: lacp + state: disabled diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/vars/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/vars/main.yml new file mode 100644 index 00000000..8b5bd3db --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp/vars/main.yml @@ -0,0 +1,19 @@ +--- +# The CI NX-OS image doesn't support `lacp system-mac` +gathered: + system: + priority: 10 + +# using mac related configs in parsed and rendered would also +# prove that we're not connecting to the appliance as expected + +rendered: + - "lacp system-priority 10" + - "lacp system-mac 00c1.4c00.bd15 role secondary" + +parsed: + system: + priority: 10 + mac: + address: 00c1.4c00.bd15 + role: secondary diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/defaults/main.yaml new file mode 100644 index 00000000..871ea460 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "[^_].*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tasks/cli.yaml new file mode 100644 index 00000000..9e4fb34b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tasks/main.yaml new file mode 100644 index 00000000..8d0b9433 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tasks/main.yaml @@ -0,0 +1,9 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tasks/nxapi.yaml new file mode 100644 index 00000000..18bf1b6e --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tasks/nxapi.yaml @@ -0,0 +1,31 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tests/common/_populate_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tests/common/_populate_config.yaml new file mode 100644 index 00000000..3e3f94ac --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tests/common/_populate_config.yaml @@ -0,0 +1,14 @@ +--- +- name: Populate configuration + cisco.nxos.nxos_config: + lines: + - "feature lacp" + - "interface {{ nxos_int1 }}" + - " lacp port-priority 5" + - " lacp rate fast" + - "interface port-channel10" + - " switchport" + - " lacp mode delay" + - "interface port-channel11" + - " lacp max-bundle 10" + - " lacp min-links 5" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tests/common/_remove_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tests/common/_remove_config.yaml new file mode 100644 index 00000000..e579913a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tests/common/_remove_config.yaml @@ -0,0 +1,11 @@ +--- +- name: Remove configuration + cisco.nxos.nxos_config: + lines: + - "no interface port-channel5" + - "no interface port-channel10" + - "no interface port-channel11" + - "default interface {{ nxos_int1 }}" + - "default interface {{ nxos_int2 }}" + - "no feature lacp" + ignore_errors: true diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tests/common/deleted.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tests/common/deleted.yaml new file mode 100644 index 00000000..c38b3ef2 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tests/common/deleted.yaml @@ -0,0 +1,77 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_lacp_interfaces deleted integration tests connection={{ ansible_connection }} + +- name: Set a fact for 'mode' + ansible.builtin.set_fact: + mode: delay + when: >- + platform is not search('N3K|N5K|N6K|N7K') and + imagetag is not search('A8|I2') and + image_version is not search ('9.2') and + chassis_type is not search('C95') + +- name: Setup1 + cisco.nxos.nxos_config: &id002 + lines: + - "no interface port-channel5" + - "no interface port-channel10" + - "no feature lacp" + +- block: + - name: Setup2 + cisco.nxos.nxos_config: + lines: + - "feature lacp" + - "interface port-channel5" + - "lacp min-links 5" + - "interface port-channel10" + - " lacp max-bundle 10" + + - name: Setup3 - layer 2 for mode command + when: mode is defined + cisco.nxos.nxos_config: + lines: + - "interface port-channel10" + - " switchport" + - " lacp mode delay" + + - name: Gather lacp_interfaces facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: lacp_interfaces + + - name: Deleted + register: result + cisco.nxos.nxos_lacp_interfaces: &id001 + state: deleted + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.lacp_interfaces|symmetric_difference(result.before)|length == 0 + - result.after|length == 0 + - result.changed == true + - "'interface port-channel5' in result.commands" + - "'no lacp min-links' in result.commands" + - "'interface port-channel10' in result.commands" + - "'no lacp max-bundle' in result.commands" + + - ansible.builtin.assert: + that: + - "'no lacp mode delay' in result.commands" + - result.commands|length == 5 + when: mode is defined + + - name: Idempotence - deleted + register: result + cisco.nxos.nxos_lacp_interfaces: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + always: + - name: Teardown + cisco.nxos.nxos_config: *id002 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tests/common/empty_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tests/common/empty_config.yaml new file mode 100644 index 00000000..80634f8c --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tests/common/empty_config.yaml @@ -0,0 +1,61 @@ +--- +- ansible.builtin.debug: + msg: START nxos_lacp_interfaces empty_config integration tests on connection={{ ansible_connection }} + +- name: Merged with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_lacp_interfaces: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_lacp_interfaces: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Overridden with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_lacp_interfaces: + config: + state: overridden + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Rendered with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_lacp_interfaces: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' + +- name: Parsed with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_lacp_interfaces: + running_config: + state: parsed + +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state parsed' + +- ansible.builtin.debug: + msg: END nxos_lacp_interfaces empty_config integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tests/common/gathered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tests/common/gathered.yaml new file mode 100644 index 00000000..dc9daf86 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tests/common/gathered.yaml @@ -0,0 +1,21 @@ +--- +- ansible.builtin.debug: + msg: START nxos_lacp_interfaces gathered integration tests on connection={{ ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Gather lacp_interfaces facts from the device using nxos_lacp_interfaces + register: result + cisco.nxos.nxos_lacp_interfaces: + state: gathered + + - ansible.builtin.assert: + that: "{{ result['gathered'] | symmetric_difference(gathered) |length == 0 }}" + always: + - ansible.builtin.include_tasks: _remove_config.yaml + + - ansible.builtin.debug: + msg: END nxos_lacp_interfaces gathered integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tests/common/merged.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tests/common/merged.yaml new file mode 100644 index 00000000..ee01bc24 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tests/common/merged.yaml @@ -0,0 +1,84 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_lacp_interfaces merged integration tests connection={{ ansible_connection }} + +- name: Set a fact for 'mode' + ansible.builtin.set_fact: + mode: delay + when: >- + platform is not search('N3K|N5K|N6K|N7K') and + imagetag is not search('A8|I2') and + image_version is not search ('9.2') and + chassis_type is not search('C95') + +- name: Setup1 + cisco.nxos.nxos_config: &id002 + lines: + - "no interface port-channel5" + - "no interface port-channel10" + - "no feature lacp" + +- block: + - name: Setup2 + cisco.nxos.nxos_config: + lines: + - "feature lacp" + + - name: Setup3 - layer 2 for mode command + when: mode is defined + cisco.nxos.nxos_config: + lines: + - "interface port-channel5" + - " switchport" + + - name: Merged + register: result + cisco.nxos.nxos_lacp_interfaces: &id001 + config: + - name: port-channel10 + links: + min: 5 + + - name: port-channel5 + mode: "{{ mode | default(omit) }}" + links: + max: 10 + state: merged + + - ansible.builtin.assert: + that: + - result.changed == true + - result.before|length == 0 + - "'interface port-channel10' in result.commands" + - "'lacp min-links 5' in result.commands" + - "'interface port-channel5' in result.commands" + - "'lacp max-bundle 10' in result.commands" + + - ansible.builtin.assert: + that: + - "'lacp mode delay' in result.commands" + - result.commands|length == 5 + when: mode is defined + + - name: Gather lacp_interfaces facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: lacp_interfaces + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.lacp_interfaces|symmetric_difference(result.after)|length == 0 + + - name: Idempotence - merged + register: result + cisco.nxos.nxos_lacp_interfaces: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + always: + - name: Teardown + cisco.nxos.nxos_config: *id002 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tests/common/overridden.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tests/common/overridden.yaml new file mode 100644 index 00000000..e3dfb838 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tests/common/overridden.yaml @@ -0,0 +1,89 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_lacp_interfaces overridden integration tests connection={{ ansible_connection }} + +- name: Set a fact for 'mode' + ansible.builtin.set_fact: + mode: delay + when: >- + platform is not search('N3K|N5K|N6K|N7K') and + imagetag is not search('A8|I2') and + image_version is not search ('9.2') and + chassis_type is not search('C95') + +- name: Setup1 + cisco.nxos.nxos_config: &id003 + lines: + - "no interface port-channel5" + - "no interface port-channel10" + - "no interface port-channel11" + - "no feature lacp" + +- block: + - name: Setup2 + cisco.nxos.nxos_config: + lines: + - "feature lacp" + - "interface port-channel10" + - "lacp min-links 5" + - "interface port-channel5" + - " lacp max-bundle 10" + + - name: Setup3 - layer 2 for mode command + when: mode is defined + cisco.nxos.nxos_config: + lines: + - "interface port-channel11" + - " switchport" + + - name: Gather lacp_interfaces facts + cisco.nxos.nxos_facts: &id001 + gather_subset: + - "!all" + - "!min" + gather_network_resources: lacp_interfaces + + - name: Overridden + register: result + cisco.nxos.nxos_lacp_interfaces: &id002 + config: + - name: port-channel11 + links: + min: 4 + mode: "{{ mode | default(omit) }}" + state: overridden + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.lacp_interfaces|symmetric_difference(result.before)|length == 0 + - result.changed == true + - "'interface port-channel10' in result.commands" + - "'no lacp min-links' in result.commands" + - "'interface port-channel5' in result.commands" + - "'no lacp max-bundle' in result.commands" + - "'interface port-channel11' in result.commands" + + - ansible.builtin.assert: + that: + - "'lacp mode delay' in result.commands" + - result.commands|length == 7 + when: mode is defined + + - name: Gather lacp_interfaces post facts + cisco.nxos.nxos_facts: *id001 + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.lacp_interfaces|symmetric_difference(result.after)|length == 0 + + - name: Idempotence - overridden + register: result + cisco.nxos.nxos_lacp_interfaces: *id002 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + always: + - name: Teardown + cisco.nxos.nxos_config: *id003 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tests/common/parsed.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tests/common/parsed.yaml new file mode 100644 index 00000000..37f24b20 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tests/common/parsed.yaml @@ -0,0 +1,26 @@ +--- +- ansible.builtin.debug: + msg: START nxos_lacp_interfaces parsed integration tests on connection={{ ansible_connection }} + +- block: + # Ethernet interface used in the task don't actually exist on the appliance + - name: Use parsed state to convert externally supplied configuration to structured format + register: result + cisco.nxos.nxos_lacp_interfaces: + running_config: | + interface nve1 + source-interface Ethernet1/100 + interface port-channel10 + lacp min-links 10 + lacp max-bundle 15 + interface Ethernet1/800 + lacp port-priority 100 + lacp rate fast + description interface + state: parsed + + - ansible.builtin.assert: + that: "{{ parsed | symmetric_difference(result['parsed']) |length==0 }}" + +- ansible.builtin.debug: + msg: END nxos_lacp_interfaces parsed integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tests/common/rendered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tests/common/rendered.yaml new file mode 100644 index 00000000..f5419dfb --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tests/common/rendered.yaml @@ -0,0 +1,41 @@ +--- +- ansible.builtin.debug: + msg: START nxos_lacp_interfaces rendered integration tests on connection={{ ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- block: + # Interfaces used here doesn't actually exist on the device + - name: Use rendered state to convert task input to device specific commands + register: result + nxos_lacp_interfaces: + config: + - name: Ethernet1/800 + rate: fast + - name: Ethernet1/801 + rate: fast + port_priority: 32 + - name: port-channel10 + links: + max: 15 + min: 2 + convergence: + graceful: true + state: rendered + + - ansible.builtin.assert: + that: "{{ rendered | symmetric_difference(result['rendered']) |length==0 }}" + + - name: Gather lacp_interfaces facts from the device and assert that its empty + register: result + cisco.nxos.nxos_lacp_interfaces: + state: gathered + + - name: Make sure that rendered + ansible.builtin.assert: + that: "{{ result['gathered'] == [] }}" + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: END nxos_lacp_interfaces rendered integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tests/common/replaced.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tests/common/replaced.yaml new file mode 100644 index 00000000..f7627478 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/tests/common/replaced.yaml @@ -0,0 +1,77 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_lacp_interfaces replaced integration tests connection={{ ansible_connection }} + +- name: Set a fact for 'mode' + ansible.builtin.set_fact: + mode: delay + when: >- + platform is not search('N3K|N5K|N6K|N7K') and + imagetag is not search('A8|I2') and + image_version is not search ('9.2') and + chassis_type is not search('C95') + +- name: Setup1 + cisco.nxos.nxos_config: &id003 + lines: + - "no interface port-channel10" + - "no feature lacp" + +- block: + - name: Setup2 + cisco.nxos.nxos_config: + lines: + - "feature lacp" + - "interface port-channel10" + - "switchport" + - " lacp min-links 5" + + - name: Gather lacp_interfaces facts + cisco.nxos.nxos_facts: &id001 + gather_subset: + - "!all" + - "!min" + gather_network_resources: lacp_interfaces + + - name: Replaced + register: result + cisco.nxos.nxos_lacp_interfaces: &id002 + config: + - name: port-channel10 + links: + max: 10 + mode: "{{ mode | default(omit) }}" + state: replaced + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.lacp_interfaces|symmetric_difference(result.before)|length == 0 + - result.changed == true + - "'interface port-channel10' in result.commands" + - "'no lacp min-links' in result.commands" + - "'lacp max-bundle 10' in result.commands" + + - ansible.builtin.assert: + that: + - "'lacp mode delay' in result.commands" + - result.commands|length == 4 + when: mode is defined + + - name: Gather lacp_interfaces post facts + cisco.nxos.nxos_facts: *id001 + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.lacp_interfaces|symmetric_difference(result.after)|length == 0 + + - name: Idempotence - replaced + register: result + cisco.nxos.nxos_lacp_interfaces: *id002 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + always: + - name: Teardown + cisco.nxos.nxos_config: *id003 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/vars/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/vars/main.yml new file mode 100644 index 00000000..633e5a08 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lacp_interfaces/vars/main.yml @@ -0,0 +1,31 @@ +--- +gathered: + - name: "{{ nxos_int1 }}" + port_priority: 5 + rate: fast + - name: port-channel10 + mode: delay + - name: port-channel11 + links: + max: 10 + min: 5 + +parsed: + - name: port-channel10 + links: + max: 15 + min: 10 + - name: Ethernet1/800 + port_priority: 100 + rate: fast + +rendered: + - "interface Ethernet1/800" + - "lacp rate fast" + - "interface Ethernet1/801" + - "lacp port-priority 32" + - "lacp rate fast" + - "interface port-channel10" + - "lacp min-links 2" + - "lacp max-bundle 15" + - "lacp graceful-convergence" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/defaults/main.yaml new file mode 100644 index 00000000..871ea460 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "[^_].*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tasks/cli.yaml new file mode 100644 index 00000000..9e4fb34b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tasks/main.yaml new file mode 100644 index 00000000..bf71b999 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tasks/main.yaml @@ -0,0 +1,19 @@ +--- +- name: Set system defaults for switchports + cisco.nxos.nxos_config: + lines: "system default switchport" + connection: ansible.netcommon.network_cli + +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi + +- name: Set system defaults for switchports + cisco.nxos.nxos_config: + lines: "no system default switchport" + connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tasks/nxapi.yaml new file mode 100644 index 00000000..18bf1b6e --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tasks/nxapi.yaml @@ -0,0 +1,31 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tests/common/_populate_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tests/common/_populate_config.yaml new file mode 100644 index 00000000..4715592e --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tests/common/_populate_config.yaml @@ -0,0 +1,9 @@ +--- +- name: Populate configuration + cisco.nxos.nxos_config: + lines: + - "feature lacp" + - "interface {{ nxos_int1 }}" + - " channel-group 10 mode active" + - "interface {{ nxos_int2 }}" + - " channel-group 11 mode passive" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tests/common/_remove_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tests/common/_remove_config.yaml new file mode 100644 index 00000000..59c0f3b3 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tests/common/_remove_config.yaml @@ -0,0 +1,12 @@ +--- +- name: Remove configuration + cisco.nxos.nxos_config: + lines: + - "default interface {{ nxos_int1 }}" + - "default interface {{ nxos_int2 }}" + - "no interface port-channel10" + - "no interface port-channel11" + - "no interface port-channel19" + - "no interface port-channel20" + - "no feature lacp" + ignore_errors: true diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tests/common/deleted.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tests/common/deleted.yaml new file mode 100644 index 00000000..e1deb531 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tests/common/deleted.yaml @@ -0,0 +1,67 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_lag_interfaces deleted integration tests connection={{ ansible_connection }} + +- name: Set a fact for 'test_int1' + ansible.builtin.set_fact: + test_int1: "{{ nxos_int1 }}" + +- name: Set a fact for 'test_int2' + ansible.builtin.set_fact: + test_int2: "{{ nxos_int2 }}" + +- ansible.builtin.include_tasks: _remove_config.yaml + +- name: Enable 'feature lacp' + cisco.nxos.nxos_feature: + feature: lacp + +- block: + - name: Setup2 + loop: + - interface {{ test_int1 }} + - interface {{ test_int2 }} + cisco.nxos.nxos_config: + lines: + - channel-group 10 + parents: "{{ item }}" + + - name: Gather lag interfaces facts + cisco.nxos.nxos_facts: &id001 + gather_subset: + - "!all" + - "!min" + gather_network_resources: lag_interfaces + + - name: Deleted + register: result + cisco.nxos.nxos_lag_interfaces: &id002 + state: deleted + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.lag_interfaces|symmetric_difference(result.before)|length == 0 + + - name: Gather lag interfaces post facts + cisco.nxos.nxos_facts: *id001 + + - ansible.builtin.assert: + that: + # the module should not remove the implicitly created port-channel + - result.after|length == 1 + - result.changed == true + + - name: Idempotence - deleted + register: result + cisco.nxos.nxos_lag_interfaces: *id002 + + - ansible.builtin.assert: + that: + - result.changed == false + always: + - ansible.builtin.include_tasks: _remove_config.yaml + + - name: Disable 'feature lacp' + cisco.nxos.nxos_feature: + feature: lacp + state: disabled diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tests/common/empty_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tests/common/empty_config.yaml new file mode 100644 index 00000000..558f53eb --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tests/common/empty_config.yaml @@ -0,0 +1,61 @@ +--- +- ansible.builtin.debug: + msg: START nxos_lag_interfaces empty_config integration tests on connection={{ ansible_connection }} + +- name: Merged with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_lag_interfaces: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_lag_interfaces: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Overridden with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_lag_interfaces: + config: + state: overridden + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Rendered with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_lag_interfaces: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' + +- name: Parsed with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_lag_interfaces: + running_config: + state: parsed + +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state parsed' + +- ansible.builtin.debug: + msg: END nxos_lag_interfaces empty_config integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tests/common/gathered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tests/common/gathered.yaml new file mode 100644 index 00000000..56a91dc5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tests/common/gathered.yaml @@ -0,0 +1,21 @@ +--- +- ansible.builtin.debug: + msg: START nxos_lag_interfaces gathered integration tests on connection={{ ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Gather lag_interfaces facts from the device using nxos_lag_interfaces + register: result + cisco.nxos.nxos_lag_interfaces: + state: gathered + + - ansible.builtin.assert: + that: "{{ result['gathered'] | symmetric_difference(gathered) |length == 0 }}" + always: + - ansible.builtin.include_tasks: _remove_config.yaml + + - ansible.builtin.debug: + msg: END nxos_lag_interfaces gathered integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tests/common/merged.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tests/common/merged.yaml new file mode 100644 index 00000000..96b74273 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tests/common/merged.yaml @@ -0,0 +1,105 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_lag_interfaces merged integration tests connection={{ ansible_connection }} + +- name: Set a fact for 'test_int1' + ansible.builtin.set_fact: + test_int1: "{{ nxos_int1 }}" + +- name: Set a fact for 'test_int2' + ansible.builtin.set_fact: + test_int2: "{{ nxos_int2 }}" + +- name: Enable 'feature lacp' + cisco.nxos.nxos_feature: + feature: lacp + +- name: Setup + ignore_errors: true + cisco.nxos.nxos_config: + lines: + - no interface port-channel 10 + - no interface port-channel 11 + - no interface port-channel 19 + - no interface port-channel 20 + +- name: Setup2 + cisco.nxos.nxos_lag_interfaces: &id003 + state: deleted + +- block: + - name: Merged + register: result + cisco.nxos.nxos_lag_interfaces: &id001 + config: + - name: port-channel10 + members: + - member: "{{ test_int1 }}" + + - member: "{{ test_int2 }}" + mode: true + state: merged + + - ansible.builtin.assert: + that: + - result.before|length == 0 + - result.changed == true + + - name: Gather lag interfaces facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: lag_interfaces + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.lag_interfaces|symmetric_difference(result.after)|length == 0 + + - name: Idempotence - merged + register: result + cisco.nxos.nxos_lag_interfaces: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + + - name: Add new port-channel with no members + ignore_errors: true + cisco.nxos.nxos_config: + lines: + - interface port-channel 11 + + - name: Merged - no members + register: result + cisco.nxos.nxos_lag_interfaces: &id002 + config: + - name: port-channel11 + members: + - member: "{{ test_int1 }}" + + - member: "{{ test_int2 }}" + mode: true + state: merged + + - ansible.builtin.assert: + that: + - result.changed == true + + - name: Idempotence - merged - no members + register: result + cisco.nxos.nxos_lag_interfaces: *id002 + + - ansible.builtin.assert: + that: + - result.changed == false + + always: + - name: Teardown + ignore_errors: true + cisco.nxos.nxos_lag_interfaces: *id003 + + - name: Disable 'feature lacp' + cisco.nxos.nxos_feature: + feature: lacp + state: disabled diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tests/common/overridden.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tests/common/overridden.yaml new file mode 100644 index 00000000..f2bafafb --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tests/common/overridden.yaml @@ -0,0 +1,105 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_lag_interfaces overridden integration tests connection={{ ansible_connection }} + +- name: Set a fact for 'test_int1', 'test_int2', and 'test_int3' + ansible.builtin.set_fact: + test_int1: "{{ nxos_int1 }}" + test_int2: "{{ nxos_int2 }}" + test_int3: "{{ nxos_int3 }}" + +- name: Enable 'feature lacp' + cisco.nxos.nxos_feature: + feature: lacp + +- name: Setup1 + ignore_errors: true + cisco.nxos.nxos_config: + lines: + - no interface port-channel 10 + - no interface port-channel 19 + - no interface port-channel 20 + +- name: Setup2 + cisco.nxos.nxos_lag_interfaces: &id003 + state: deleted + +- block: + - name: Setup3 + ignore_errors: true + loop: + - interface {{ test_int1 }} + - interface {{ test_int2 }} + cisco.nxos.nxos_config: + lines: + - channel-group 10 + parents: "{{ item }}" + + - name: Gather lag interfaces facts + cisco.nxos.nxos_facts: &id001 + gather_subset: + - "!all" + - "!min" + gather_network_resources: lag_interfaces + + - name: Overridden + register: result + cisco.nxos.nxos_lag_interfaces: &id002 + config: + - name: port-channel19 + members: + - member: "{{ test_int3 }}" + state: overridden + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.lag_interfaces|symmetric_difference(result.before)|length == 0 + - result.changed == true + + - name: Gather lag interfaces post facts + cisco.nxos.nxos_facts: *id001 + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.lag_interfaces|symmetric_difference(result.after)|length == 0 + + - name: Idempotence - overridden + register: result + cisco.nxos.nxos_lag_interfaces: *id002 + + - ansible.builtin.assert: + that: + - result.changed == false + + - name: Create port-channel20 + cisco.nxos.nxos_interfaces: + config: + - name: port-channel20 + description: Ansible Resource LAG + + - name: Add first member to port-channel using overridden + cisco.nxos.nxos_lag_interfaces: + config: + - name: port-channel20 + members: + - member: Ethernet1/9 + mode: active + force: true + state: overridden + register: result + + - ansible.builtin.assert: + that: + - "result.changed == True" + - "'interface Ethernet1/9' in result.commands" + - "'channel-group 20 force mode active' in result.commands" + + always: + - name: Teardown + ignore_errors: true + cisco.nxos.nxos_lag_interfaces: *id003 + + - name: Disable 'feature lacp' + cisco.nxos.nxos_feature: + feature: lacp + state: disabled diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tests/common/parsed.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tests/common/parsed.yaml new file mode 100644 index 00000000..681902bb --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tests/common/parsed.yaml @@ -0,0 +1,29 @@ +--- +- ansible.builtin.debug: + msg: START nxos_lag_interfaces parsed integration tests on connection={{ ansible_connection }} + +- block: + # Interfaces used in the task don't actually exist on the appliance + - name: Use parsed state to convert externally supplied configuration to structured format + register: result + cisco.nxos.nxos_lag_interfaces: + running_config: | + interface port-channel10 + interface port-channel11 + interface port-channel12 + interface Ethernet1/800 + channel-group 10 + no shutdown + interface Ethernet1/801 + channel-group 10 mode active + interface Ethernet1/802 + channel-group 11 mode passive + interface Ethernet1/803 + channel-group 11 mode passive + state: parsed + + - ansible.builtin.assert: + that: "{{ parsed | symmetric_difference(result['parsed']) |length==0 }}" + +- ansible.builtin.debug: + msg: END nxos_lag_interfaces parsed integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tests/common/rendered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tests/common/rendered.yaml new file mode 100644 index 00000000..10297832 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tests/common/rendered.yaml @@ -0,0 +1,39 @@ +--- +- ansible.builtin.debug: + msg: START nxos_lag_interfaces rendered integration tests on connection={{ ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- block: + # Interfaces used here doesn't actually exist on the device + - name: Use rendered state to convert task input to device specific commands + register: result + cisco.nxos.nxos_lag_interfaces: + config: + - name: port-channel10 + members: + - member: Ethernet1/800 + mode: active + - member: Ethernet1/801 + - name: port-channel11 + members: + - member: Ethernet1/802 + mode: passive + state: rendered + + - ansible.builtin.assert: + that: "{{ rendered | symmetric_difference(result['rendered']) |length==0 }}" + + - name: Gather l2_interfaces facts from the device and assert that its empty + register: result + cisco.nxos.nxos_lag_interfaces: + state: gathered + + - name: Make sure that rendered + ansible.builtin.assert: + that: "{{ result['gathered'] == [] }}" + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: END nxos_lag_interfaces rendered integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tests/common/replaced.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tests/common/replaced.yaml new file mode 100644 index 00000000..5461c2c1 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/tests/common/replaced.yaml @@ -0,0 +1,84 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_lag_interfaces replaced integration tests connection={{ ansible_connection }} + +- name: Set a fact for 'test_int1' + ansible.builtin.set_fact: + test_int1: "{{ nxos_int1 }}" + +- name: Set a fact for 'test_int2' + ansible.builtin.set_fact: + test_int2: "{{ nxos_int2 }}" + +- name: Enable 'feature lacp' + cisco.nxos.nxos_feature: + feature: lacp + +- name: Setup1 + ignore_errors: true + cisco.nxos.nxos_config: + lines: + - no interface port-channel 10 + - no interface port-channel 11 + - no interface port-channel 19 + - no interface port-channel 20 + +- name: Setup2 + cisco.nxos.nxos_lag_interfaces: &id003 + state: deleted + +- block: + - name: Setup3 + ignore_errors: true + loop: + - interface {{ test_int1 }} + - interface {{ test_int2 }} + cisco.nxos.nxos_config: + lines: + - channel-group 10 + parents: "{{ item }}" + + - name: Gather lag interfaces facts + cisco.nxos.nxos_facts: &id001 + gather_subset: + - "!all" + - "!min" + gather_network_resources: lag_interfaces + + - name: Replaced + register: result + cisco.nxos.nxos_lag_interfaces: &id002 + config: + - name: port-channel11 + members: + - member: "{{ test_int2 }}" + mode: active + state: replaced + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.lag_interfaces|symmetric_difference(result.before)|length == 0 + + - name: Gather lag interfaces post facts + cisco.nxos.nxos_facts: *id001 + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.lag_interfaces|symmetric_difference(result.after)|length == 0 + + - name: Idempotence - replaced + register: result + cisco.nxos.nxos_lag_interfaces: *id002 + + - ansible.builtin.assert: + that: + - result.changed == false + always: + - name: Teardown1 + ignore_errors: true + cisco.nxos.nxos_lag_interfaces: *id003 + + - name: Disable 'feature lacp' + cisco.nxos.nxos_feature: + feature: lacp + state: disabled diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/vars/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/vars/main.yml new file mode 100644 index 00000000..a82857b9 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lag_interfaces/vars/main.yml @@ -0,0 +1,34 @@ +--- +gathered: + - name: port-channel10 + members: + - member: "{{ nxos_int1 }}" + mode: active + - name: port-channel11 + members: + - member: "{{ nxos_int2 }}" + mode: passive + +rendered: + - "interface Ethernet1/800" + - "channel-group 10 mode active" + - "interface Ethernet1/801" + - "channel-group 10" + - "interface Ethernet1/802" + - "channel-group 11 mode passive" + +parsed: + - members: + - member: Ethernet1/800 + - member: Ethernet1/801 + mode: active + name: port-channel10 + + - members: + - member: Ethernet1/802 + mode: passive + - member: Ethernet1/803 + mode: passive + name: port-channel11 + + - name: port-channel12 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/defaults/main.yaml new file mode 100644 index 00000000..871ea460 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "[^_].*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/tasks/cli.yaml new file mode 100644 index 00000000..3bff5201 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yml" + use_regex: true + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/tasks/nxapi.yaml new file mode 100644 index 00000000..e0ebc3f5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/tasks/nxapi.yaml @@ -0,0 +1,31 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/tests/common/_populate_config.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/tests/common/_populate_config.yml new file mode 100644 index 00000000..a0d64f35 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/tests/common/_populate_config.yml @@ -0,0 +1,9 @@ +--- +- name: Populate configuration + cisco.nxos.nxos_config: + lines: + - "feature lldp" + - "lldp holdtime 129" + - "lldp reinit 5" + - "lldp timer 35" + - "no lldp tlv-select system-name" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/tests/common/_remove_config.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/tests/common/_remove_config.yml new file mode 100644 index 00000000..42a64ce4 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/tests/common/_remove_config.yml @@ -0,0 +1,6 @@ +--- +- name: Remove configuration + cisco.nxos.nxos_feature: + feature: lldp + state: disabled + ignore_errors: true diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/tests/common/deleted.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/tests/common/deleted.yml new file mode 100644 index 00000000..581197d7 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/tests/common/deleted.yml @@ -0,0 +1,83 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_lldp_global deleted integration tests connection = {{ ansible_connection }} + +- block: + - name: Set a fact for 'cfg_port_id' + ansible.builtin.set_fact: + cfg_port_id: true + when: platform is not search('N[567]K') and imagetag is not search("I[2345]") + + - name: Feature off to cleanup lldp + cisco.nxos.nxos_feature: &id003 + feature: lldp + state: disabled + + - name: Enable 'feature lldp' + cisco.nxos.nxos_feature: + feature: lldp + state: enabled + + - name: Setup + cisco.nxos.nxos_config: + lines: + - "lldp holdtime 125" + - "lldp timer 32" + - "no lldp tlv-select dcbxp" + - "lldp tlv-select system-name" + - "no lldp tlv-select system-description" + + - name: Setup2 + when: cfg_port_id is defined + cisco.nxos.nxos_config: + lines: + - "lldp portid-subtype 1" + - "no lldp tlv-select power-management" + + - name: Gather lldp_global facts + cisco.nxos.nxos_facts: &id001 + gather_subset: + - "!all" + - "!min" + gather_network_resources: lldp_global + + - name: Deleted + register: result + cisco.nxos.nxos_lldp_global: &id002 + state: deleted + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.lldp_global == result.before + - "'no lldp holdtime 125' in result.commands" + - "'no lldp timer 32' in result.commands" + - "'lldp tlv-select dcbxp' in result.commands" + - "'lldp tlv-select system-description' in result.commands" + - "result.changed == true " + - result.after | length == 0 + + - ansible.builtin.assert: + that: + - "'no lldp portid-subtype 1' in result.commands" + - "'lldp tlv-select power-management' in result.commands" + when: cfg_port_id is defined + + - name: Gather lldp_global post facts + cisco.nxos.nxos_facts: *id001 + + - ansible.builtin.assert: + that: + - "ansible_facts.network_resources == {} " + + - name: Idempotence - deleted + register: result + cisco.nxos.nxos_lldp_global: *id002 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + always: + - name: Teardown + cisco.nxos.nxos_feature: *id003 + when: platform is not search('N35') diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/tests/common/gathered.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/tests/common/gathered.yml new file mode 100644 index 00000000..2a7a4b48 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/tests/common/gathered.yml @@ -0,0 +1,22 @@ +--- +- ansible.builtin.debug: + msg: START nxos_lldp_global gathered integration tests on connection={{ ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yml + +- ansible.builtin.include_tasks: _populate_config.yml + +- block: + - name: Gather lldp_global facts from the device using nxos_lldp_global + register: result + cisco.nxos.nxos_lldp_global: + state: gathered + + - ansible.builtin.assert: + that: "{{ result['gathered'] == gathered }}" + + always: + - ansible.builtin.include_tasks: _remove_config.yml + + - ansible.builtin.debug: + msg: END nxos_lldp_global gathered integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/tests/common/merged.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/tests/common/merged.yml new file mode 100644 index 00000000..54833be4 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/tests/common/merged.yml @@ -0,0 +1,71 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_lldp_global merged integration tests connection={{ansible_connection}} + +- block: + - name: Set a fact for 'port_id' and 'tlv_power_mgmt' + ansible.builtin.set_fact: + port_id: 1 + tlv_power_mgmt: + power_management: false + when: platform is not search('N5K|N6K|N7K') and imagetag is not search("I[2345]") + + - name: Feature off to cleanup lldp + cisco.nxos.nxos_feature: &id002 + feature: lldp + state: disabled + + - name: Enable lldp + cisco.nxos.nxos_feature: + feature: lldp + + - name: Merged + register: result + cisco.nxos.nxos_lldp_global: &id001 + config: + reinit: 5 + timer: 40 + port_id: "{{port_id|default(omit)}}" + tlv_select: "{{tlv_power_mgmt|default(omit)}}" + state: merged + + - ansible.builtin.assert: + that: + - result.before|length == 0 + - result.changed == true + - "'lldp reinit 5' in result.commands" + - "'lldp timer 40' in result.commands" + + - ansible.builtin.assert: + that: + - "'lldp portid-subtype 1' in result.commands" + when: port_id is defined + + - ansible.builtin.assert: + that: + - "'no lldp tlv-select power-management' in result.commands" + when: tlv_power_mgmt is defined + + - name: Gather lldp_global facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: lldp_global + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.lldp_global == result.after + + - name: Idempotence - merged + register: result + cisco.nxos.nxos_lldp_global: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands | length == 0 + always: + - name: Teardown + cisco.nxos.nxos_feature: *id002 + when: platform is not search('N35') diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/tests/common/parsed.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/tests/common/parsed.yml new file mode 100644 index 00000000..ce8de23a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/tests/common/parsed.yml @@ -0,0 +1,20 @@ +--- +- ansible.builtin.debug: + msg: START nxos_lldp_global parsed integration tests on connection={{ ansible_connection }} + +- block: + - name: Use parsed state to convert externally supplied configuration to structured format + register: result + cisco.nxos.nxos_lldp_global: + running_config: | + lldp holdtime 131 + lldp reinit 7 + no lldp tlv-select system-name + no lldp tlv-select system-description + state: parsed + + - ansible.builtin.assert: + that: "{{ parsed == result['parsed'] }}" + +- ansible.builtin.debug: + msg: END nxos_lldp_global parsed integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/tests/common/rendered.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/tests/common/rendered.yml new file mode 100644 index 00000000..a3ab171a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/tests/common/rendered.yml @@ -0,0 +1,35 @@ +--- +- ansible.builtin.debug: + msg: START nxos_lldp_global rendered integration tests on connection={{ ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yml + +- block: + - name: Use rendered state to convert task input to device specific commands + register: result + cisco.nxos.nxos_lldp_global: + config: + holdtime: 130 + port_id: 1 + reinit: 5 + tlv_select: + dcbxp: true + power_management: true + state: rendered + + - ansible.builtin.assert: + that: "{{ rendered | symmetric_difference(result['rendered']) |length==0 }}" + + - name: Gather lldp_global facts from the device and assert that its empty + register: result + cisco.nxos.nxos_lldp_global: + state: gathered + + - name: Make sure that rendered task actually did not make any changes to the device + ansible.builtin.assert: + that: "{{ result['gathered'] == {} }}" + always: + - ansible.builtin.include_tasks: _remove_config.yml + +- ansible.builtin.debug: + msg: END nxos_lldp_global rendered integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/tests/common/replaced.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/tests/common/replaced.yml new file mode 100644 index 00000000..e9a31384 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/tests/common/replaced.yml @@ -0,0 +1,92 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_lldp_global replaced integration tests connection = {{ansible_connection}} + +- block: + - name: Set a fact for 'port_id' and 'tlv_power_mgmt' + ansible.builtin.set_fact: + port_id: 1 + tlv_power_mgmt: + power_management: false + when: platform is not search('N[567]K') and imagetag is not search("I[2345]") + + - name: Feature off to cleanup lldp + cisco.nxos.nxos_feature: &id002 + feature: lldp + state: disabled + + - name: Enable lldp feature + cisco.nxos.nxos_feature: + feature: lldp + state: enabled + + - name: Setup + cisco.nxos.nxos_config: + lines: + - "lldp holdtime 125" + - "lldp tlv-select system-name" + - "no lldp tlv-select port-vlan" + + - name: Setup2 + when: port_id is defined + cisco.nxos.nxos_config: + lines: + - "lldp portid-subtype 1" + - "no lldp tlv-select power-management" + + - name: Replaced + register: result + cisco.nxos.nxos_lldp_global: &id001 + config: + holdtime: 125 + timer: 35 + tlv_select: + system: + name: false + description: false + port: + vlan: false + dcbxp: false + state: replaced + + - ansible.builtin.assert: + that: + - result.changed == true + - "'lldp timer 35' in result.commands" + - "'no lldp tlv-select system-name' in result.commands" + - "'no lldp tlv-select system-description' in result.commands" + - "'no lldp tlv-select dcbxp' in result.commands" + + - ansible.builtin.assert: + that: + - "'no lldp portid-subtype 1' in result.commands" + when: port_id is defined + + - ansible.builtin.assert: + that: + - "'lldp tlv-select power-management' in result.commands" + when: tlv_power_mgmt is defined + + - name: Gather lldp_global post facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: lldp_global + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.lldp_global == result.after + + - name: Idempotence - replaced + register: result + cisco.nxos.nxos_lldp_global: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + always: + - name: Teardown + cisco.nxos.nxos_feature: *id002 + when: platform is not search('N35') diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/vars/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/vars/main.yml new file mode 100644 index 00000000..4a3dc810 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_global/vars/main.yml @@ -0,0 +1,23 @@ +--- +gathered: + reinit: 5 + timer: 35 + tlv_select: + system: + name: false + holdtime: 129 + +rendered: + - "lldp tlv-select dcbxp" + - "lldp tlv-select power-management" + - "lldp portid-subtype 1" + - "lldp reinit 5" + - "lldp holdtime 130" + +parsed: + holdtime: 131 + reinit: 7 + tlv_select: + system: + description: false + name: false diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tasks/cli.yaml new file mode 100644 index 00000000..c34726ef --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tasks/cli.yaml @@ -0,0 +1,31 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tasks/main.yaml new file mode 100644 index 00000000..8d0b9433 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tasks/main.yaml @@ -0,0 +1,9 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tasks/nxapi.yaml new file mode 100644 index 00000000..e0ebc3f5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tasks/nxapi.yaml @@ -0,0 +1,31 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tests/common/deleted.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tests/common/deleted.yml new file mode 100644 index 00000000..639254f5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tests/common/deleted.yml @@ -0,0 +1,72 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_lldp_interfaces deleted integration tests connection = {{ ansible_connection }} + +- name: Enable 'feature lldp' + cisco.nxos.nxos_feature: + feature: lldp + state: enabled + +- block: + - name: Setup + cisco.nxos.nxos_config: + lines: + - "interface Ethernet1/1" + - " lldp receive" + - " no lldp transmit" + - "interface Ethernet1/2" + - " no lldp receive" + - " lldp tlv-set vlan 12" + - "interface Ethernet1/3" + - " lldp tlv-set management-address 192.0.2.12" + + - name: Delete on single interface + register: result + cisco.nxos.nxos_lldp_interfaces: + config: + - name: Ethernet1/2 + state: deleted + + - ansible.builtin.assert: + that: + - result.changed == true + - "'interface Ethernet1/2' in result.commands" + - "'lldp receive' in result.commands" + - "'no lldp tlv-set vlan 12' in result.commands" + - result.commands | length == 3 + + - name: Gather lldp_interfaces facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: lldp_interfaces + + - name: Deleted + register: result + cisco.nxos.nxos_lldp_interfaces: &id001 + state: deleted + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.lldp_interfaces == result.before + - "'interface Ethernet1/1' in result.commands" + - "'lldp transmit' in result.commands" + - "'interface Ethernet1/3' in result.commands" + - "'no lldp tlv-set management-address 192.0.2.12' in result.commands" + - "result.changed == true " + - result.commands | length == 4 + + - name: Idempotence - deleted + register: result + cisco.nxos.nxos_lldp_interfaces: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + always: + - name: Teardown + cisco.nxos.nxos_feature: + feature: lldp + state: disabled diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tests/common/gathered.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tests/common/gathered.yml new file mode 100644 index 00000000..f9d3e603 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tests/common/gathered.yml @@ -0,0 +1,51 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_lldp_interfaces gathered integration tests connection={{ansible_connection}}" + +- name: Enable 'feature lldp' + cisco.nxos.nxos_feature: + feature: lldp + state: enabled + +- block: + - name: Setup + cisco.nxos.nxos_config: + lines: + - "interface Ethernet1/1" + - " lldp receive" + - " no lldp transmit" + - "interface Ethernet1/2" + - " no lldp receive" + - " lldp tlv-set vlan 12" + - "interface Ethernet1/3" + - " lldp tlv-set management-address 192.0.2.12" + + - name: Gather lldp interfaces facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: lldp_interfaces + + - name: Gathered + register: result + cisco.nxos.nxos_lldp_interfaces: &id001 + state: gathered + + - ansible.builtin.assert: + that: + - result.changed == false + - ansible_facts.network_resources.lldp_interfaces == result.gathered + + - name: Idempotence - gathered + register: result + cisco.nxos.nxos_lldp_interfaces: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + always: + - name: Teardown + cisco.nxos.nxos_feature: + feature: lldp + state: disabled diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tests/common/merged.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tests/common/merged.yml new file mode 100644 index 00000000..2f8c0eb0 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tests/common/merged.yml @@ -0,0 +1,59 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_lldp_interfaces merged integration tests connection={{ansible_connection}} + +- name: Enable lldp + cisco.nxos.nxos_feature: + feature: lldp + +- block: + - name: Merged + register: result + cisco.nxos.nxos_lldp_interfaces: &id001 + config: + - name: Ethernet 1/1 + receive: false + tlv_set: + vlan: 123 + + - name: Ethernet1/2 + transmit: false + tlv_set: + management_address: 10.0.0.1 + state: merged + + - ansible.builtin.assert: + that: + - result.changed == true + - "'interface Ethernet1/1' in result.commands" + - "'no lldp receive' in result.commands" + - "'lldp tlv-set vlan 123' in result.commands" + - "'interface Ethernet1/2' in result.commands" + - "'no lldp transmit' in result.commands" + - "'lldp tlv-set management-address 10.0.0.1' in result.commands" + - result.commands | length == 6 + + - name: Gather lldp_interfaces facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: lldp_interfaces + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.lldp_interfaces == result.after + + - name: Idempotence - merged + register: result + cisco.nxos.nxos_lldp_interfaces: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands | length == 0 + always: + - name: Teardown + cisco.nxos.nxos_feature: + feature: lldp + state: disabled diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tests/common/overridden.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tests/common/overridden.yml new file mode 100644 index 00000000..cb54a42a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tests/common/overridden.yml @@ -0,0 +1,65 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_lldp_interfaces overridden tests connection={{ ansible_connection }} + +- name: Enable 'feature lldp' + cisco.nxos.nxos_feature: + feature: lldp + state: enabled + +- block: + - name: Setup + cisco.nxos.nxos_config: + lines: + - "interface Ethernet1/1" + - " no lldp receive" + - " lldp tlv-set management-address 12.12.12.12" + + - name: Gather lldp_interfaces facts + cisco.nxos.nxos_facts: &id001 + gather_subset: + - "!all" + - "!min" + gather_network_resources: lldp_interfaces + + - name: Overridden + register: result + cisco.nxos.nxos_lldp_interfaces: &id002 + config: + - name: Ethernet1/2 + receive: false + tlv_set: + vlan: 12 + state: overridden + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.lldp_interfaces == result.before + - "'interface Ethernet1/1' in result.commands" + - "'lldp receive' in result.commands" + - "'no lldp tlv-set management-address 12.12.12.12' in result.commands" + - "'interface Ethernet1/2' in result.commands" + - "'no lldp receive' in result.commands" + - "'lldp tlv-set vlan 12' in result.commands" + - result.commands | length == 6 + + - name: Gather lldp_interfaces post facts + cisco.nxos.nxos_facts: *id001 + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.lldp_interfaces == result.after + + - name: Idempotence - overridden + register: result + cisco.nxos.nxos_lldp_interfaces: *id002 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + always: + - name: Teardown + cisco.nxos.nxos_feature: + feature: lldp + state: disabled diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tests/common/parsed.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tests/common/parsed.yml new file mode 100644 index 00000000..ea03c58b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tests/common/parsed.yml @@ -0,0 +1,40 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_lldp_interfaces parsed integration tests connection={{ansible_connection}}" + +- name: Enable lldp + cisco.nxos.nxos_feature: + feature: lldp + +- block: + - name: Gather lldp interfaces facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: lldp_interfaces + + - name: Parsed + register: result + cisco.nxos.nxos_lldp_interfaces: &id001 + running_config: + "interface Ethernet1/1\n lldp receive\n no lldp transmit\ninterface Ethernet1/2\n no lldp receive\n lldp tlv-set vlan 12\ninterface Ethernet1/3\n\ + \ lldp tlv-set management-address 192.0.2.12\n" + state: parsed + + - ansible.builtin.assert: + that: + - result.changed == false + - result.parsed == parsed + + - name: Idempotence - parsed + register: result + cisco.nxos.nxos_lldp_interfaces: *id001 + + - ansible.builtin.assert: + that: result.changed == false + always: + - name: Teardown + cisco.nxos.nxos_feature: + feature: lldp + state: disabled diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tests/common/remove_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tests/common/remove_config.yaml new file mode 100644 index 00000000..db070420 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tests/common/remove_config.yaml @@ -0,0 +1,7 @@ +--- +- ignore_errors: true + cisco.nxos.nxos_config: + lines: + - "no interface port-channel1" + - "no interface port-channel2" + - "no interface port-channel12" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tests/common/rendered.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tests/common/rendered.yml new file mode 100644 index 00000000..3b14c21a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tests/common/rendered.yml @@ -0,0 +1,42 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_lldp_interfaces rendered tests connection={{ ansible_connection }} + +- name: Rendered + register: result + cisco.nxos.nxos_lldp_interfaces: &id001 + config: + - name: Ethernet1/1 + receive: true + transmit: false + + - name: Ethernet1/2 + receive: false + tlv_set: + vlan: 12 + + - name: Ethernet1/3 + tlv_set: + management_address: 192.0.2.12 + state: rendered + +- ansible.builtin.assert: + that: + - result.changed == false + - "'interface Ethernet1/1' in result.rendered" + - "'lldp receive' in result.rendered" + - "'no lldp transmit' in result.rendered" + - "'interface Ethernet1/2' in result.rendered" + - "'no lldp receive' in result.rendered" + - "'lldp tlv-set vlan 12' in result.rendered" + - "'interface Ethernet1/3' in result.rendered" + - "'lldp tlv-set management-address 192.0.2.12' in result.rendered" + - result.rendered | length == 8 + +- name: Idempotence - rendered + register: result + cisco.nxos.nxos_lldp_interfaces: *id001 + +- ansible.builtin.assert: + that: + - result.changed == false diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tests/common/replaced.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tests/common/replaced.yml new file mode 100644 index 00000000..60195052 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tests/common/replaced.yml @@ -0,0 +1,61 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_lldp_interfaces replaced integration tests connection = {{ansible_connection}} + +- name: Enable 'feature lldp' + cisco.nxos.nxos_feature: + feature: lldp + state: enabled + +- block: + - name: Setup + cisco.nxos.nxos_config: + lines: + - "interface Ethernet1/2" + - " no lldp receive" + - " lldp tlv-set management-address 192.168.122.64" + + - name: Replaced + register: result + cisco.nxos.nxos_lldp_interfaces: &id001 + config: + - name: Ethernet1/2 + transmit: false + tlv_set: + vlan: 2 + state: replaced + + - ansible.builtin.assert: + that: + - result.changed == true + - "'interface Ethernet1/2' in result.commands" + - "'lldp receive' in result.commands" + - "'no lldp tlv-set management-address 192.168.122.64' in result.commands" + - "'no lldp transmit' in result.commands" + - "'lldp tlv-set vlan 2' in result.commands" + - result.commands|length == 5 + + - name: Gather lldp_interfaces post facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: lldp_interfaces + + - ansible.builtin.assert: + that: + - ansible_facts.network_resources.lldp_interfaces == result.after + + - name: Idempotence - replaced + register: result + cisco.nxos.nxos_lldp_interfaces: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + always: + - name: Teardown + cisco.nxos.nxos_feature: + feature: lldp + state: disabled diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tests/common/rtt.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tests/common/rtt.yml new file mode 100644 index 00000000..516fb3fe --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/tests/common/rtt.yml @@ -0,0 +1,69 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_lldp_interfaces round trip integration tests on connection={{ ansible_connection }} + +- name: Enable lldp + cisco.nxos.nxos_feature: + feature: lldp + +- ansible.builtin.include_tasks: remove_config.yaml + +- block: + - name: Rtt - apply the provided configuration (base config) + register: base_config + cisco.nxos.nxos_lldp_interfaces: + config: + - name: Ethernet1/1 + transmit: false + tlv_set: + vlan: 5 + state: merged + + - name: Gather interfaces facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: + - lldp_interfaces + + - name: Apply provided configuration (this will be reverted) + register: result + cisco.nxos.nxos_lldp_interfaces: + config: + - name: Ethernet1/1 + transmit: false + + - name: Ethernet1/2 + transmit: true + tlv_set: + vlan: 12 + management_address: 10.1.1.2 + state: overridden + + - name: Assert that changes were applied + ansible.builtin.assert: + that: + - result.changed == true + - "'interface Ethernet1/1' in result.commands" + - "'no lldp tlv-set vlan 5' in result.commands" + - "'interface Ethernet1/2' in result.commands" + - "'lldp transmit' in result.commands" + - "'lldp tlv-set vlan 12' in result.commands" + - "'lldp tlv-set management-address 10.1.1.2' in result.commands" + - result.commands | length == 6 + + - name: Revert back to base configuration + register: revert + cisco.nxos.nxos_lldp_interfaces: + config: "{{ ansible_facts['network_resources']['lldp_interfaces'] }}" + state: overridden + + - name: Assert that configuration was reverted + ansible.builtin.assert: + that: "{{ base_config['after'] | symmetric_difference(revert['after']) |length == 0 }}" + always: + - name: Teardown + cisco.nxos.nxos_feature: + feature: lldp + state: disabled diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/vars/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/vars/main.yml new file mode 100644 index 00000000..ed33efa4 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_lldp_interfaces/vars/main.yml @@ -0,0 +1,12 @@ +--- +parsed: + - name: Ethernet1/1 + receive: true + transmit: false + - name: Ethernet1/2 + receive: false + tlv_set: + vlan: 12 + - name: Ethernet1/3 + tlv_set: + management_address: 192.0.2.12 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging/meta/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging/meta/main.yaml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging/meta/main.yaml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging/tasks/main.yaml new file mode 100644 index 00000000..ccb324f3 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging/tasks/main.yaml @@ -0,0 +1,19 @@ +--- +- name: Run the CLI and NX-API tests + block: + - name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + + - name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi + always: + - name: Set baud rate back to 9600 so our tests don't break + connection: ansible.netcommon.network_cli + cisco.nxos.nxos_config: + lines: + - speed 9600 + parents: line console diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging/tests/common/basic.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging/tests/common/basic.yaml new file mode 100644 index 00000000..72bf146d --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging/tests/common/basic.yaml @@ -0,0 +1,485 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_logging basic test + +- name: Workaround to clear logging logfile size + ignore_errors: true + cisco.nxos.nxos_config: + lines: + - logging logfile test 1 size 4194304 + +- name: Purge logging configuration first + cisco.nxos.nxos_logging: + purge: true + +- name: Set up console logging + register: result + cisco.nxos.nxos_logging: &id001 + dest: console + dest_level: 0 + state: present + +- ansible.builtin.assert: + that: + - result.changed == true + - '"logging console 0" in result.commands' + +- name: Set up console logging again (idempotent) + register: result + cisco.nxos.nxos_logging: *id001 + +- ansible.builtin.assert: &id003 + that: + - result.changed == false + +- name: Set up console logging with level 2 (edge case) + register: result + cisco.nxos.nxos_logging: &id002 + dest: console + dest_level: 2 + state: present + +- ansible.builtin.assert: + that: + - result.changed == true + - '"logging console 2" in result.commands' + +- name: Set up console logging with level 2 (edge case) (idempotent) + register: result + cisco.nxos.nxos_logging: *id002 + +- ansible.builtin.assert: *id003 + +- block: + - name: Logfile logging with level + register: result + cisco.nxos.nxos_logging: &id004 + dest: logfile + name: test + dest_level: 1 + state: present + + - ansible.builtin.assert: + that: + - result.changed == true + - '"logging logfile test 1" in result.commands' + + - name: Logfile logging with level (idempotent) + register: result + cisco.nxos.nxos_logging: *id004 + + - ansible.builtin.assert: *id003 + when: platform is not search('N5K|N7K') and imagetag is not search("A8") + +- name: Configure module with level + register: result + cisco.nxos.nxos_logging: &id005 + dest: module + dest_level: 2 + +- ansible.builtin.assert: + that: + - result.changed == true + - '"logging module 2" in result.commands' + +- name: Configure module with level (idempotent) + register: result + cisco.nxos.nxos_logging: *id005 + +- ansible.builtin.assert: *id003 + +- name: Configure monitor with level + register: result + cisco.nxos.nxos_logging: &id006 + dest: monitor + dest_level: 3 + +- ansible.builtin.assert: + that: + - result.changed == true + - '"logging monitor 3" in result.commands' + +- name: Configure monitor with level (idempotent) + register: result + cisco.nxos.nxos_logging: *id006 + +- ansible.builtin.assert: *id003 + +- name: Configure monitor with level 5 (edge case) + register: result + cisco.nxos.nxos_logging: &id007 + dest: monitor + dest_level: 5 + +- ansible.builtin.assert: + that: + - result.changed == true + - '"logging monitor 5" in result.commands' + +- name: Configure monitor with level 5 (edge case) (idempotent) + register: result + cisco.nxos.nxos_logging: *id007 + +- ansible.builtin.assert: *id003 + +- name: Configure facility with level + register: result + cisco.nxos.nxos_logging: &id008 + facility: daemon + facility_level: 4 + +- ansible.builtin.assert: + that: + - result.changed == true + - '"logging level daemon 4" in result.commands' + +- name: Configure facility with level (idempotent) + register: result + cisco.nxos.nxos_logging: *id008 + +- ansible.builtin.assert: *id003 + +- name: Configure remote logging + register: result + cisco.nxos.nxos_logging: &id009 + dest: server + remote_server: test-syslogserver.com + facility: auth + facility_level: 1 + use_vrf: management + state: present + +- ansible.builtin.assert: + that: + - result.changed == true + - '"logging server test-syslogserver.com 1 facility auth use-vrf management" in result.commands' + +- name: Configure remote logging (idempotent) + register: result + cisco.nxos.nxos_logging: *id009 + +- ansible.builtin.assert: *id003 + +- name: Configure source interface for logging + register: result + cisco.nxos.nxos_logging: &id010 + interface: mgmt0 + +- ansible.builtin.assert: + that: + - result.changed == true + - '"logging source-interface mgmt 0" in result.commands' + +- name: Configure source interface for logging (idempotent) + register: result + cisco.nxos.nxos_logging: *id010 + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Remove logging as collection teardown + register: result + cisco.nxos.nxos_logging: &id011 + aggregate: + - dest: console + dest_level: 3 + + - dest: module + dest_level: 2 + + - dest: monitor + dest_level: 5 + + - dest: logfile + dest_level: 1 + name: test + + - facility: daemon + facility_level: 4 + + - dest: server + remote_server: test-syslogserver.com + facility: auth + facility_level: 1 + use_vrf: management + + - interface: mgmt0 + state: absent + +- ansible.builtin.assert: + that: + - result.changed == true + - '"no logging logfile" in result.commands' + - '"no logging level daemon 4" in result.commands' + - '"no logging monitor" in result.commands' + - '"no logging module" in result.commands' + - '"no logging server test-syslogserver.com" in result.commands' + - '"no logging source-interface" in result.commands' + when: platform is not search('N5K|N7K') and imagetag is not search("A8") + +- ansible.builtin.assert: + that: + - result.changed == true + - '"no logging level daemon 4" in result.commands' + - '"no logging monitor" in result.commands' + - '"no logging module" in result.commands' + - '"no logging server test-syslogserver.com" in result.commands' + - '"no logging source-interface" in result.commands' + when: platform is search('N5K|N7K') or imagetag is search("A8") + +- name: Remove aggregate logging (idempotent) + register: result + cisco.nxos.nxos_logging: *id011 + +- ansible.builtin.assert: *id003 + +- block: + - name: Configure logging message + register: result + cisco.nxos.nxos_logging: &id012 + interface_message: add-interface-description + state: present + + - ansible.builtin.assert: &id013 + that: + - result.changed == true + + - name: Configure logging message (idempotent) + register: result + cisco.nxos.nxos_logging: *id012 + + - ansible.builtin.assert: *id003 + + - name: Remove logging message + register: result + cisco.nxos.nxos_logging: + interface_message: add-interface-description + state: absent + + - ansible.builtin.assert: *id013 + when: platform is not search('N5K') and imagetag is not search("A8") + +- name: Logfile logging with level and size + register: result + cisco.nxos.nxos_logging: &id014 + dest: logfile + name: test + dest_level: 1 + file_size: 16384 + state: present + +- ansible.builtin.assert: + that: + - result.changed == true + - '"logging logfile test 1 size 16384" in result.commands' + +- name: Logfile logging with level and size (idempotent) + register: result + cisco.nxos.nxos_logging: *id014 + +- ansible.builtin.assert: *id003 + +- name: Remove logfile logging with level and size + register: result + cisco.nxos.nxos_logging: + dest: logfile + name: test + dest_level: 1 + file_size: 16384 + state: absent + +- ansible.builtin.assert: *id013 + +- name: Set up logging event link enable + register: result + cisco.nxos.nxos_logging: &id015 + event: link-enable + +- ansible.builtin.assert: + that: + - result.changed == true + - '"logging event link-status enable" in result.commands' + +- name: Set up logging event link enable again (idempotent) + register: result + cisco.nxos.nxos_logging: *id015 + +- ansible.builtin.assert: *id003 + +- name: Remove logging event link enable + register: result + cisco.nxos.nxos_logging: &id016 + event: link-enable + state: absent + +- ansible.builtin.assert: *id013 + +- name: Remove logging event link enable again (idempotent) + register: result + cisco.nxos.nxos_logging: *id016 + +- ansible.builtin.assert: *id003 + +- name: Set up logging event link default + register: result + cisco.nxos.nxos_logging: &id017 + event: link-default + +- ansible.builtin.assert: + that: + - result.changed == true + - '"logging event link-status default" in result.commands' + +- name: Set up logging event link default again (idempotent) + register: result + cisco.nxos.nxos_logging: *id017 + +- ansible.builtin.assert: *id003 + +- name: Remove logging event link default + register: result + cisco.nxos.nxos_logging: &id018 + event: link-default + state: absent + +- ansible.builtin.assert: *id013 + +- name: Remove logging event link default again (idempotent) + register: result + cisco.nxos.nxos_logging: *id018 + +- ansible.builtin.assert: *id003 + +- name: Set up logging event trunk enable + register: result + cisco.nxos.nxos_logging: &id019 + event: trunk-enable + +- ansible.builtin.assert: + that: + - result.changed == true + - '"logging event trunk-status enable" in result.commands' + +- name: Set up logging event trunk enable again (idempotent) + register: result + cisco.nxos.nxos_logging: *id019 + +- ansible.builtin.assert: *id003 + +- name: Remove logging event trunk enable + register: result + cisco.nxos.nxos_logging: &id020 + event: trunk-enable + state: absent + +- ansible.builtin.assert: *id013 + +- name: Remove logging event trunk enable again (idempotent) + register: result + cisco.nxos.nxos_logging: *id020 + +- ansible.builtin.assert: *id003 + +- name: Set up logging event trunk default + register: result + cisco.nxos.nxos_logging: &id021 + event: trunk-default + +- ansible.builtin.assert: + that: + - result.changed == true + - '"logging event trunk-status default" in result.commands' + +- name: Set up logging event trunk default again (idempotent) + register: result + cisco.nxos.nxos_logging: *id021 + +- ansible.builtin.assert: *id003 + +- name: Remove logging event trunk default + register: result + cisco.nxos.nxos_logging: &id022 + event: trunk-default + state: absent + +- ansible.builtin.assert: *id013 + +- name: Remove logging event trunk default again (idempotent) + register: result + cisco.nxos.nxos_logging: *id022 + +- ansible.builtin.assert: *id003 + +- name: Set up logging timestamp + register: result + cisco.nxos.nxos_logging: &id023 + timestamp: microseconds + state: present + +- ansible.builtin.assert: *id013 + +- name: Set up logging timestamp (idempotent) + register: result + cisco.nxos.nxos_logging: *id023 + +- ansible.builtin.assert: *id003 + +- name: Remove logging timestamp + register: result + cisco.nxos.nxos_logging: + timestamp: microseconds + state: absent + +- ansible.builtin.assert: *id013 + +- name: Set up facility ethpm link up error + register: result + cisco.nxos.nxos_logging: &id024 + facility: ethpm + facility_link_status: link-up-error + state: present + +- ansible.builtin.assert: *id013 + +- name: Set up facility ethpm link up error (idempotent) + register: result + cisco.nxos.nxos_logging: *id024 + +- ansible.builtin.assert: *id003 + +- name: Remove facility ethpm link up error + register: result + cisco.nxos.nxos_logging: + facility: ethpm + facility_link_status: link-up-error + state: absent + +- ansible.builtin.assert: *id013 + +- name: Set up facility ethpm link down error + register: result + cisco.nxos.nxos_logging: &id025 + facility: ethpm + facility_link_status: link-down-error + state: present + +- ansible.builtin.assert: *id013 + +- name: Set up facility ethpm link down error (idempotent) + register: result + cisco.nxos.nxos_logging: *id025 + +- ansible.builtin.assert: *id003 + +- name: Remove facility ethpm link down error + register: result + cisco.nxos.nxos_logging: + facility: ethpm + facility_link_status: link-down-error + state: absent + +- ansible.builtin.assert: *id013 + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_logging basic test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging/tests/common/purge.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging/tests/common/purge.yaml new file mode 100644 index 00000000..fa773b58 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging/tests/common/purge.yaml @@ -0,0 +1,111 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_logging purge test + +- name: Purge logging configuration first + cisco.nxos.nxos_logging: + purge: true + +- block: + - name: Set up console logging + register: result + cisco.nxos.nxos_logging: + dest: console + dest_level: 0 + state: present + + - ansible.builtin.assert: + that: + - result.changed == true + - '"logging console 0" in result.commands' + + - name: Set up logging timestamp + register: result + cisco.nxos.nxos_logging: + timestamp: microseconds + state: present + + - ansible.builtin.assert: + that: + - result.changed == true + - '"logging timestamp microseconds" in result.commands' + + - name: Configure monitor with level + register: result + cisco.nxos.nxos_logging: + dest: monitor + dest_level: 3 + + - ansible.builtin.assert: + that: + - result.changed == true + - '"logging monitor 3" in result.commands' + + - name: Configure facility with level + register: result + cisco.nxos.nxos_logging: + facility: daemon + facility_level: 4 + + - ansible.builtin.assert: + that: + - result.changed == true + - '"logging level daemon 4" in result.commands' + + - name: Configure logging level virtual-service 7 using nxos_config + register: result + cisco.nxos.nxos_config: + lines: logging level virtual-service 7 + + - ansible.builtin.assert: + that: + - result.changed == true + + - name: Purge the outliers + register: result + cisco.nxos.nxos_logging: + purge: true + + - ansible.builtin.assert: + that: + - result.changed == true + - '"no logging level virtual-service 7" in result.commands' + + - block: + - name: Purge the outliers (idempotent) + register: result + cisco.nxos.nxos_logging: + purge: true + + - assert: + that: + - result.changed == false + when: imagetag is not search("A8") + + - name: Remove logging as collection teardown + register: result + cisco.nxos.nxos_logging: + aggregate: + - dest: console + dest_level: 0 + + - dest: monitor + dest_level: 3 + + - timestamp: microseconds + + - facility: daemon + facility_level: 4 + state: absent + + - ansible.builtin.assert: + that: + - result.changed == true + - '"no logging console" in result.commands' + - '"no logging timestamp microseconds" in result.commands' + - '"no logging level daemon 4" in result.commands' + - '"no logging monitor" in result.commands' + when: ansible_connection != "local" + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_logging purge test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/defaults/main.yaml new file mode 100644 index 00000000..871ea460 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "[^_].*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tasks/cli.yaml new file mode 100644 index 00000000..9e4fb34b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tasks/main.yaml new file mode 100644 index 00000000..b62ef52e --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli.yaml + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tasks/nxapi.yaml new file mode 100644 index 00000000..5cb76e67 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tests/common/_populate_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tests/common/_populate_config.yaml new file mode 100644 index 00000000..532e4e05 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tests/common/_populate_config.yaml @@ -0,0 +1,15 @@ +--- +- name: Populate configuration + cisco.nxos.nxos_config: + lines: + - "logging console 3" + - "logging monitor 4" + - "logging ip access-list cache entries 16384" + - "logging ip access-list cache interval 200" + - "logging ip access-list cache threshold 5000" + - "logging level auth 2" + - "logging level aaa 1" + - "logging level ftp 6" + - "logging server 203.0.113.100 1 use-vrf management" + - "logging server 203.0.113.101 3 facility local6 use-vrf default" + - "logging origin-id hostname" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tests/common/_remove_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tests/common/_remove_config.yaml new file mode 100644 index 00000000..ba137bbd --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tests/common/_remove_config.yaml @@ -0,0 +1,6 @@ +--- +- name: Remove existing logging configuration + cisco.nxos.nxos_logging_global: + state: deleted + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tests/common/deleted.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tests/common/deleted.yaml new file mode 100644 index 00000000..ccac2c74 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tests/common/deleted.yaml @@ -0,0 +1,40 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_logging_global deleted integration tests connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Delete all logging configuration + cisco.nxos.nxos_logging_global: &del + state: deleted + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ result['before'] == merged['after'] }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ deleted['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dicts were correctly generated + ansible.builtin.assert: + that: + - result['after'] == {} + + - name: Delete all logging configuration (idempotent) + cisco.nxos.nxos_logging_global: *del + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tests/common/empty_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tests/common/empty_config.yaml new file mode 100644 index 00000000..22a95f77 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tests/common/empty_config.yaml @@ -0,0 +1,61 @@ +--- +- ansible.builtin.debug: + msg: START nxos_logging_global empty_config integration tests on connection={{ ansible_connection }} + +- name: Merged with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_logging_global: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_logging_global: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Overridden with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_logging_global: + config: + state: overridden + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Rendered with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_logging_global: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' + +- name: Parsed with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_logging_global: + running_config: + state: parsed + +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state parsed' + +- ansible.builtin.debug: + msg: END nxos_logging_global empty_config integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tests/common/fixtures/parsed.cfg b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tests/common/fixtures/parsed.cfg new file mode 100644 index 00000000..500b8dd9 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tests/common/fixtures/parsed.cfg @@ -0,0 +1,11 @@ +logging console 3 +logging monitor 4 +logging ip access-list cache entries 16384 +logging ip access-list cache interval 200 +logging ip access-list cache threshold 5000 +logging level auth 2 +logging level aaa 1 +logging level ftp 6 +logging origin-id hostname +logging server 203.0.113.100 1 use-vrf management +logging server 203.0.113.101 3 use-vrf default facility local6 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tests/common/gathered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tests/common/gathered.yaml new file mode 100644 index 00000000..e30e8d64 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tests/common/gathered.yaml @@ -0,0 +1,21 @@ +--- +- ansible.builtin.debug: + msg: START nxos_logging_global gathered integration tests on connection={{ ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Gather logging global facts using gathered + register: result + cisco.nxos.nxos_logging_global: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: + - "{{ result['gathered'] == merged['after'] }}" + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tests/common/merged.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tests/common/merged.yaml new file mode 100644 index 00000000..807a88ee --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tests/common/merged.yaml @@ -0,0 +1,65 @@ +--- +- ansible.builtin.debug: + msg: "Start nxos_logging_global merged integration tests connection={{ ansible_connection }}" + +- ansible.builtin.include_tasks: _remove_config.yaml + +- block: + - name: Merge the provided configuration with the existing running configuration + cisco.nxos.nxos_logging_global: &id001 + config: + console: + severity: error + monitor: + severity: warning + ip: + access_list: + cache: + entries: 16384 + interval: 200 + threshold: 5000 + facilities: + - facility: auth + severity: critical + - facility: aaa + severity: alert + - facility: ftp + severity: informational + hosts: + - host: 203.0.113.100 + severity: alert + use_vrf: management + - host: 203.0.113.101 + severity: error + facility: local6 + use_vrf: default + origin_id: + hostname: true + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ result['before'] == {} }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ merged['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ merged['after'] == result['after'] }}" + + - name: Merge the provided configuration with the existing running configuration (idempotent) + cisco.nxos.nxos_logging_global: *id001 + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tests/common/overridden.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tests/common/overridden.yaml new file mode 100644 index 00000000..637f3df7 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tests/common/overridden.yaml @@ -0,0 +1,65 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_logging_global overridden integration tests connection={{ ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Override all logging configuration with provided configuration + cisco.nxos.nxos_logging_global: &id001 + config: + monitor: + severity: warning + ip: + access_list: + cache: + entries: 4096 + facilities: + - facility: auth + severity: critical + - facility: aaa + severity: alert + - facility: ftp + severity: informational + hosts: + - host: 203.0.113.101 + severity: error + facility: local6 + use_vrf: default + - host: 198.51.100.101 + severity: alert + port: 6538 + use_vrf: management + origin_id: + ip: 192.0.2.100 + state: overridden + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ merged['after'] == result['before'] }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dicts were correctly generated + ansible.builtin.assert: + that: + - replaced['after'] == result['after'] + + - name: Override all logging configuration with provided configuration (idempotent) + register: result + cisco.nxos.nxos_logging_global: *id001 + + - name: Assert that task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tests/common/parsed.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tests/common/parsed.yaml new file mode 100644 index 00000000..d959f00a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tests/common/parsed.yaml @@ -0,0 +1,14 @@ +--- +- ansible.builtin.debug: + msg: START nxos_logging_global parsed integration tests on connection={{ ansible_connection }} + +- name: Parse externally provided logging configuration + register: result + cisco.nxos.nxos_logging_global: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed + +- name: Assert that configuration was correctly parsed + ansible.builtin.assert: + that: + - "{{ merged['after'] == result['parsed'] }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tests/common/rendered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tests/common/rendered.yaml new file mode 100644 index 00000000..77c4bbac --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tests/common/rendered.yaml @@ -0,0 +1,42 @@ +--- +- ansible.builtin.debug: + msg: START nxos_logging_global rendered integration tests on connection={{ ansible_connection }} + +- name: Render platform specific configuration lines with state rendered (without connecting to the device) + cisco.nxos.nxos_logging_global: + config: + console: + severity: error + monitor: + severity: warning + ip: + access_list: + cache: + entries: 16384 + interval: 200 + threshold: 5000 + facilities: + - facility: auth + severity: critical + - facility: aaa + severity: alert + - facility: ftp + severity: informational + hosts: + - host: 203.0.113.100 + severity: alert + use_vrf: management + - host: 203.0.113.101 + severity: error + facility: local6 + use_vrf: default + origin_id: + hostname: true + state: rendered + register: result + +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - "{{ merged['commands'] | symmetric_difference(result['rendered']) |length == 0 }}" + - result.changed == False diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tests/common/replaced.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tests/common/replaced.yaml new file mode 100644 index 00000000..0c4a3b86 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/tests/common/replaced.yaml @@ -0,0 +1,66 @@ +--- +- ansible.builtin.debug: + msg: "Start nxos_logging_global replaced integration tests connection={{ ansible_connection }}" + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Replace logging global configurations of listed logging global with provided configurations + cisco.nxos.nxos_logging_global: &id001 + config: + monitor: + severity: warning + ip: + access_list: + cache: + entries: 4096 + facilities: + - facility: auth + severity: critical + - facility: aaa + severity: alert + - facility: ftp + severity: informational + hosts: + - host: 203.0.113.101 + severity: error + facility: local6 + use_vrf: default + - host: 198.51.100.101 + severity: alert + port: 6538 + use_vrf: management + origin_id: + ip: 192.0.2.100 + state: replaced + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ merged['after'] == result['before'] }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dicts were correctly generated + ansible.builtin.assert: + that: + - replaced['after'] == result['after'] + + - name: Replace logging global configurations with provided configurations (idempotent) + register: result + cisco.nxos.nxos_logging_global: *id001 + + - name: Assert that task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/vars/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/vars/main.yml new file mode 100644 index 00000000..85d26009 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_logging_global/vars/main.yml @@ -0,0 +1,93 @@ +--- +merged: + before: {} + commands: + - "logging console 3" + - "logging monitor 4" + - "logging ip access-list cache entries 16384" + - "logging ip access-list cache interval 200" + - "logging ip access-list cache threshold 5000" + - "logging level auth 2" + - "logging level aaa 1" + - "logging level ftp 6" + - "logging server 203.0.113.100 1 use-vrf management" + - "logging server 203.0.113.101 3 facility local6 use-vrf default" + - "logging origin-id hostname" + after: + console: + severity: error + facilities: + - facility: aaa + severity: alert + - facility: auth + severity: critical + - facility: ftp + severity: informational + ip: + access_list: + cache: + entries: 16384 + interval: 200 + threshold: 5000 + monitor: + severity: warning + origin_id: + hostname: true + hosts: + - severity: alert + host: 203.0.113.100 + use_vrf: management + - facility: local6 + severity: error + host: 203.0.113.101 + use_vrf: default + +replaced: + commands: + - "logging console" + - "logging ip access-list cache entries 4096" + - "no logging ip access-list cache interval 200" + - "no logging ip access-list cache threshold 5000" + - "no logging origin-id hostname" + - "logging origin-id ip 192.0.2.100" + - "logging server 198.51.100.101 1 port 6538 use-vrf management" + - "no logging server 203.0.113.100 1 use-vrf management" + after: + facilities: + - facility: aaa + severity: alert + - facility: auth + severity: critical + - facility: ftp + severity: informational + ip: + access_list: + cache: + entries: 4096 + monitor: + severity: warning + origin_id: + ip: 192.0.2.100 + hosts: + - severity: alert + port: 6538 + host: 198.51.100.101 + use_vrf: management + - facility: local6 + severity: error + host: 203.0.113.101 + use_vrf: default + +deleted: + commands: + - "logging console" + - "logging monitor" + - "no logging ip access-list cache entries 16384" + - "no logging ip access-list cache interval 200" + - "no logging ip access-list cache threshold 5000" + - "no logging origin-id hostname" + - "no logging level auth 2" + - "no logging level aaa 1" + - "no logging level ftp 6" + - "no logging server 203.0.113.100 1 use-vrf management" + - "no logging server 203.0.113.101 3 facility local6 use-vrf default" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp/tasks/main.yaml new file mode 100644 index 00000000..c9e70304 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp/tasks/main.yaml @@ -0,0 +1,12 @@ +--- +- name: Run the CLI and NX-API tests + block: + - name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + always: + - name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp/tests/common/sanity.yaml new file mode 100644 index 00000000..f22c99f5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp/tests/common/sanity.yaml @@ -0,0 +1,114 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_ntp sanity test + +- name: Setup - remove ntp if configured + ignore_errors: true + cisco.nxos.nxos_ntp: &id005 + server: 1.2.3.4 + key_id: 32 + prefer: disabled + vrf_name: management + source_addr: 192.0.2.5 + state: absent + +- block: + - name: Configure ntp + register: result + cisco.nxos.nxos_ntp: &id001 + server: 1.2.3.4 + key_id: 32 + prefer: enabled + vrf_name: management + source_addr: 192.0.2.5 + state: present + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Idempotence check + register: result + cisco.nxos.nxos_ntp: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Configure ntp with some defaults + register: result + cisco.nxos.nxos_ntp: &id003 + peer: 1.2.3.4 + key_id: default + prefer: enabled + vrf_name: default + source_addr: default + state: present + + - ansible.builtin.assert: *id002 + + - name: Idempotence check + register: result + cisco.nxos.nxos_ntp: *id003 + + - ansible.builtin.assert: *id004 + + - name: Remove ntp configuration + register: result + cisco.nxos.nxos_ntp: *id005 + + - ansible.builtin.assert: *id002 + + - name: Remove idempotence check + register: result + cisco.nxos.nxos_ntp: *id005 + + - ansible.builtin.assert: *id004 + + - name: Configure ntp again + register: result + cisco.nxos.nxos_ntp: &id006 + source_int: Ethernet1/3 + peer: 1.2.3.4 + prefer: enabled + state: present + + - ansible.builtin.assert: *id002 + + - name: Idempotence check + register: result + cisco.nxos.nxos_ntp: *id006 + + - ansible.builtin.assert: *id004 + + - name: Remove source interface + register: result + cisco.nxos.nxos_ntp: &id007 + source_int: default + state: present + + - ansible.builtin.assert: *id002 + + - name: Idempotence check + register: result + cisco.nxos.nxos_ntp: *id007 + + - ansible.builtin.assert: *id004 + + - name: Remove ntp + register: result + cisco.nxos.nxos_ntp: *id005 + + - ansible.builtin.assert: *id002 + + - name: Remove idempotence check + register: result + cisco.nxos.nxos_ntp: *id005 + + - ansible.builtin.assert: *id004 + always: + - name: Remove ntp configuration + cisco.nxos.nxos_ntp: *id005 + + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_ntp sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_auth/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_auth/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_auth/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_auth/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_auth/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_auth/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_auth/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_auth/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_auth/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_auth/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_auth/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_auth/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_auth/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_auth/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_auth/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_auth/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_auth/tests/common/sanity.yaml new file mode 100644 index 00000000..3ceb9e12 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_auth/tests/common/sanity.yaml @@ -0,0 +1,133 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_ntp_auth sanity test + +- name: Configure text ntp authentication + ignore_errors: true + cisco.nxos.nxos_ntp_auth: &id009 + key_id: 32 + md5string: hello + state: absent + +- block: + - name: Configure text ntp authentication + register: result + cisco.nxos.nxos_ntp_auth: + key_id: 32 + md5string: hello + authentication: false + state: present + + - ansible.builtin.assert: &id001 + that: + - result.changed == true + + - name: Remove text ntp authentication + register: result + cisco.nxos.nxos_ntp_auth: + key_id: 32 + md5string: hello + authentication: false + state: absent + + - ansible.builtin.assert: *id001 + + - name: Configure encrypt ntp authentication + register: result + cisco.nxos.nxos_ntp_auth: &id002 + key_id: 32 + md5string: hello + auth_type: encrypt + state: present + + - ansible.builtin.assert: *id001 + + - name: Check idempotence - configure encrypt ntp authentication + register: result + cisco.nxos.nxos_ntp_auth: *id002 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Turn on authentication + register: result + cisco.nxos.nxos_ntp_auth: &id003 + authentication: true + state: present + + - ansible.builtin.assert: *id001 + + - name: Check idempotence - turn on authentication + register: result + cisco.nxos.nxos_ntp_auth: *id003 + + - ansible.builtin.assert: *id004 + + - name: Turn off authentication + register: result + cisco.nxos.nxos_ntp_auth: &id005 + authentication: false + state: present + + - ansible.builtin.assert: *id001 + + - name: Check idempotence - turn off authentication + register: result + cisco.nxos.nxos_ntp_auth: *id005 + + - ansible.builtin.assert: *id004 + + - name: Add trusted key + register: result + cisco.nxos.nxos_ntp_auth: &id006 + key_id: 32 + trusted_key: true + state: present + + - ansible.builtin.assert: *id001 + + - name: Check idempotence - add trusted key + register: result + cisco.nxos.nxos_ntp_auth: *id006 + + - ansible.builtin.assert: *id004 + + - name: Remove trusted key + register: result + cisco.nxos.nxos_ntp_auth: &id007 + key_id: 32 + trusted_key: false + state: present + + - ansible.builtin.assert: *id001 + + - name: Check idempotence - remove trusted key + register: result + cisco.nxos.nxos_ntp_auth: *id007 + + - ansible.builtin.assert: *id004 + + - name: Remove encrypt ntp authentication + register: result + cisco.nxos.nxos_ntp_auth: &id008 + key_id: 32 + md5string: hello + auth_type: encrypt + authentication: true + state: absent + + - ansible.builtin.assert: *id001 + + - name: Check idempotence - remove encrypt ntp authentication + register: result + cisco.nxos.nxos_ntp_auth: *id008 + + - ansible.builtin.assert: *id004 + always: + - name: Cleanup ntp auth configuration + ignore_errors: true + cisco.nxos.nxos_ntp_auth: *id009 + + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_ntp_auth sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/defaults/main.yaml new file mode 100644 index 00000000..871ea460 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "[^_].*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tasks/cli.yaml new file mode 100644 index 00000000..9e4fb34b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tasks/main.yaml new file mode 100644 index 00000000..b62ef52e --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli.yaml + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tasks/nxapi.yaml new file mode 100644 index 00000000..5cb76e67 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tests/common/_populate_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tests/common/_populate_config.yaml new file mode 100644 index 00000000..2c2e860c --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tests/common/_populate_config.yaml @@ -0,0 +1,13 @@ +--- +- name: Populate configuration + cisco.nxos.nxos_config: + lines: + - "ntp authenticate" + - "ntp logging" + - "ntp master 2" + - "ntp peer 192.0.2.1 use-vrf default key 1 minpoll 5 maxpoll 15" + - "ntp peer 192.0.2.2 prefer use-vrf siteA key 2" + - "ntp server 198.51.100.1 use-vrf default key 2" + - "ntp server 203.0.113.1 use-vrf siteB key 1" + - "ntp access-group peer PeerAcl1" + - "ntp access-group serve ServeAcl1" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tests/common/_remove_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tests/common/_remove_config.yaml new file mode 100644 index 00000000..c49e3ad3 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tests/common/_remove_config.yaml @@ -0,0 +1,6 @@ +--- +- name: Remove existing logging configuration + cisco.nxos.nxos_ntp_global: + state: deleted + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tests/common/deleted.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tests/common/deleted.yaml new file mode 100644 index 00000000..4f2cc676 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tests/common/deleted.yaml @@ -0,0 +1,40 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_ntp_global deleted integration tests connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Delete all logging configuration + cisco.nxos.nxos_ntp_global: &del + state: deleted + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ result['before'] == merged['after'] }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ deleted['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dicts were correctly generated + ansible.builtin.assert: + that: + - result['after'] == {} + + - name: Delete all logging configuration (idempotent) + cisco.nxos.nxos_ntp_global: *del + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tests/common/empty_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tests/common/empty_config.yaml new file mode 100644 index 00000000..16c6144a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tests/common/empty_config.yaml @@ -0,0 +1,61 @@ +--- +- ansible.builtin.debug: + msg: START nxos_ntp_global empty_config integration tests on connection={{ ansible_connection }} + +- name: Merged with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_ntp_global: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_ntp_global: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Overridden with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_ntp_global: + config: + state: overridden + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Rendered with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_ntp_global: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' + +- name: Parsed with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_ntp_global: + running_config: + state: parsed + +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state parsed' + +- ansible.builtin.debug: + msg: END nxos_ntp_global empty_config integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tests/common/fixtures/parsed.cfg b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tests/common/fixtures/parsed.cfg new file mode 100644 index 00000000..939f23a6 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tests/common/fixtures/parsed.cfg @@ -0,0 +1,9 @@ +ntp authenticate +ntp logging +ntp master 2 +ntp peer 192.0.2.1 use-vrf default key 1 minpoll 5 maxpoll 15 +ntp peer 192.0.2.2 prefer use-vrf siteA key 2 +ntp server 198.51.100.1 use-vrf default key 2 +ntp server 203.0.113.1 use-vrf siteB key 1 +ntp access-group peer PeerAcl1 +ntp access-group serve ServeAcl1 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tests/common/gathered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tests/common/gathered.yaml new file mode 100644 index 00000000..152b2501 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tests/common/gathered.yaml @@ -0,0 +1,21 @@ +--- +- ansible.builtin.debug: + msg: START nxos_ntp_global gathered integration tests on connection={{ ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Gather logging global facts using gathered + register: result + cisco.nxos.nxos_ntp_global: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: + - "{{ result['gathered'] == merged['after'] }}" + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tests/common/merged.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tests/common/merged.yaml new file mode 100644 index 00000000..096ce69d --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tests/common/merged.yaml @@ -0,0 +1,76 @@ +--- +- ansible.builtin.debug: + msg: "Start nxos_ntp_global merged integration tests connection={{ ansible_connection }}" + +- ansible.builtin.include_tasks: _remove_config.yaml + +- block: + - name: Merge the provided configuration with the existing running configuration + cisco.nxos.nxos_ntp_global: &id001 + config: + access_group: + peer: + - access_list: PeerAcl1 + serve: + - access_list: ServeAcl1 + authenticate: true + logging: true + master: + stratum: 2 + peers: + - peer: 192.0.2.1 + key_id: 1 + maxpoll: 15 + minpoll: 5 + vrf: default + - peer: 192.0.2.2 + key_id: 2 + prefer: true + vrf: siteA + servers: + - server: 198.51.100.1 + key_id: 2 + vrf: default + - server: 203.0.113.1 + key_id: 1 + vrf: siteB + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ result['before'] == {} }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ merged['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ merged['after'] == result['after'] }}" + + - name: Merge the provided configuration with the existing running configuration (idempotent) + cisco.nxos.nxos_ntp_global: *id001 + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + - name: Attempt to configure non-existent auth key (should fail) + cisco.nxos.nxos_ntp_global: + config: + trusted_keys: + - key_id: 12344 + register: result + ignore_errors: true + + - ansible.builtin.assert: + that: + - "result.failed == True" + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tests/common/overridden.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tests/common/overridden.yaml new file mode 100644 index 00000000..86c1a2d5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tests/common/overridden.yaml @@ -0,0 +1,63 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_ntp_global overridden integration tests connection={{ ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Override all logging configuration with provided configuration + cisco.nxos.nxos_ntp_global: &id001 + config: + access_group: + peer: + - access_list: PeerAcl2 + serve: + - access_list: ServeAcl2 + logging: true + master: + stratum: 2 + peers: + - peer: 192.0.2.1 + key_id: 1 + maxpoll: 15 + minpoll: 5 + vrf: default + - peer: 192.0.2.5 + key_id: 2 + prefer: true + vrf: siteA + servers: + - server: 198.51.100.1 + key_id: 2 + vrf: default + state: replaced + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ merged['after'] == result['before'] }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dicts were correctly generated + ansible.builtin.assert: + that: + - replaced['after'] == result['after'] + + - name: Override all logging configuration with provided configuration (idempotent) + register: result + cisco.nxos.nxos_ntp_global: *id001 + + - name: Assert that task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tests/common/parsed.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tests/common/parsed.yaml new file mode 100644 index 00000000..321c2a9f --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tests/common/parsed.yaml @@ -0,0 +1,14 @@ +--- +- ansible.builtin.debug: + msg: START nxos_ntp_global parsed integration tests on connection={{ ansible_connection }} + +- name: Parse externally provided ntp configuration + register: result + cisco.nxos.nxos_ntp_global: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed + +- name: Assert that configuration was correctly parsed + ansible.builtin.assert: + that: + - "{{ merged['after'] == result['parsed'] }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tests/common/rendered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tests/common/rendered.yaml new file mode 100644 index 00000000..0a0007ea --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tests/common/rendered.yaml @@ -0,0 +1,41 @@ +--- +- ansible.builtin.debug: + msg: START nxos_ntp_global rendered integration tests on connection={{ ansible_connection }} + +- name: Render platform specific configuration lines with state rendered (without connecting to the device) + cisco.nxos.nxos_ntp_global: + config: + access_group: + peer: + - access_list: PeerAcl1 + serve: + - access_list: ServeAcl1 + authenticate: true + logging: true + master: + stratum: 2 + peers: + - peer: 192.0.2.1 + key_id: 1 + maxpoll: 15 + minpoll: 5 + vrf: default + - peer: 192.0.2.2 + key_id: 2 + prefer: true + vrf: siteA + servers: + - server: 198.51.100.1 + key_id: 2 + vrf: default + - server: 203.0.113.1 + key_id: 1 + vrf: siteB + state: rendered + register: result + +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - "{{ merged['commands'] | symmetric_difference(result['rendered']) |length == 0 }}" + - result.changed == False diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tests/common/replaced.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tests/common/replaced.yaml new file mode 100644 index 00000000..c657e860 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/tests/common/replaced.yaml @@ -0,0 +1,64 @@ +--- +- ansible.builtin.debug: + msg: "Start nxos_ntp_global replaced integration tests connection={{ ansible_connection }}" + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Replace logging global configurations of listed logging global with provided configurations + cisco.nxos.nxos_ntp_global: &id001 + config: + access_group: + peer: + - access_list: PeerAcl2 + serve: + - access_list: ServeAcl2 + logging: true + master: + stratum: 2 + peers: + - peer: 192.0.2.1 + key_id: 1 + maxpoll: 15 + minpoll: 5 + vrf: default + - peer: 192.0.2.5 + key_id: 2 + prefer: true + vrf: siteA + servers: + - server: 198.51.100.1 + key_id: 2 + vrf: default + state: replaced + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ merged['after'] == result['before'] }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dicts were correctly generated + ansible.builtin.assert: + that: + - replaced['after'] == result['after'] + + - name: Replace logging global configurations with provided configurations (idempotent) + register: result + cisco.nxos.nxos_ntp_global: *id001 + + - name: Assert that task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/vars/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/vars/main.yml new file mode 100644 index 00000000..65b3d6e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_global/vars/main.yml @@ -0,0 +1,85 @@ +--- +merged: + before: {} + commands: + - "ntp authenticate" + - "ntp logging" + - "ntp master 2" + - "ntp peer 192.0.2.1 use-vrf default key 1 minpoll 5 maxpoll 15" + - "ntp peer 192.0.2.2 prefer use-vrf siteA key 2" + - "ntp server 198.51.100.1 use-vrf default key 2" + - "ntp server 203.0.113.1 use-vrf siteB key 1" + - "ntp access-group peer PeerAcl1" + - "ntp access-group serve ServeAcl1" + after: + access_group: + peer: + - access_list: PeerAcl1 + serve: + - access_list: ServeAcl1 + authenticate: true + logging: true + master: + stratum: 2 + peers: + - peer: 192.0.2.1 + key_id: 1 + maxpoll: 15 + minpoll: 5 + vrf: default + - peer: 192.0.2.2 + key_id: 2 + prefer: true + vrf: siteA + servers: + - server: 198.51.100.1 + key_id: 2 + vrf: default + - server: 203.0.113.1 + key_id: 1 + vrf: siteB + +replaced: + commands: + - "no ntp authenticate" + - "ntp peer 192.0.2.5 prefer use-vrf siteA key 2" + - "no ntp peer 192.0.2.2 prefer use-vrf siteA key 2" + - "no ntp server 203.0.113.1 use-vrf siteB key 1" + - "ntp access-group peer PeerAcl2" + - "no ntp access-group peer PeerAcl1" + - "ntp access-group serve ServeAcl2" + - "no ntp access-group serve ServeAcl1" + after: + access_group: + peer: + - access_list: PeerAcl2 + serve: + - access_list: ServeAcl2 + logging: true + master: + stratum: 2 + peers: + - peer: 192.0.2.1 + key_id: 1 + maxpoll: 15 + minpoll: 5 + vrf: default + - peer: 192.0.2.5 + key_id: 2 + prefer: true + vrf: siteA + servers: + - server: 198.51.100.1 + key_id: 2 + vrf: default +deleted: + commands: + - "no ntp authenticate" + - "no ntp logging" + - "no ntp master 2" + - "no ntp peer 192.0.2.1 use-vrf default key 1 minpoll 5 maxpoll 15" + - "no ntp peer 192.0.2.2 prefer use-vrf siteA key 2" + - "no ntp server 198.51.100.1 use-vrf default key 2" + - "no ntp server 203.0.113.1 use-vrf siteB key 1" + - "no ntp access-group peer PeerAcl1" + - "no ntp access-group serve ServeAcl1" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_options/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_options/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_options/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_options/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_options/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_options/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_options/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_options/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_options/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_options/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_options/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_options/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_options/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_options/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_options/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_options/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_options/tests/common/sanity.yaml new file mode 100644 index 00000000..1ee9433e --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ntp_options/tests/common/sanity.yaml @@ -0,0 +1,99 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_ntp_options sanity test + +- name: Apply default ntp configuration + ignore_errors: true + cisco.nxos.nxos_ntp_options: &id007 + state: absent + +- block: + - name: Configure ntp with master and default stratum + register: result + cisco.nxos.nxos_ntp_options: &id001 + master: true + logging: true + state: present + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Check idempotence - configure ntp with master and default stratum + register: result + cisco.nxos.nxos_ntp_options: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Configure ntp with master and non-default stratum + register: result + cisco.nxos.nxos_ntp_options: &id003 + master: true + stratum: 10 + state: present + + - ansible.builtin.assert: *id002 + + - name: Check idempotence - configure ntp with master and non-default stratum + register: result + cisco.nxos.nxos_ntp_options: *id003 + + - ansible.builtin.assert: *id004 + + - name: Configure ntp with master and no logging + register: result + cisco.nxos.nxos_ntp_options: &id005 + master: true + stratum: 10 + logging: false + state: present + + - ansible.builtin.assert: *id002 + + - name: Check idempotence - configure ntp with master and no logging + register: result + cisco.nxos.nxos_ntp_options: *id005 + + - ansible.builtin.assert: *id004 + + - name: Configure ntp with logging and no master + register: result + cisco.nxos.nxos_ntp_options: &id006 + master: false + logging: true + state: present + + - ansible.builtin.assert: *id002 + + - name: Check idempotence - configure ntp with logging and no master + register: result + cisco.nxos.nxos_ntp_options: *id006 + + - ansible.builtin.assert: *id004 + + - name: Configure ntp with master and non-default stratum again + register: result + cisco.nxos.nxos_ntp_options: *id003 + + - ansible.builtin.assert: *id002 + + - name: Remove ntp options + register: result + cisco.nxos.nxos_ntp_options: *id007 + + - ansible.builtin.assert: *id002 + + - name: Check idempotence - remove + register: result + cisco.nxos.nxos_ntp_options: *id007 + + - ansible.builtin.assert: *id004 + always: + - name: Cleanup ntp configuration + register: result + cisco.nxos.nxos_ntp_options: *id007 + + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_ntp_options sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/nxapi.yaml new file mode 100644 index 00000000..25cdd490 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/nxapi.yaml @@ -0,0 +1,41 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" +- name: Run test cases (connection=local) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: local + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/default/assert_changes_http.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/default/assert_changes_http.yaml new file mode 100644 index 00000000..aac4fb89 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/default/assert_changes_http.yaml @@ -0,0 +1,16 @@ +--- +- name: Assert http configuration changes + ansible.builtin.assert: + that: + - result.stdout[0]['TABLE_listen_on_port']['ROW_listen_on_port'].l_port + - result.stdout[0]['TABLE_listen_on_port']['ROW_listen_on_port'].l_port|string is search("80") + - result.stdout[0]['operation_status'].o_status == 'nxapi enabled' + when: result.stdout[0].TABLE_listen_on_port is defined + +- name: Assert http configuration changes 9.2 or greater + ansible.builtin.assert: + that: + - result.stdout[0]['http_port'] + - result.stdout[0]['http_port']|string is search("80") + - result.stdout[0]['nxapi_status'] == 'nxapi enabled' + when: result.stdout[0].http_port is defined diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/default/assert_changes_https.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/default/assert_changes_https.yaml new file mode 100644 index 00000000..6cb4e5ac --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/default/assert_changes_https.yaml @@ -0,0 +1,16 @@ +--- +- name: Assert https configuration changes + ansible.builtin.assert: + that: + - result.stdout[0]['TABLE_listen_on_port']['ROW_listen_on_port'].l_port + - result.stdout[0]['TABLE_listen_on_port']['ROW_listen_on_port'].l_port|string is search("9443") + - result.stdout[0]['operation_status'].o_status == 'nxapi enabled' + when: result.stdout[0].TABLE_listen_on_port is defined + +- name: Assert https configuration changes 9.2 or greater + ansible.builtin.assert: + that: + - result.stdout[0]['https_port'] + - result.stdout[0]['https_port']|string is search("9443") + - result.stdout[0]['nxapi_status'] == 'nxapi enabled' + when: result.stdout[0].https_port is defined diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/default/assert_changes_https_http.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/default/assert_changes_https_http.yaml new file mode 100644 index 00000000..fd3fb8c9 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/default/assert_changes_https_http.yaml @@ -0,0 +1,20 @@ +--- +- name: Assert https & http configuration changes + ansible.builtin.assert: + that: + - result.stdout[0]['TABLE_listen_on_port']['ROW_listen_on_port'][1].l_port + - result.stdout[0]['TABLE_listen_on_port']['ROW_listen_on_port'][1].l_port|string is search("9443") + - result.stdout[0]['TABLE_listen_on_port']['ROW_listen_on_port'][0].l_port + - result.stdout[0]['TABLE_listen_on_port']['ROW_listen_on_port'][0].l_port|string is search("80") + - result.stdout[0]['operation_status'].o_status == 'nxapi enabled' + when: result.stdout[0].TABLE_listen_on_port is defined + +- name: Assert https & http configuration changes 9.2 or greater + ansible.builtin.assert: + that: + - result.stdout[0]['https_port'] + - result.stdout[0]['https_port']|string is search("9443") + - result.stdout[0]['http_port'] + - result.stdout[0]['http_port']|string is search("80") + - result.stdout[0]['nxapi_status'] == 'nxapi enabled' + when: result.stdout[0].https_port is defined or result.stdout[0].http_port is defined diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/default/assert_changes_https_http_ports.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/default/assert_changes_https_http_ports.yaml new file mode 100644 index 00000000..38061aed --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/default/assert_changes_https_http_ports.yaml @@ -0,0 +1,20 @@ +--- +- name: Assert https & http configuration changes + ansible.builtin.assert: + that: + - result.stdout[0]['TABLE_listen_on_port']['ROW_listen_on_port'][1].l_port + - result.stdout[0]['TABLE_listen_on_port']['ROW_listen_on_port'][1].l_port|string is search("500") + - result.stdout[0]['TABLE_listen_on_port']['ROW_listen_on_port'][0].l_port + - result.stdout[0]['TABLE_listen_on_port']['ROW_listen_on_port'][0].l_port|string is search("99") + - result.stdout[0]['operation_status'].o_status == 'nxapi enabled' + when: result.stdout[0].TABLE_listen_on_port is defined + +- name: Assert https & http configuration changes 9.2 or greater + ansible.builtin.assert: + that: + - result.stdout[0]['https_port'] + - result.stdout[0]['https_port']|string is search("500") + - result.stdout[0]['http_port'] + - result.stdout[0]['http_port']|string is search("99") + - result.stdout[0]['nxapi_status'] == 'nxapi enabled' + when: result.stdout[0].https_port is defined or result.stdout[0].http_port is defined diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/n5k/assert_changes_http.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/n5k/assert_changes_http.yaml new file mode 100644 index 00000000..452fb8c0 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/n5k/assert_changes_http.yaml @@ -0,0 +1,6 @@ +--- +- name: Assert http configuration changes + ansible.builtin.assert: + that: + - result.stdout[0].https_port is not defined + - result.stdout[0].http_port|string is search("80") diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/n5k/assert_changes_https.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/n5k/assert_changes_https.yaml new file mode 100644 index 00000000..1abeb020 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/n5k/assert_changes_https.yaml @@ -0,0 +1,6 @@ +--- +- name: Assert https configuration changes + ansible.builtin.assert: + that: + - result.stdout[0].http_port is not defined + - result.stdout[0].https_port|string is search("9443") diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/n5k/assert_changes_https_http.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/n5k/assert_changes_https_http.yaml new file mode 100644 index 00000000..e1c2ad2d --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/n5k/assert_changes_https_http.yaml @@ -0,0 +1,8 @@ +--- +- name: Assert https && http configuration changes + ansible.builtin.assert: + that: + - result.stdout[0].https_port is defined + - result.stdout[0].http_port is defined + - result.stdout[0].https_port|string is search("9443") + - result.stdout[0].http_port|string is search("80") diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/n5k/assert_changes_https_http_ports.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/n5k/assert_changes_https_http_ports.yaml new file mode 100644 index 00000000..d9d906a7 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/n5k/assert_changes_https_http_ports.yaml @@ -0,0 +1,8 @@ +--- +- name: Assert https && http configuration changes + ansible.builtin.assert: + that: + - result.stdout[0].https_port is defined + - result.stdout[0].http_port is defined + - result.stdout[0].https_port|string is search("500") + - result.stdout[0].http_port|string is search("99") diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/n7k/assert_changes_http.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/n7k/assert_changes_http.yaml new file mode 100644 index 00000000..af44dac4 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/n7k/assert_changes_http.yaml @@ -0,0 +1,7 @@ +--- +- name: Assert http configuration changes + ansible.builtin.assert: + that: + - result.stdout[0].https_port is not defined + - result.stdout[0].http_port|string is search("80") + - result.stdout[0].sandbox_status == 'Enabled' diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/n7k/assert_changes_https.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/n7k/assert_changes_https.yaml new file mode 100644 index 00000000..42f6d6e6 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/n7k/assert_changes_https.yaml @@ -0,0 +1,7 @@ +--- +- name: Assert https configuration changes + ansible.builtin.assert: + that: + - result.stdout[0].http_port is not defined + - result.stdout[0].https_port|string is search("9443") + - result.stdout[0].sandbox_status == 'Enabled' diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/n7k/assert_changes_https_http.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/n7k/assert_changes_https_http.yaml new file mode 100644 index 00000000..cc1b87aa --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/n7k/assert_changes_https_http.yaml @@ -0,0 +1,9 @@ +--- +- name: Assert https & http configuration changes + ansible.builtin.assert: + that: + - result.stdout[0].https_port is defined + - result.stdout[0].http_port is defined + - result.stdout[0].https_port|string is search("9443") + - result.stdout[0].http_port|string is search("80") + - result.stdout[0].sandbox_status == 'Enabled' diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/n7k/assert_changes_https_http_ports.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/n7k/assert_changes_https_http_ports.yaml new file mode 100644 index 00000000..141084d0 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tasks/platform/n7k/assert_changes_https_http_ports.yaml @@ -0,0 +1,9 @@ +--- +- name: Assert https & http configuration changes + ansible.builtin.assert: + that: + - result.stdout[0].https_port is defined + - result.stdout[0].http_port is defined + - result.stdout[0].https_port|string is search("500") + - result.stdout[0].http_port|string is search("99") + - result.stdout[0].sandbox_status == 'Enabled' diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tests/cli/configure.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tests/cli/configure.yaml new file mode 100644 index 00000000..fb0f380f --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tests/cli/configure.yaml @@ -0,0 +1,144 @@ +--- +- ansible.builtin.debug: + msg: START cli/configure.yaml + +- name: Set a fact for 'nxapi_sandbox_option' + ansible.builtin.set_fact: + nxapi_sandbox_option: true + when: platform is search('N7K') + +- name: Setup - put NX-API in stopped state + cisco.nxos.nxos_nxapi: + state: absent + +- block: + - name: Configure NX-API https + register: result + cisco.nxos.nxos_nxapi: &id001 + enable_http: false + enable_sandbox: "{{nxapi_sandbox_option|default(omit)}}" + enable_https: true + https_port: 9443 + + - register: result + cisco.nxos.nxos_command: + commands: + - show nxapi | json + + - ansible.builtin.include_tasks: tasks/platform/n7k/assert_changes_https.yaml + when: platform is match('N7K') + + - ansible.builtin.include_tasks: tasks/platform/n5k/assert_changes_https.yaml + when: platform is search('N5K|N6K') + + - ansible.builtin.include_tasks: tasks/platform/default/assert_changes_https.yaml + when: platform is not search('N35|N5K|N6K|N7K') + + - name: Configure NX-API https again + register: result + cisco.nxos.nxos_nxapi: *id001 + + - name: Assert configuration is idempotent + ansible.builtin.assert: &id003 + that: + - result.changed == false + + - name: Configure NX-API https & http + register: result + cisco.nxos.nxos_nxapi: &id002 + enable_http: true + enable_sandbox: "{{nxapi_sandbox_option|default(omit)}}" + enable_https: true + https_port: 9443 + + - register: result + cisco.nxos.nxos_command: + commands: + - show nxapi | json + + - ansible.builtin.include_tasks: tasks/platform/n7k/assert_changes_https_http.yaml + when: platform is match('N7K') + + - ansible.builtin.include_tasks: tasks/platform/n5k/assert_changes_https_http.yaml + when: platform is match('N5K') + + - ansible.builtin.include_tasks: tasks/platform/default/assert_changes_https_http.yaml + when: platform is not search('N35|N5K|N6K|N7K') + + - name: Configure NX-API https & http again + register: result + cisco.nxos.nxos_nxapi: *id002 + + - name: Assert configuration is idempotent + ansible.builtin.assert: *id003 + + - name: Configure different NX-API https & http ports + register: result + cisco.nxos.nxos_nxapi: &id004 + enable_http: true + enable_sandbox: "{{nxapi_sandbox_option|default(omit)}}" + enable_https: true + http_port: 99 + https_port: 500 + + - register: result + cisco.nxos.nxos_command: + commands: + - show nxapi | json + + - ansible.builtin.include_tasks: tasks/platform/n7k/assert_changes_https_http_ports.yaml + when: platform is match('N7K') + + - ansible.builtin.include_tasks: tasks/platform/n5k/assert_changes_https_http_ports.yaml + when: platform is match('N5K') + + - ansible.builtin.include_tasks: tasks/platform/default/assert_changes_https_http_ports.yaml + when: platform is not search('N35|N5K|N6K|N7K') + + - name: Configure different NX-API https & http ports again + register: result + cisco.nxos.nxos_nxapi: *id004 + + - name: Assert configuration is idempotent + ansible.builtin.assert: *id003 + + - name: Configure NX-API http + register: result + cisco.nxos.nxos_nxapi: &id005 + enable_http: true + enable_sandbox: "{{nxapi_sandbox_option|default(omit)}}" + enable_https: false + + - register: result + cisco.nxos.nxos_command: + commands: + - show nxapi | json + + - ansible.builtin.include_tasks: tasks/platform/n7k/assert_changes_http.yaml + when: platform is match('N7K') + + - ansible.builtin.include_tasks: tasks/platform/n5k/assert_changes_http.yaml + when: platform is match('N5K') + + - ansible.builtin.include_tasks: tasks/platform/default/assert_changes_http.yaml + when: platform is not search('N35|N5K|N6K|N7K') + + - name: Configure NX-API http again + register: result + cisco.nxos.nxos_nxapi: *id005 + + - name: Assert configuration is idempotent + ansible.builtin.assert: *id003 + always: + - name: Cleanup - disable NX-API + register: result + cisco.nxos.nxos_nxapi: + state: absent + + - name: Cleanup - re-enable NX-API + register: result + cisco.nxos.nxos_nxapi: + state: present + + - ansible.builtin.debug: + msg: END cli/configure.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tests/cli/disable.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tests/cli/disable.yaml new file mode 100644 index 00000000..54eea69a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tests/cli/disable.yaml @@ -0,0 +1,30 @@ +--- +- ansible.builtin.debug: + msg: START cli/disable.yaml + +- name: Disable NX-API + register: result + cisco.nxos.nxos_nxapi: + state: absent + +- name: Check NX-API state + register: result + cisco.nxos.nxos_command: + commands: + - show feature | grep nxapi + +- name: Assert NX-API is disabled + ansible.builtin.assert: + that: result.stdout[0] is search('disabled') + +- name: Disable NX-API again + register: result + cisco.nxos.nxos_nxapi: + state: absent + +- name: Assert idempotence + ansible.builtin.assert: + that: result.changed == false + +- ansible.builtin.debug: + msg: END cli/disable.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tests/cli/enable.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tests/cli/enable.yaml new file mode 100644 index 00000000..267d075d --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tests/cli/enable.yaml @@ -0,0 +1,34 @@ +--- +- ansible.builtin.debug: + msg: START cli/enable.yaml + +- name: Setup - put NX-API in stopped state + register: result + cisco.nxos.nxos_nxapi: + state: absent + +- name: Enable NX-API + register: result + cisco.nxos.nxos_nxapi: + state: present + +- name: Check NX-API state + register: result + cisco.nxos.nxos_command: + commands: + - show feature | grep nxapi + +- name: Assert NX-API is enabled + ansible.builtin.assert: + that: result.stdout[0] is search('enabled') + +- name: Enable NX-API again + register: result + cisco.nxos.nxos_nxapi: + +- name: Assert idempotence + ansible.builtin.assert: + that: result.changed == false + +- ansible.builtin.debug: + msg: END cli/enable.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tests/cli/nxapi_ssl.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tests/cli/nxapi_ssl.yaml new file mode 100644 index 00000000..6e4a8c21 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tests/cli/nxapi_ssl.yaml @@ -0,0 +1,251 @@ +--- +- block: + - ansible.builtin.debug: + msg: START cli/nxapi_ssl.yaml + + - name: Configure NX-API https w/weak ciphers + register: result + cisco.nxos.nxos_nxapi: &id001 + enable_https: true + enable_sandbox: "{{nxapi_sandbox_option|default(omit)}}" + ssl_strong_ciphers: false + + - register: result + cisco.nxos.nxos_command: + commands: + - show run all | inc nxapi | inc ciphers + + - name: Assert weak ciphers configuration + ansible.builtin.assert: + that: + - result.stdout_lines[0][0] == 'nxapi ssl ciphers weak' + + - name: Configure NX-API http w/weak ciphers again + register: result + cisco.nxos.nxos_nxapi: *id001 + + - name: Assert configuration is idempotent + ansible.builtin.assert: &id003 + that: + - result.changed == false + + - name: Configure NX-API https w/strong ciphers + register: result + cisco.nxos.nxos_nxapi: &id002 + enable_https: true + enable_sandbox: "{{nxapi_sandbox_option|default(omit)}}" + ssl_strong_ciphers: true + + - register: result + cisco.nxos.nxos_command: + commands: + - show run all | inc nxapi | inc ciphers + + - name: Assert strong ciphers configuration + ansible.builtin.assert: + that: + - result.stdout_lines[0][0] == 'no nxapi ssl ciphers weak' + + - name: Configure NX-API https w/strong ciphers again + register: result + cisco.nxos.nxos_nxapi: *id002 + + - name: Assert configuration is idempotent + ansible.builtin.assert: *id003 + + - name: Configure NX-API https w/default tlsv1 + register: result + cisco.nxos.nxos_nxapi: &id004 + enable_https: true + enable_sandbox: "{{nxapi_sandbox_option|default(omit)}}" + + - register: result + cisco.nxos.nxos_command: + commands: + - show run all | inc nxapi | inc protocols + + - name: Assert NX-API https w/default tlsv1 configuration + ansible.builtin.assert: + that: + - result.stdout_lines[0][0] == 'nxapi ssl protocols TLSv1' + + - name: Configure NX-API https w/default again + register: result + cisco.nxos.nxos_nxapi: *id004 + + - name: Assert configuration is idempotent + ansible.builtin.assert: *id003 + + - name: Configure NX-API https tlsv1.1 -default tlsv1 + register: result + cisco.nxos.nxos_nxapi: &id005 + enable_https: true + enable_sandbox: "{{nxapi_sandbox_option|default(omit)}}" + tlsv1_1: true + tlsv1_0: false + + - register: result + cisco.nxos.nxos_command: + commands: + - show run all | inc nxapi | inc protocols + + - name: Assert NX-API https w/tlsv1.1 configuration + ansible.builtin.assert: + that: + - result.stdout_lines[0][0] == 'nxapi ssl protocols TLSv1.1' + + - name: Configure NX-API https w/tlsv1.1 -default tlsv1 again + register: result + cisco.nxos.nxos_nxapi: *id005 + + - name: Assert configuration is idempotent + ansible.builtin.assert: *id003 + + - name: Configure NX-API https tlsv1.2 -default tlsv1 + register: result + cisco.nxos.nxos_nxapi: &id006 + enable_https: true + enable_sandbox: "{{nxapi_sandbox_option|default(omit)}}" + tlsv1_2: true + tlsv1_0: false + + - register: result + cisco.nxos.nxos_command: + commands: + - show run all | inc nxapi | inc protocols + + - name: Assert NX-API https w/tlsv1.2 configuration + ansible.builtin.assert: + that: + - result.stdout_lines[0][0] == 'nxapi ssl protocols TLSv1.2' + + - name: Configure NX-API https w/tlsv1.2 -default tlsv1 again + register: result + cisco.nxos.nxos_nxapi: *id006 + + - name: Assert configuration is idempotent + ansible.builtin.assert: *id003 + + - name: Configure NX-API https w/tls1.2 +default tlsv1 + register: result + cisco.nxos.nxos_nxapi: &id007 + enable_https: true + enable_sandbox: "{{nxapi_sandbox_option|default(omit)}}" + ssl_strong_ciphers: true + tlsv1_2: true + + - register: result + cisco.nxos.nxos_command: + commands: + - show run all | inc nxapi | inc protocols + + - name: Assert NX-API https w/tls1.2 +default tlsv1 configuration + ansible.builtin.assert: + that: + - result.stdout_lines[0][0] == 'nxapi ssl protocols TLSv1 TLSv1.2' + + - name: Configure NX-API https w/tls1.2 again + register: result + cisco.nxos.nxos_nxapi: *id007 + + - name: Assert configuration is idempotent + ansible.builtin.assert: *id003 + + - name: Configure NX-API https w/tls1.2 tls1.1 -default tlsv1 + register: result + cisco.nxos.nxos_nxapi: &id008 + enable_https: true + enable_sandbox: "{{nxapi_sandbox_option|default(omit)}}" + ssl_strong_ciphers: true + tlsv1_0: false + tlsv1_1: true + tlsv1_2: true + + - register: result + cisco.nxos.nxos_command: + commands: + - show run all | inc nxapi | inc protocols + + - name: Assert NX-API https w/tls1.2 tls1.2 -default tlsv1 configuration + ansible.builtin.assert: + that: + - result.stdout_lines[0][0] == 'nxapi ssl protocols TLSv1.1 TLSv1.2' + + - name: Configure NX-API https w/tls1.2 tls1.1 -default tlsv1 again + register: result + cisco.nxos.nxos_nxapi: *id008 + + - name: Assert configuration is idempotent + ansible.builtin.assert: *id003 + + - name: Configure NX-API https w/tls1.2 tls1.1 +default tlsv1 + register: result + cisco.nxos.nxos_nxapi: &id009 + enable_https: true + enable_sandbox: "{{nxapi_sandbox_option|default(omit)}}" + ssl_strong_ciphers: true + tlsv1_1: true + tlsv1_2: true + + - register: result + cisco.nxos.nxos_command: + commands: + - show run all | inc nxapi | inc protocols + + - name: Assert NX-API https w/tls1.2 tls1.1 +default tlsv1 configuration + ansible.builtin.assert: + that: + - result.stdout_lines[0][0] == 'nxapi ssl protocols TLSv1 TLSv1.1 TLSv1.2' + + - name: Configure NX-API https w/tls1.2 tls1.1 +default tlsv1 again + register: result + cisco.nxos.nxos_nxapi: *id009 + + - name: Assert configuration is idempotent + ansible.builtin.assert: *id003 + + - name: Configure NX-API https with explicit tls1.2 tls1.1 tlsv1 + register: result + cisco.nxos.nxos_nxapi: &id010 + enable_https: true + enable_sandbox: "{{nxapi_sandbox_option|default(omit)}}" + ssl_strong_ciphers: true + tlsv1_0: true + tlsv1_1: true + tlsv1_2: true + + - register: result + cisco.nxos.nxos_command: + commands: + - show run all | inc nxapi | inc protocols + + - name: Assert NX-API https w/tls1.2 tls1.2 tlsv1 configuration + ansible.builtin.assert: + that: + - result.stdout_lines[0][0] == 'nxapi ssl protocols TLSv1 TLSv1.1 TLSv1.2' + + - name: Configure NX-API https w/tls1.2 tls1.1 tlsv1 again + register: result + cisco.nxos.nxos_nxapi: *id010 + + - name: Assert configuration is idempotent + ansible.builtin.assert: *id003 + always: + - name: Cleanup - disable NX-API + register: result + cisco.nxos.nxos_nxapi: + state: absent + + - name: Cleanup - re-enable NX-API + register: result + cisco.nxos.nxos_nxapi: + state: present + + - ansible.builtin.debug: + msg: END cli/nxapi_ssl.yaml + when: >- + (platform is match("N9K") or + platform is match("N3K") or + platform is match("N9K-F") or + platform is match("N35") or + platform is match("N3L")) and major_version is version('9.2', '>=') diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tests/nxapi/badtransport.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tests/nxapi/badtransport.yaml new file mode 100644 index 00000000..5e81ff9b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_nxapi/tests/nxapi/badtransport.yaml @@ -0,0 +1,18 @@ +--- +- ansible.builtin.debug: + msg: START nxapi/badtransport.yaml + +- name: Sending transport other than CLI should fail + register: result + ignore_errors: true + cisco.nxos.nxos_nxapi: + enable_http: false + enable_sandbox: false + https_port: 9443 + +- ansible.builtin.assert: + that: + - result.failed and result.msg is search('Transport') + +- ansible.builtin.debug: + msg: END nxapi/badtransport.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/defaults/main.yaml new file mode 100644 index 00000000..871ea460 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "[^_].*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tasks/cli.yaml new file mode 100644 index 00000000..9e4fb34b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tasks/main.yaml new file mode 100644 index 00000000..1621aaca --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tasks/main.yaml @@ -0,0 +1,29 @@ +--- +- name: Enable OSPF v2 and v3 features + cisco.nxos.nxos_config: + lines: + - feature ospf + - feature ospfv3 + vars: + ansible_connection: ansible.netcommon.network_cli + +- name: Run the CLI and NX-API tests + block: + - name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli.yaml + + - name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi + + always: + - name: Disable OSPF v2 and v3 features + cisco.nxos.nxos_config: + lines: + - feature ospf + - feature ospfv3 + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tasks/nxapi.yaml new file mode 100644 index 00000000..5cb76e67 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/_populate_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/_populate_config.yaml new file mode 100644 index 00000000..d3cae2c4 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/_populate_config.yaml @@ -0,0 +1,19 @@ +--- +- name: Populate configuration + cisco.nxos.nxos_config: + lines: + - "interface {{ nxos_int1 }}" + - " ip router ospf 100 area 1.1.1.1 secondaries none" + - " ip router ospf multi-area 11.11.11.11" + - " ipv6 router ospfv3 200 area 2.2.2.2" + - " ipv6 router ospfv3 multi-area 16.10.10.10" + - " ipv6 router ospfv3 multi-area 21.0.0.0" + - " ipv6 router ospfv3 multi-area 50.50.50.50" + - "interface {{ nxos_int2 }}" + - " ip ospf authentication" + - " ip ospf authentication key-chain test-1" + - " ip ospf cost 100" + - " ospfv3 network broadcast" + - " ospfv3 shutdown" + - "interface {{ nxos_int3 }}" + - " ip ospf cost 101" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/_remove_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/_remove_config.yaml new file mode 100644 index 00000000..f22ef29e --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/_remove_config.yaml @@ -0,0 +1,10 @@ +--- +- name: Default interfaces + cisco.nxos.nxos_config: + lines: + - "default interface {{ nxos_int1 }}" + - "default interface {{ nxos_int2 }}" + - "default interface {{ nxos_int3 }}" + ignore_errors: true + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/_setup.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/_setup.yaml new file mode 100644 index 00000000..319398d5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/_setup.yaml @@ -0,0 +1,12 @@ +--- +- name: "Populate interfaces" + cisco.nxos.nxos_config: + lines: + - "no switchport" + parents: "interface {{ item }}" + loop: + - "{{ nxos_int1 }}" + - "{{ nxos_int2 }}" + - "{{ nxos_int3 }}" + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/deleted.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/deleted.yaml new file mode 100644 index 00000000..93835760 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/deleted.yaml @@ -0,0 +1,101 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_ospf_interfaces deleted integration tests connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _setup.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- name: Set a fact for 'int1', 'int2', and 'int3' + ansible.builtin.set_fact: + int1: + name: "{{ nxos_int1 }}" + int2: + name: "{{ nxos_int2 }}" + int3: + name: "{{ nxos_int3 }}" + +- block: + - name: Delete OSPF configuration from a single interface + cisco.nxos.nxos_ospf_interfaces: &id001 + config: + - name: "{{ nxos_int1 }}" + state: deleted + register: result + + - name: Assert that before dicts are correctly generated + ansible.builtin.assert: + that: + - result["before"][0] == merged["after"][0] + - result["before"][1] == merged["after"][1] + - result["before"][2] == merged["after"][2] + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - '"interface {{ nxos_int1 }}" in result.commands' + - '"no ip router ospf 100 area 1.1.1.1 secondaries none" in result.commands' + - '"no ip router ospf multi-area 11.11.11.11" in result.commands' + - '"no ipv6 router ospfv3 200 area 2.2.2.2" in result.commands' + - '"no ipv6 router ospfv3 multi-area 21.0.0.0" in result.commands' + - '"no ipv6 router ospfv3 multi-area 50.50.50.50" in result.commands' + - '"no ipv6 router ospfv3 multi-area 16.10.10.10" in result.commands' + - result.commands|length == 7 + + - name: Assert that after dict is correctly generated + ansible.builtin.assert: + that: + - result["after"][0] == int1 + - result["after"][1] == merged["after"][1] + - result["after"][2] == merged["after"][2] + + - name: Delete OSPF configuration from a single interface (idempotent) + register: result + cisco.nxos.nxos_ospf_interfaces: *id001 + + - name: Assert that task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + - ansible.builtin.include_tasks: _populate_config.yaml + + - name: Delete OSPF configuration from all interfaces + cisco.nxos.nxos_ospf_interfaces: &id002 + state: deleted + register: result + + - name: Assert that before dicts are correctly generated + ansible.builtin.assert: + that: + - result["before"][0] == merged["after"][0] + - result["before"][1] == merged["after"][1] + - result["before"][2] == merged["after"][2] + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ deleted['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dict is correctly generated + ansible.builtin.assert: + that: + - result["after"][0] == int1 + - result["after"][1] == int2 + - result["after"][2] == int3 + + - name: Delete OSPF configuration from all interfaces (idempotent) + register: result + cisco.nxos.nxos_ospf_interfaces: *id002 + + - name: Assert that task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/empty_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/empty_config.yaml new file mode 100644 index 00000000..485e94cb --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/empty_config.yaml @@ -0,0 +1,61 @@ +--- +- ansible.builtin.debug: + msg: START nxos_ospf_interfaces empty_config integration tests on connection={{ ansible_connection }} + +- name: Merged with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_ospf_interfaces: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_ospf_interfaces: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Overridden with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_ospf_interfaces: + config: + state: overridden + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Rendered with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_ospf_interfaces: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' + +- name: Parsed with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_ospf_interfaces: + running_config: + state: parsed + +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state parsed' + +- ansible.builtin.debug: + msg: END nxos_ospf_interfaces empty_config integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/fixtures/parsed.cfg b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/fixtures/parsed.cfg new file mode 100644 index 00000000..b089500c --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/fixtures/parsed.cfg @@ -0,0 +1,15 @@ +interface Ethernet1/1 + ip router ospf 100 area 1.1.1.1 secondaries none + ip router ospf multi-area 11.11.11.11 + ipv6 router ospfv3 200 area 2.2.2.2 + ipv6 router ospfv3 multi-area 16.10.10.10 + ipv6 router ospfv3 multi-area 21.0.0.0 + ipv6 router ospfv3 multi-area 50.50.50.50 +interface Ethernet1/2 + ip ospf authentication + ip ospf authentication key-chain test-1 + ip ospf cost 100 + ospfv3 network broadcast + ospfv3 shutdown +interface Ethernet1/3 + ip ospf cost 101 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/gathered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/gathered.yaml new file mode 100644 index 00000000..39cca32a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/gathered.yaml @@ -0,0 +1,25 @@ +--- +- ansible.builtin.debug: + msg: START nxos_ospf_interfaces gathered integration tests on connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _setup.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Gather OSPF interfaces facts using gathered + register: result + cisco.nxos.nxos_ospf_interfaces: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: + - result["gathered"][0] == merged["after"][0] + - result["gathered"][1] == merged["after"][1] + - result["gathered"][2] == merged["after"][2] + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/merged.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/merged.yaml new file mode 100644 index 00000000..6bdbbe36 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/merged.yaml @@ -0,0 +1,78 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_ospf_interfaces merged integration tests connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _setup.yaml + +- block: + - name: Merge the provided configuration with the existing running configuration + cisco.nxos.nxos_ospf_interfaces: &id001 + config: + - name: "{{ nxos_int1 }}" + address_family: + - afi: ipv4 + processes: + - process_id: "100" + area: + area_id: 1.1.1.1 + secondaries: false + multi_areas: + - 11.11.11.11 + - afi: ipv6 + processes: + - process_id: "200" + area: + area_id: 2.2.2.2 + multi_areas: + - 21.0.0.0 + - 50.50.50.50 + - 16.10.10.10 + - name: "{{ nxos_int2 }}" + address_family: + - afi: ipv4 + authentication: + enable: true + key_chain: test-1 + cost: 100 + - afi: ipv6 + network: broadcast + shutdown: true + - name: "{{ nxos_int3 }}" + address_family: + - afi: ipv4 + cost: 101 + state: merged + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: + - result["before"][0] == merged["before"][0] + - result["before"][1] == merged["before"][1] + - result["before"][2] == merged["before"][2] + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ merged['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ result['after'][0] == merged['after'][0] }}" + - "{{ result['after'][1] == merged['after'][1] }}" + - "{{ result['after'][2] == merged['after'][2] }}" + + - name: Merge the provided configuration with the existing running configuration (idempotent) + cisco.nxos.nxos_ospf_interfaces: *id001 + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/overridden.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/overridden.yaml new file mode 100644 index 00000000..9f4941c8 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/overridden.yaml @@ -0,0 +1,57 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_ospf_interfaces overridden integration tests connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _setup.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Override all OSPF interfaces configuration with provided configuration + cisco.nxos.nxos_ospf_interfaces: &id001 + config: + - name: Ethernet1/1 + address_family: + - afi: ipv4 + processes: + - process_id: "100" + area: + area_id: 1.1.1.1 + secondaries: false + multi_areas: + - 11.11.11.12 + state: overridden + register: result + + - name: Assert that before dicts are correctly generated + ansible.builtin.assert: + that: + - result["before"][0] == merged["after"][0] + - result["before"][1] == merged["after"][1] + - result["before"][2] == merged["after"][2] + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ overridden['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dict is correctly generated + ansible.builtin.assert: + that: + - result['after'][0] == overridden['after'][0] + - result['after'][1] == overridden['after'][1] + - result['after'][2] == overridden['after'][2] + + - name: Override all OSPF interfaces configuration with provided configuration (idempotent) + register: result + cisco.nxos.nxos_ospf_interfaces: *id001 + + - name: Assert that task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/parsed.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/parsed.yaml new file mode 100644 index 00000000..eb94fcdc --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/parsed.yaml @@ -0,0 +1,14 @@ +--- +- ansible.builtin.debug: + msg: START nxos_ospf_interfaces parsed integration tests on connection={{ ansible_connection }} + +- name: Parse externally provided OSPF interfaces configuration + register: result + cisco.nxos.nxos_ospf_interfaces: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed + +- name: Assert that configuration was correctly parsed + ansible.builtin.assert: + that: + - "{{ merged['after'] | symmetric_difference(result['parsed']) |length == 0 }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/rendered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/rendered.yaml new file mode 100644 index 00000000..cf3a5cc6 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/rendered.yaml @@ -0,0 +1,48 @@ +--- +- ansible.builtin.debug: + msg: START nxos_ospf_interfaces rendered integration tests on connection={{ ansible_connection }} + +- name: Render platform specific configuration lines with state rendered (without connecting to the device) + cisco.nxos.nxos_ospf_interfaces: + config: + - name: "{{ nxos_int1 }}" + address_family: + - afi: ipv4 + processes: + - process_id: "100" + area: + area_id: 1.1.1.1 + secondaries: false + multi_areas: + - 11.11.11.11 + - afi: ipv6 + processes: + - process_id: "200" + area: + area_id: 2.2.2.2 + multi_areas: + - 21.0.0.0 + - 50.50.50.50 + - 16.10.10.10 + - name: "{{ nxos_int2 }}" + address_family: + - afi: ipv4 + authentication: + enable: true + key_chain: test-1 + cost: 100 + - afi: ipv6 + network: broadcast + shutdown: true + - name: "{{ nxos_int3 }}" + address_family: + - afi: ipv4 + cost: 101 + state: rendered + register: result + +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - "{{ merged['commands'] | symmetric_difference(result['rendered']) |length == 0 }}" + - result.changed == False diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/replaced.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/replaced.yaml new file mode 100644 index 00000000..ace52da0 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/tests/common/replaced.yaml @@ -0,0 +1,59 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_ospf_interfaces replaced integration tests connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _setup.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Replace OSPF configurations of listed interfaces with provided configurations + cisco.nxos.nxos_ospf_interfaces: &id001 + config: + - name: "{{ nxos_int1 }}" + address_family: + - afi: ipv4 + processes: + - process_id: "100" + area: + area_id: 1.1.1.1 + secondaries: false + multi_areas: + - 11.11.11.12 + - name: "{{ nxos_int3 }}" + state: replaced + register: result + + - name: Assert that before dicts are correctly generated + ansible.builtin.assert: + that: + - result["before"][0] == merged["after"][0] + - result["before"][1] == merged["after"][1] + - result["before"][2] == merged["after"][2] + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dict is correctly generated + ansible.builtin.assert: + that: + - result['after'][0] == replaced['after'][0] + - result['after'][1] == replaced['after'][1] + - result['after'][2] == replaced['after'][2] + + - name: Replace OSPF configurations of listed interfaces with provided configurations (idempotent) + register: result + cisco.nxos.nxos_ospf_interfaces: *id001 + + - name: Assert that task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/vars/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/vars/main.yml new file mode 100644 index 00000000..29df4d48 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospf_interfaces/vars/main.yml @@ -0,0 +1,137 @@ +--- +merged: + before: + - name: "{{ nxos_int1 }}" + - name: "{{ nxos_int2 }}" + - name: "{{ nxos_int3 }}" + commands: + - "interface {{ nxos_int1 }}" + - "ip router ospf 100 area 1.1.1.1 secondaries none" + - "ip router ospf multi-area 11.11.11.11" + - "ipv6 router ospfv3 200 area 2.2.2.2" + - "ipv6 router ospfv3 multi-area 16.10.10.10" + - "ipv6 router ospfv3 multi-area 21.0.0.0" + - "ipv6 router ospfv3 multi-area 50.50.50.50" + - "interface {{ nxos_int2 }}" + - "ip ospf authentication" + - "ip ospf authentication key-chain test-1" + - "ip ospf cost 100" + - "ospfv3 network broadcast" + - "ospfv3 shutdown" + - "interface {{ nxos_int3 }}" + - "ip ospf cost 101" + after: + - name: "{{ nxos_int1 }}" + address_family: + - afi: ipv4 + multi_areas: + - 11.11.11.11 + processes: + - area: + area_id: 1.1.1.1 + secondaries: false + process_id: "100" + - afi: ipv6 + multi_areas: + - 16.10.10.10 + - 21.0.0.0 + - 50.50.50.50 + processes: + - area: + area_id: 2.2.2.2 + process_id: "200" + - name: "{{ nxos_int2 }}" + address_family: + - afi: ipv4 + authentication: + enable: true + key_chain: test-1 + cost: 100 + - afi: ipv6 + network: broadcast + shutdown: true + - name: "{{ nxos_int3 }}" + address_family: + - afi: ipv4 + cost: 101 + +replaced: + commands: + - "interface {{ nxos_int1 }}" + - "no ip router ospf multi-area 11.11.11.11" + - "ip router ospf multi-area 11.11.11.12" + - "no ipv6 router ospfv3 200 area 2.2.2.2" + - "no ipv6 router ospfv3 multi-area 16.10.10.10" + - "no ipv6 router ospfv3 multi-area 21.0.0.0" + - "no ipv6 router ospfv3 multi-area 50.50.50.50" + - "interface {{ nxos_int3 }}" + - "no ip ospf cost 101" + after: + - name: "{{ nxos_int1 }}" + address_family: + - afi: ipv4 + processes: + - process_id: "100" + area: + area_id: 1.1.1.1 + secondaries: false + multi_areas: + - 11.11.11.12 + - name: "{{ nxos_int2 }}" + address_family: + - afi: ipv4 + authentication: + enable: true + key_chain: test-1 + cost: 100 + - afi: ipv6 + network: broadcast + shutdown: true + - name: "{{ nxos_int3 }}" +overridden: + commands: + - "interface {{ nxos_int1 }}" + - "no ip router ospf multi-area 11.11.11.11" + - "ip router ospf multi-area 11.11.11.12" + - "no ipv6 router ospfv3 200 area 2.2.2.2" + - "no ipv6 router ospfv3 multi-area 16.10.10.10" + - "no ipv6 router ospfv3 multi-area 21.0.0.0" + - "no ipv6 router ospfv3 multi-area 50.50.50.50" + - "interface {{ nxos_int2 }}" + - "no ip ospf authentication" + - "no ip ospf authentication key-chain test-1" + - "no ip ospf cost 100" + - "no ospfv3 network broadcast" + - "no ospfv3 shutdown" + - "interface {{ nxos_int3 }}" + - "no ip ospf cost 101" + after: + - name: "{{ nxos_int1 }}" + address_family: + - afi: ipv4 + processes: + - process_id: "100" + area: + area_id: 1.1.1.1 + secondaries: false + multi_areas: + - 11.11.11.12 + - name: "{{ nxos_int2 }}" + - name: "{{ nxos_int3 }}" +deleted: + commands: + - "interface {{ nxos_int1 }}" + - "no ip router ospf 100 area 1.1.1.1 secondaries none" + - "no ip router ospf multi-area 11.11.11.11" + - "no ipv6 router ospfv3 200 area 2.2.2.2" + - "no ipv6 router ospfv3 multi-area 16.10.10.10" + - "no ipv6 router ospfv3 multi-area 21.0.0.0" + - "no ipv6 router ospfv3 multi-area 50.50.50.50" + - "interface {{ nxos_int2 }}" + - "no ip ospf authentication" + - "no ip ospf authentication key-chain test-1" + - "no ip ospf cost 100" + - "no ospfv3 network broadcast" + - "no ospfv3 shutdown" + - "interface {{ nxos_int3 }}" + - "no ip ospf cost 101" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/defaults/main.yaml new file mode 100644 index 00000000..871ea460 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "[^_].*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/meta/main.yml new file mode 100644 index 00000000..ed97d539 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/meta/main.yml @@ -0,0 +1 @@ +--- diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tasks/cli.yaml new file mode 100644 index 00000000..9e4fb34b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tasks/main.yaml new file mode 100644 index 00000000..4e36581e --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tasks/main.yaml @@ -0,0 +1,26 @@ +--- +- name: Enable 'feature ospf' + cisco.nxos.nxos_feature: + feature: ospf + vars: + ansible_connection: ansible.netcommon.network_cli + +- name: Run the CLI and NX-API tests + block: + - name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli.yaml + + - name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi + + always: + - name: Disable 'feature ospf' + cisco.nxos.nxos_feature: + feature: ospf + state: disabled + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tasks/nxapi.yaml new file mode 100644 index 00000000..5cb76e67 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tests/common/_populate_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tests/common/_populate_config.yaml new file mode 100644 index 00000000..8a11d9ff --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tests/common/_populate_config.yaml @@ -0,0 +1,27 @@ +--- +- name: Setup + cisco.nxos.nxos_config: + lines: + - "router ospf 102" + - " router-id 198.51.100.1" + - " redistribute eigrp 120 route-map rmap_1" + - " redistribute direct route-map ospf102-direct-connect" + - " area 0.0.0.100 filter-list route-map rmap_1 in" + - " area 0.0.0.100 filter-list route-map rmap_2 out" + - " area 0.0.0.100 range 192.0.2.0/24 not-advertise" + - " area 0.0.0.100 range 203.0.113.0/24 cost 120" + - " area 0.0.0.101 authentication message-digest" + - " vrf zone1" + - " router-id 198.51.100.129" + - " summary-address 203.0.113.64/26 tag 121" + - " summary-address 192.0.2.128/25" + - " redistribute static route-map zone1-static-connect" + - " area 0.0.0.102 nssa no-summary default-information-originate" + - " area 0.0.0.103 nssa no-summary" + - " area 0.0.0.103 nssa translate type7 always" + - " vrf zone2" + - " auto-cost reference-bandwidth 45 Gbps" + - "router ospf 100" + - " router-id 203.0.113.20" + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tests/common/_remove_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tests/common/_remove_config.yaml new file mode 100644 index 00000000..3a3248e6 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tests/common/_remove_config.yaml @@ -0,0 +1,10 @@ +--- +- name: Remove pre-existing OSPF processes + cisco.nxos.nxos_config: + lines: + - no router ospf 100 + - no router ospf 102 + - no router ospf 104 + ignore_errors: true + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tests/common/deleted.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tests/common/deleted.yaml new file mode 100644 index 00000000..23fab8f3 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tests/common/deleted.yaml @@ -0,0 +1,89 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_ospfv2 deleted integration tests connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Delete a single OSPF process + cisco.nxos.nxos_ospfv2: &id001 + config: + processes: + - process_id: 102 + state: deleted + register: result + + - name: Assert that before dicts are correctly generated + ansible.builtin.assert: + that: + - "{{ merged['after']['processes'] | symmetric_difference(result['before']['processes']) |length == 0 }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - '"no router ospf 102" in result.commands' + - result.commands|length == 1 + + - name: Assert that after dict is correctly generated + ansible.builtin.assert: + that: + - "{{ deleted['after']['processes'] | symmetric_difference(result['after']['processes']) |length == 0 }}" + + - name: Delete a single OSPF process (idempotent) + register: result + cisco.nxos.nxos_ospfv2: *id001 + + - name: Assert that task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + - name: Assert that before dict is correctly generated + ansible.builtin.assert: + that: + - "{{ deleted['after']['processes'] | symmetric_difference(result['before']['processes']) |length == 0 }}" + + - ansible.builtin.include_tasks: _populate_config.yaml + + - name: Delete all OSPF processes from the device + cisco.nxos.nxos_ospfv2: &id002 + state: deleted + register: result + + - name: Assert that before dicts are correctly generated + ansible.builtin.assert: + that: + - "{{ merged['after']['processes'] | symmetric_difference(result['before']['processes']) |length == 0 }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - '"no router ospf 100" in result.commands' + - '"no router ospf 102" in result.commands' + - result.commands|length == 2 + + - name: Assert that after dict is correctly generated + ansible.builtin.assert: + that: + - "{{ result['after'] == {} }}" + + - name: Delete all OSPF processes from the device (idempotent) + register: result + cisco.nxos.nxos_ospfv2: *id002 + + - name: Assert that task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + - name: Assert that before dict is correctly generated + ansible.builtin.assert: + that: + - "{{ result['before'] == {} }}" + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tests/common/fixtures/parsed.cfg b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tests/common/fixtures/parsed.cfg new file mode 100644 index 00000000..30da2d2b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tests/common/fixtures/parsed.cfg @@ -0,0 +1,21 @@ +router ospf 100 + router-id 203.0.113.20 +router ospf 102 + router-id 198.51.100.1 + redistribute direct route-map ospf102-direct-connect + redistribute eigrp 120 route-map rmap_1 + area 0.0.0.100 filter-list route-map rmap_2 out + area 0.0.0.100 filter-list route-map rmap_1 in + area 0.0.0.100 range 192.0.2.0/24 not-advertise + area 0.0.0.100 range 203.0.113.0/24 cost 120 + area 0.0.0.101 authentication message-digest + vrf zone1 + router-id 198.51.100.129 + area 0.0.0.102 nssa no-summary default-information-originate + area 0.0.0.103 nssa no-summary + area 0.0.0.103 nssa translate type7 always + redistribute static route-map zone1-static-connect + summary-address 192.0.2.128/25 + summary-address 203.0.113.64/26 tag 121 + vrf zone2 + auto-cost reference-bandwidth 45 Gbps diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tests/common/gathered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tests/common/gathered.yaml new file mode 100644 index 00000000..4facdd01 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tests/common/gathered.yaml @@ -0,0 +1,20 @@ +--- +- ansible.builtin.debug: + msg: START nxos_ospfv2 gathered integration tests on connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Gather ospfv2 facts using gathered + register: result + cisco.nxos.nxos_ospfv2: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: "{{ merged['after']['processes'] | symmetric_difference(result['gathered']['processes']) |length == 0 }}" + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tests/common/merged.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tests/common/merged.yaml new file mode 100644 index 00000000..523c615d --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tests/common/merged.yaml @@ -0,0 +1,89 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_ospfv2 merged integration tests connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- block: + - name: Merge the provided configuration with the existing running configuration + cisco.nxos.nxos_ospfv2: &id001 + config: + processes: + - process_id: 100 + router_id: 203.0.113.20 + - process_id: 102 + router_id: 198.51.100.1 + areas: + - area_id: 0.0.0.100 + filter_list: + - route_map: rmap_1 + direction: in + - route_map: rmap_2 + direction: out + ranges: + - prefix: 192.0.2.0/24 + not_advertise: true + - prefix: 203.0.113.0/24 + cost: 120 + - area_id: 0.0.0.101 + authentication: + message_digest: true + redistribute: + - protocol: eigrp + id: 120 + route_map: rmap_1 + - protocol: direct + route_map: ospf102-direct-connect + vrfs: + - vrf: zone1 + router_id: 198.51.100.129 + redistribute: + - protocol: static + route_map: zone1-static-connect + summary_address: + - prefix: 203.0.113.64/26 + tag: 121 + - prefix: 192.0.2.128/25 + areas: + - area_id: 0.0.0.102 + nssa: + default_information_originate: true + no_summary: true + - area_id: 0.0.0.103 + nssa: + no_summary: true + translate: + type7: + always: true + - vrf: zone2 + auto_cost: + reference_bandwidth: 45 + unit: Gbps + state: merged + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ result['before'] == {} }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ merged['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ merged['after']['processes'] | symmetric_difference(result['after']['processes']) |length == 0 }}" + + - name: Merge the provided configuration with the existing running configuration (idempotent) + cisco.nxos.nxos_ospfv2: *id001 + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tests/common/overridden.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tests/common/overridden.yaml new file mode 100644 index 00000000..c98483e7 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tests/common/overridden.yaml @@ -0,0 +1,52 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_ospfv2 overridden integration tests connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Override all OSPF configuration with provided configuration + cisco.nxos.nxos_ospfv2: &id001 + config: + processes: + - process_id: 104 + router_id: 203.0.113.20 + - process_id: 102 + router_id: 198.51.100.1 + shutdown: true + state: overridden + register: result + + - name: Assert that before dicts are correctly generated + ansible.builtin.assert: + that: + - "{{ merged['after']['processes'] | symmetric_difference(result['before']['processes']) |length == 0 }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ overridden['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dict is correctly generated + ansible.builtin.assert: + that: + - "{{ overridden['after']['processes'] | symmetric_difference(result['after']['processes']) |length == 0 }}" + + - name: Override all OSPF configuration with provided configuration (idempotent) + register: result + cisco.nxos.nxos_ospfv2: *id001 + + - name: Assert that task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + - name: Assert that before dict is correctly generated + ansible.builtin.assert: + that: + - "{{ overridden['after']['processes'] | symmetric_difference(result['before']['processes']) |length == 0 }}" + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tests/common/parsed.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tests/common/parsed.yaml new file mode 100644 index 00000000..8606c5d7 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tests/common/parsed.yaml @@ -0,0 +1,14 @@ +--- +- ansible.builtin.debug: + msg: START nxos_ospfv2 parsed integration tests on connection={{ ansible_connection }} + +- name: Parse externally provided ospfv2 configuration + register: result + cisco.nxos.nxos_ospfv2: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed + +- name: Assert that configuration was correctly parsed + ansible.builtin.assert: + that: + - "{{ merged['after']['processes'] | symmetric_difference(result['parsed']['processes']) |length == 0 }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tests/common/rendered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tests/common/rendered.yaml new file mode 100644 index 00000000..300b5907 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tests/common/rendered.yaml @@ -0,0 +1,65 @@ +--- +- ansible.builtin.debug: + msg: START nxos_ospfv2 rendered integration tests on connection={{ ansible_connection }} + +- name: Render platform specific configuration lines with state rendered (without connecting to the device) + cisco.nxos.nxos_ospfv2: + config: + processes: + - process_id: 100 + router_id: 203.0.113.20 + - process_id: 102 + router_id: 198.51.100.1 + areas: + - area_id: 0.0.0.100 + filter_list: + - route_map: rmap_1 + direction: in + - route_map: rmap_2 + direction: out + ranges: + - prefix: 192.0.2.0/24 + not_advertise: true + - prefix: 203.0.113.0/24 + cost: 120 + - area_id: 0.0.0.101 + authentication: + message_digest: true + redistribute: + - protocol: eigrp + id: 120 + route_map: rmap_1 + - protocol: direct + route_map: ospf102-direct-connect + vrfs: + - vrf: zone1 + router_id: 198.51.100.129 + redistribute: + - protocol: static + route_map: zone1-static-connect + summary_address: + - prefix: 203.0.113.64/26 + tag: 121 + - prefix: 192.0.2.128/25 + areas: + - area_id: 0.0.0.102 + nssa: + default_information_originate: true + no_summary: true + - area_id: 0.0.0.103 + nssa: + no_summary: true + translate: + type7: + always: true + - vrf: zone2 + auto_cost: + reference_bandwidth: 45 + unit: Gbps + state: rendered + register: result + +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - "{{ merged['commands'] | symmetric_difference(result['rendered']) |length == 0 }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tests/common/replaced.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tests/common/replaced.yaml new file mode 100644 index 00000000..f59f487c --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/tests/common/replaced.yaml @@ -0,0 +1,78 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_ospfv2 replaced integration tests connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Replace device configurations of listed OSPF processes with provided configurations + cisco.nxos.nxos_ospfv2: &id001 + config: + processes: + - process_id: 102 + router_id: 198.51.100.1 + areas: + - area_id: 0.0.0.100 + filter_list: + - route_map: rmap_8 + direction: in + ranges: + - not_advertise: true + prefix: 192.0.2.0/24 + - area_id: 0.0.0.101 + stub: + no_summary: true + redistribute: + - protocol: eigrp + id: 130 + route_map: rmap_1 + - protocol: direct + route_map: ospf102-direct-connect + vrfs: + - vrf: zone1 + router_id: 198.51.100.129 + redistribute: + - protocol: bgp + id: 65563 + route_map: zone1-bgp-connect + areas: + - area_id: 0.0.0.102 + nssa: + default_information_originate: true + no_summary: true + state: replaced + register: result + + - name: Assert that before dicts are correctly generated + ansible.builtin.assert: + that: + - "{{ merged['after']['processes'] | symmetric_difference(result['before']['processes']) |length == 0 }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dict is correctly generated + ansible.builtin.assert: + that: + - "{{ replaced['after']['processes'] | symmetric_difference(result['after']['processes']) |length == 0 }}" + + - name: Replace device configurations of listed OSPF processes with provided configurarions (idempotent) + register: result + cisco.nxos.nxos_ospfv2: *id001 + + - name: Assert that task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + - name: Assert that before dict is correctly generated + ansible.builtin.assert: + that: + - "{{ replaced['after']['processes'] | symmetric_difference(result['before']['processes']) |length == 0 }}" + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/vars/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/vars/main.yml new file mode 100644 index 00000000..25419c85 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv2/vars/main.yml @@ -0,0 +1,158 @@ +--- +merged: + commands: + - router ospf 102 + - router-id 198.51.100.1 + - redistribute eigrp 120 route-map rmap_1 + - redistribute direct route-map ospf102-direct-connect + - area 0.0.0.100 filter-list route-map rmap_1 in + - area 0.0.0.100 filter-list route-map rmap_2 out + - area 0.0.0.100 range 192.0.2.0/24 not-advertise + - area 0.0.0.100 range 203.0.113.0/24 cost 120 + - area 0.0.0.101 authentication message-digest + - vrf zone1 + - router-id 198.51.100.129 + - summary-address 203.0.113.64/26 tag 121 + - summary-address 192.0.2.128/25 + - redistribute static route-map zone1-static-connect + - area 0.0.0.102 nssa no-summary default-information-originate + - area 0.0.0.103 nssa no-summary + - area 0.0.0.103 nssa translate type7 always + - vrf zone2 + - auto-cost reference-bandwidth 45 Gbps + - router ospf 100 + - router-id 203.0.113.20 + after: + processes: + - process_id: "100" + router_id: 203.0.113.20 + - areas: + - area_id: 0.0.0.100 + filter_list: + - direction: out + route_map: rmap_2 + - direction: in + route_map: rmap_1 + ranges: + - not_advertise: true + prefix: 192.0.2.0/24 + - cost: 120 + prefix: 203.0.113.0/24 + - area_id: 0.0.0.101 + authentication: + message_digest: true + process_id: "102" + redistribute: + - protocol: direct + route_map: ospf102-direct-connect + - id: "120" + protocol: eigrp + route_map: rmap_1 + router_id: 198.51.100.1 + vrfs: + - areas: + - area_id: 0.0.0.102 + nssa: + default_information_originate: true + no_summary: true + - area_id: 0.0.0.103 + nssa: + no_summary: true + translate: + type7: + always: true + redistribute: + - protocol: static + route_map: zone1-static-connect + router_id: 198.51.100.129 + summary_address: + - prefix: 192.0.2.128/25 + - prefix: 203.0.113.64/26 + tag: 121 + vrf: zone1 + - auto_cost: + reference_bandwidth: 45 + unit: Gbps + vrf: zone2 + +replaced: + commands: + - router ospf 102 + - redistribute eigrp 130 route-map rmap_1 + - no redistribute eigrp 120 route-map rmap_1 + - area 0.0.0.100 filter-list route-map rmap_8 in + - no area 0.0.0.100 filter-list route-map rmap_2 out + - no area 0.0.0.100 range 203.0.113.0/24 + - no area 0.0.0.101 authentication + - area 0.0.0.101 stub no-summary + - vrf zone1 + - no summary-address 203.0.113.64/26 tag 121 + - no summary-address 192.0.2.128/25 + - redistribute bgp 65563 route-map zone1-bgp-connect + - no redistribute static route-map zone1-static-connect + - no area 0.0.0.103 nssa + - no area 0.0.0.103 nssa translate type7 always + - no vrf zone2 + after: + processes: + - process_id: "100" + router_id: 203.0.113.20 + - areas: + - area_id: 0.0.0.101 + stub: + no_summary: true + - area_id: 0.0.0.100 + filter_list: + - direction: in + route_map: rmap_8 + ranges: + - not_advertise: true + prefix: 192.0.2.0/24 + process_id: "102" + redistribute: + - protocol: direct + route_map: ospf102-direct-connect + - id: "130" + protocol: eigrp + route_map: rmap_1 + router_id: 198.51.100.1 + vrfs: + - areas: + - area_id: 0.0.0.102 + nssa: + default_information_originate: true + no_summary: true + redistribute: + - id: "65563" + protocol: bgp + route_map: zone1-bgp-connect + router_id: 198.51.100.129 + vrf: zone1 +overridden: + commands: + - no router ospf 100 + - router ospf 104 + - router-id 203.0.113.20 + - router ospf 102 + - shutdown + - no redistribute direct route-map ospf102-direct-connect + - no redistribute eigrp 120 route-map rmap_1 + - no area 0.0.0.100 filter-list route-map rmap_2 out + - no area 0.0.0.100 filter-list route-map rmap_1 in + - no area 0.0.0.100 range 192.0.2.0/24 + - no area 0.0.0.100 range 203.0.113.0/24 + - no area 0.0.0.101 authentication + - no vrf zone1 + - no vrf zone2 + after: + processes: + - process_id: "104" + router_id: 203.0.113.20 + - process_id: "102" + router_id: 198.51.100.1 + shutdown: true +deleted: + after: + processes: + - process_id: "100" + router_id: 203.0.113.20 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/defaults/main.yaml new file mode 100644 index 00000000..871ea460 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "[^_].*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/meta/main.yml new file mode 100644 index 00000000..ed97d539 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/meta/main.yml @@ -0,0 +1 @@ +--- diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tasks/cli.yaml new file mode 100644 index 00000000..9e4fb34b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tasks/main.yaml new file mode 100644 index 00000000..8be45e21 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tasks/main.yaml @@ -0,0 +1,26 @@ +--- +- name: Enable 'feature ospfv3' + cisco.nxos.nxos_feature: + feature: ospfv3 + vars: + ansible_connection: ansible.netcommon.network_cli + +- name: Run the CLI and NX-API tests + block: + - name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli.yaml + + - name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi + + always: + - name: Disable 'feature ospfv3' + cisco.nxos.nxos_feature: + feature: ospfv3 + state: disabled + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tasks/nxapi.yaml new file mode 100644 index 00000000..5cb76e67 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tests/common/_populate_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tests/common/_populate_config.yaml new file mode 100644 index 00000000..e9ead8bc --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tests/common/_populate_config.yaml @@ -0,0 +1,24 @@ +--- +- name: Setup + cisco.nxos.nxos_config: + lines: + - "router ospfv3 102" + - " router-id 198.51.100.1" + - " address-family ipv6 unicast" + - " redistribute eigrp 120 route-map rmap_1" + - " redistribute direct route-map ospf102-direct-connect" + - " area 0.0.0.100 filter-list route-map rmap_1 in" + - " area 0.0.0.100 filter-list route-map rmap_2 out" + - " area 0.0.0.100 range 2001:db2::/32 not-advertise" + - " area 0.0.0.100 range 2001:db3::/32 cost 120" + - " vrf zone1" + - " router-id 198.51.100.129" + - " area 0.0.0.102 nssa no-summary default-information-originate" + - " area 0.0.0.103 nssa no-summary" + - " area 0.0.0.103 nssa translate type7 always" + - " vrf zone2" + - " auto-cost reference-bandwidth 45 Gbps" + - "router ospfv3 100" + - " router-id 203.0.113.20" + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tests/common/_remove_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tests/common/_remove_config.yaml new file mode 100644 index 00000000..5ea2b6dc --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tests/common/_remove_config.yaml @@ -0,0 +1,10 @@ +--- +- name: Remove pre-existing OSPF processes + cisco.nxos.nxos_config: + lines: + - no router ospfv3 100 + - no router ospfv3 102 + - no router ospfv3 104 + ignore_errors: true + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tests/common/deleted.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tests/common/deleted.yaml new file mode 100644 index 00000000..bf860b01 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tests/common/deleted.yaml @@ -0,0 +1,89 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_ospfv3 deleted integration tests connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Delete a single OSPF process + cisco.nxos.nxos_ospfv3: &id001 + config: + processes: + - process_id: 102 + state: deleted + register: result + + - name: Assert that before dicts are correctly generated + ansible.builtin.assert: + that: + - "{{ merged['after']['processes'] | symmetric_difference(result['before']['processes']) |length == 0 }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - '"no router ospfv3 102" in result.commands' + - result.commands|length == 1 + + - name: Assert that after dict is correctly generated + ansible.builtin.assert: + that: + - "{{ deleted['after']['processes'] | symmetric_difference(result['after']['processes']) |length == 0 }}" + + - name: Delete a single OSPF process (idempotent) + register: result + cisco.nxos.nxos_ospfv3: *id001 + + - name: Assert that task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + - name: Assert that before dict is correctly generated + ansible.builtin.assert: + that: + - "{{ deleted['after']['processes'] | symmetric_difference(result['before']['processes']) |length == 0 }}" + + - ansible.builtin.include_tasks: _populate_config.yaml + + - name: Delete all ospfv3 processes from the device + cisco.nxos.nxos_ospfv3: &id002 + state: deleted + register: result + + - name: Assert that before dicts are correctly generated + ansible.builtin.assert: + that: + - "{{ merged['after']['processes'] | symmetric_difference(result['before']['processes']) |length == 0 }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - '"no router ospfv3 100" in result.commands' + - '"no router ospfv3 102" in result.commands' + - result.commands|length == 2 + + - name: Assert that after dict is correctly generated + ansible.builtin.assert: + that: + - "{{ result['after'] == {} }}" + + - name: Delete all OSPF processes from the device (idempotent) + register: result + cisco.nxos.nxos_ospfv3: *id002 + + - name: Assert that task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + - name: Assert that before dict is correctly generated + ansible.builtin.assert: + that: + - "{{ result['before'] == {} }}" + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tests/common/empty_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tests/common/empty_config.yaml new file mode 100644 index 00000000..34996cf3 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tests/common/empty_config.yaml @@ -0,0 +1,61 @@ +--- +- ansible.builtin.debug: + msg: START nxos_ospfv3 empty_config integration tests on connection={{ ansible_connection }} + +- name: Merged with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_ospfv3: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_ospfv3: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Overridden with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_ospfv3: + config: + state: overridden + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Rendered with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_ospfv3: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' + +- name: Parsed with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_ospfv3: + running_config: + state: parsed + +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state parsed' + +- ansible.builtin.debug: + msg: END nxos_ospfv3 empty_config integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tests/common/fixtures/parsed.cfg b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tests/common/fixtures/parsed.cfg new file mode 100644 index 00000000..45520977 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tests/common/fixtures/parsed.cfg @@ -0,0 +1,18 @@ +router ospfv3 100 + router-id 203.0.113.20 +router ospfv3 102 + router-id 198.51.100.1 + address-family ipv6 unicast + redistribute direct route-map ospf102-direct-connect + redistribute eigrp 120 route-map rmap_1 + area 0.0.0.100 filter-list route-map rmap_2 out + area 0.0.0.100 filter-list route-map rmap_1 in + area 0.0.0.100 range 2001:db2::/32 not-advertise + area 0.0.0.100 range 2001:db3::/32 cost 120 + vrf zone1 + router-id 198.51.100.129 + area 0.0.0.102 nssa no-summary default-information-originate + area 0.0.0.103 nssa no-summary + area 0.0.0.103 nssa translate type7 always + vrf zone2 + auto-cost reference-bandwidth 45 Gbps diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tests/common/gathered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tests/common/gathered.yaml new file mode 100644 index 00000000..09a406e3 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tests/common/gathered.yaml @@ -0,0 +1,20 @@ +--- +- ansible.builtin.debug: + msg: START nxos_ospfv3 gathered integration tests on connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Gather ospfv3 facts using gathered + register: result + cisco.nxos.nxos_ospfv3: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: "{{ merged['after']['processes'] | symmetric_difference(result['gathered']['processes']) |length == 0 }}" + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tests/common/merged.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tests/common/merged.yaml new file mode 100644 index 00000000..b63cc923 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tests/common/merged.yaml @@ -0,0 +1,82 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_ospfv3 merged integration tests connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- block: + - name: Merge the provided configuration with the existing running configuration + cisco.nxos.nxos_ospfv3: &id001 + config: + processes: + - process_id: 100 + router_id: 203.0.113.20 + - process_id: 102 + router_id: 198.51.100.1 + address_family: + afi: ipv6 + safi: unicast + areas: + - area_id: 0.0.0.100 + filter_list: + - route_map: rmap_1 + direction: in + - route_map: rmap_2 + direction: out + ranges: + - prefix: 2001:db2::/32 + not_advertise: true + - prefix: 2001:db3::/32 + cost: 120 + redistribute: + - protocol: eigrp + id: 120 + route_map: rmap_1 + - protocol: direct + route_map: ospf102-direct-connect + vrfs: + - vrf: zone1 + router_id: 198.51.100.129 + areas: + - area_id: 0.0.0.102 + nssa: + default_information_originate: true + no_summary: true + - area_id: 0.0.0.103 + nssa: + no_summary: true + translate: + type7: + always: true + - vrf: zone2 + auto_cost: + reference_bandwidth: 45 + unit: Gbps + state: merged + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ result['before'] == {} }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ merged['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ merged['after']['processes'] | symmetric_difference(result['after']['processes']) |length == 0 }}" + + - name: Merge the provided configuration with the existing running configuration (idempotent) + cisco.nxos.nxos_ospfv3: *id001 + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tests/common/overridden.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tests/common/overridden.yaml new file mode 100644 index 00000000..7d9bc6c9 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tests/common/overridden.yaml @@ -0,0 +1,52 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_ospfv3 overridden integration tests connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Override all ospfv3 configuration with provided configuration + cisco.nxos.nxos_ospfv3: &id001 + config: + processes: + - process_id: 104 + router_id: 203.0.113.20 + - process_id: 102 + router_id: 198.51.100.1 + shutdown: true + state: overridden + register: result + + - name: Assert that before dicts are correctly generated + ansible.builtin.assert: + that: + - "{{ merged['after']['processes'] | symmetric_difference(result['before']['processes']) |length == 0 }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ overridden['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dict is correctly generated + ansible.builtin.assert: + that: + - "{{ overridden['after']['processes'] | symmetric_difference(result['after']['processes']) |length == 0 }}" + + - name: Override all OSPF configuration with provided configuration (idempotent) + register: result + cisco.nxos.nxos_ospfv3: *id001 + + - name: Assert that task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + - name: Assert that before dict is correctly generated + ansible.builtin.assert: + that: + - "{{ overridden['after']['processes'] | symmetric_difference(result['before']['processes']) |length == 0 }}" + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tests/common/parsed.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tests/common/parsed.yaml new file mode 100644 index 00000000..3f4c2d2a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tests/common/parsed.yaml @@ -0,0 +1,14 @@ +--- +- ansible.builtin.debug: + msg: START nxos_ospfv3 parsed integration tests on connection={{ ansible_connection }} + +- name: Parse externally provided ospfv3 configuration + register: result + cisco.nxos.nxos_ospfv3: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed + +- name: Assert that configuration was correctly parsed + ansible.builtin.assert: + that: + - "{{ merged['after']['processes'] | symmetric_difference(result['parsed']['processes']) |length == 0 }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tests/common/rendered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tests/common/rendered.yaml new file mode 100644 index 00000000..f59cbb00 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tests/common/rendered.yaml @@ -0,0 +1,59 @@ +--- +- ansible.builtin.debug: + msg: START nxos_ospfv3 rendered integration tests on connection={{ ansible_connection }} + +- name: Render platform specific configuration lines with state rendered (without connecting to the device) + cisco.nxos.nxos_ospfv3: + config: + processes: + - process_id: 100 + router_id: 203.0.113.20 + - process_id: 102 + router_id: 198.51.100.1 + address_family: + afi: ipv6 + safi: unicast + areas: + - area_id: 0.0.0.100 + filter_list: + - route_map: rmap_1 + direction: in + - route_map: rmap_2 + direction: out + ranges: + - prefix: 2001:db2::/32 + not_advertise: true + - prefix: 2001:db3::/32 + cost: 120 + redistribute: + - protocol: eigrp + id: 120 + route_map: rmap_1 + - protocol: direct + route_map: ospf102-direct-connect + vrfs: + - vrf: zone1 + router_id: 198.51.100.129 + areas: + - area_id: 0.0.0.102 + nssa: + default_information_originate: true + no_summary: true + - area_id: 0.0.0.103 + nssa: + no_summary: true + translate: + type7: + always: true + - vrf: zone2 + auto_cost: + reference_bandwidth: 45 + unit: Gbps + state: rendered + register: result + +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - "{{ merged['commands'] | symmetric_difference(result['rendered']) |length == 0 }}" + - result.changed == False diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tests/common/replaced.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tests/common/replaced.yaml new file mode 100644 index 00000000..f819c559 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/tests/common/replaced.yaml @@ -0,0 +1,74 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_ospfv3 replaced integration tests connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Replace device configurations of listed ospfv3 processes with provided configurations + cisco.nxos.nxos_ospfv3: &id001 + config: + processes: + - process_id: 102 + router_id: 198.51.100.1 + address_family: + afi: ipv6 + safi: unicast + areas: + - area_id: 0.0.0.100 + filter_list: + - route_map: rmap_8 + direction: in + ranges: + - not_advertise: true + prefix: 2001:db2::/32 + redistribute: + - protocol: eigrp + id: 130 + route_map: rmap_1 + - protocol: direct + route_map: ospf102-direct-connect + vrfs: + - vrf: zone1 + router_id: 198.51.100.129 + areas: + - area_id: 0.0.0.102 + nssa: + default_information_originate: true + no_summary: true + state: replaced + register: result + + - name: Assert that before dicts are correctly generated + ansible.builtin.assert: + that: + - "{{ merged['after']['processes'] | symmetric_difference(result['before']['processes']) |length == 0 }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dict is correctly generated + ansible.builtin.assert: + that: + - "{{ replaced['after']['processes'] | symmetric_difference(result['after']['processes']) |length == 0 }}" + + - name: Replace device configurations of listed OSPF processes with provided configurarions (idempotent) + register: result + cisco.nxos.nxos_ospfv3: *id001 + + - name: Assert that task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + - name: Assert that before dict is correctly generated + ansible.builtin.assert: + that: + - "{{ replaced['after']['processes'] | symmetric_difference(result['before']['processes']) |length == 0 }}" + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/vars/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/vars/main.yml new file mode 100644 index 00000000..ddfd096b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_ospfv3/vars/main.yml @@ -0,0 +1,142 @@ +--- +merged: + commands: + - router ospfv3 102 + - router-id 198.51.100.1 + - address-family ipv6 unicast + - redistribute eigrp 120 route-map rmap_1 + - redistribute direct route-map ospf102-direct-connect + - area 0.0.0.100 filter-list route-map rmap_1 in + - area 0.0.0.100 filter-list route-map rmap_2 out + - area 0.0.0.100 range 2001:db2::/32 not-advertise + - area 0.0.0.100 range 2001:db3::/32 cost 120 + - vrf zone1 + - router-id 198.51.100.129 + - area 0.0.0.102 nssa no-summary default-information-originate + - area 0.0.0.103 nssa no-summary + - area 0.0.0.103 nssa translate type7 always + - vrf zone2 + - auto-cost reference-bandwidth 45 Gbps + - router ospfv3 100 + - router-id 203.0.113.20 + after: + processes: + - process_id: "100" + router_id: 203.0.113.20 + - address_family: + afi: ipv6 + safi: unicast + redistribute: + - protocol: direct + route_map: ospf102-direct-connect + - id: "120" + protocol: eigrp + route_map: rmap_1 + areas: + - area_id: 0.0.0.100 + filter_list: + - direction: out + route_map: rmap_2 + - direction: in + route_map: rmap_1 + ranges: + - not_advertise: true + prefix: 2001:db2::/32 + - cost: 120 + prefix: 2001:db3::/32 + process_id: "102" + router_id: 198.51.100.1 + vrfs: + - areas: + - area_id: 0.0.0.102 + nssa: + default_information_originate: true + no_summary: true + - area_id: 0.0.0.103 + nssa: + no_summary: true + translate: + type7: + always: true + router_id: 198.51.100.129 + vrf: zone1 + - auto_cost: + reference_bandwidth: 45 + unit: Gbps + vrf: zone2 + +replaced: + commands: + - router ospfv3 102 + - address-family ipv6 unicast + - redistribute eigrp 130 route-map rmap_1 + - no redistribute eigrp 120 route-map rmap_1 + - area 0.0.0.100 filter-list route-map rmap_8 in + - no area 0.0.0.100 filter-list route-map rmap_2 out + - no area 0.0.0.100 range 2001:db3::/32 + - vrf zone1 + - no area 0.0.0.103 nssa + - no area 0.0.0.103 nssa translate type7 always + - no vrf zone2 + after: + processes: + - process_id: "100" + router_id: 203.0.113.20 + - address_family: + afi: ipv6 + areas: + - area_id: 0.0.0.100 + filter_list: + - direction: in + route_map: rmap_8 + ranges: + - not_advertise: true + prefix: 2001:db2::/32 + redistribute: + - protocol: direct + route_map: ospf102-direct-connect + - id: "130" + protocol: eigrp + route_map: rmap_1 + safi: unicast + process_id: "102" + router_id: 198.51.100.1 + vrfs: + - areas: + - area_id: 0.0.0.102 + nssa: + default_information_originate: true + no_summary: true + router_id: 198.51.100.129 + vrf: zone1 +overridden: + commands: + - no router ospfv3 100 + - router ospfv3 104 + - router-id 203.0.113.20 + - router ospfv3 102 + - shutdown + - address-family ipv6 unicast + - no redistribute direct route-map ospf102-direct-connect + - no redistribute eigrp 120 route-map rmap_1 + - no area 0.0.0.100 filter-list route-map rmap_2 out + - no area 0.0.0.100 filter-list route-map rmap_1 in + - no area 0.0.0.100 range 2001:db2::/32 + - no area 0.0.0.100 range 2001:db3::/32 + - no vrf zone1 + - no vrf zone2 + after: + processes: + - process_id: "104" + router_id: 203.0.113.20 + - process_id: "102" + router_id: 198.51.100.1 + shutdown: true + address_family: + afi: ipv6 + safi: unicast +deleted: + after: + processes: + - process_id: "100" + router_id: 203.0.113.20 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_overlay_global/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_overlay_global/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_overlay_global/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_overlay_global/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_overlay_global/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_overlay_global/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_overlay_global/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_overlay_global/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_overlay_global/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_overlay_global/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_overlay_global/tasks/main.yaml new file mode 100644 index 00000000..c9e70304 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_overlay_global/tasks/main.yaml @@ -0,0 +1,12 @@ +--- +- name: Run the CLI and NX-API tests + block: + - name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + always: + - name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_overlay_global/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_overlay_global/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_overlay_global/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_overlay_global/tasks/platform/n7k/cleanup.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_overlay_global/tasks/platform/n7k/cleanup.yaml new file mode 100644 index 00000000..6de2a7ac --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_overlay_global/tasks/platform/n7k/cleanup.yaml @@ -0,0 +1,22 @@ +--- +- name: Unconfigure VDC setting limit-resource module-type f3 + ignore_errors: true # noqa ignore-errors + cisco.nxos.nxos_config: + commands: + - terminal dont-ask ; vdc {{ vdcid }} ; no limit-resource module-type f3 + match: none + +- name: Previous command is asynchronous and can take a while. allow time for it to complete + ansible.builtin.pause: + seconds: 45 + +- name: Configure VDC setting allocate interface unallocated-interfaces + ignore_errors: true # noqa ignore-errors + cisco.nxos.nxos_config: + commands: + - terminal dont-ask ; vdc {{ vdcid }} ; allocate interface unallocated-interfaces + match: none + +- name: Previous command is asynchronous can take a while. allow time for it to complete + ansible.builtin.pause: + seconds: 45 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_overlay_global/tasks/platform/n7k/setup.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_overlay_global/tasks/platform/n7k/setup.yaml new file mode 100644 index 00000000..856dae1f --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_overlay_global/tasks/platform/n7k/setup.yaml @@ -0,0 +1,39 @@ +--- +- name: Get default VDC id + register: vdcout + cisco.nxos.nxos_command: + commands: + - show vdc current-vdc | json + +- name: Set a fact for 'vdcid' + ansible.builtin.set_fact: + vdcid: "{{ vdcout.stdout_lines[0].name }}" + +- name: Configure VDC setting limit-resource module-type f3 + ignore_errors: true # noqa ignore-errors + cisco.nxos.nxos_config: + commands: + - terminal dont-ask ; vdc {{ vdcid }} ; limit-resource module-type f3 + match: none + +- name: Previous command is asynchronous and can take a while. allow time for it to complete + ansible.builtin.pause: + seconds: 45 + +- name: Configure VDC setting allocate interface unallocated-interfaces + ignore_errors: true # noqa ignore-errors + cisco.nxos.nxos_config: + commands: + - terminal dont-ask ; vdc {{ vdcid }} ; allocate interface unallocated-interfaces + match: none + +- name: Previous command is asynchronous and can take a while. allow time for it to complete + ansible.builtin.pause: + seconds: 45 + +- name: Configure additional N7K requiste features + cisco.nxos.nxos_config: + commands: + - feature-set fabric + - feature fabric forwarding + match: none diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_overlay_global/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_overlay_global/tests/common/sanity.yaml new file mode 100644 index 00000000..6ad8399a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_overlay_global/tests/common/sanity.yaml @@ -0,0 +1,97 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_overlay_global sanity test + +- name: Set a fact for 'overlay_global_supported' + ansible.builtin.set_fact: + overlay_global_supported: false + +- name: Set a fact for 'overlay_global_supported' + ansible.builtin.set_fact: + overlay_global_supported: true + when: platform is search("N35NG|N7K|^N9K$") or ( platform is match("N9k-F") and imagetag is version('F3', 'ne')) + +- ansible.builtin.debug: + msg: Platform {{ platform }} running Image version {{ image_version }} supports nxos_overlay_global + when: overlay_global_supported + +- block: + - name: Enable NV overlay EVPN + cisco.nxos.nxos_evpn_global: + nv_overlay_evpn: true + + - name: Apply N7K specific setup configuration + ansible.builtin.include_tasks: tasks/platform/n7k/setup.yaml + when: platform is match('N7K') + + - name: Configure additional N7K requiste features + when: platform is match('N7K') + cisco.nxos.nxos_config: + commands: + - feature-set fabric + - feature fabric forwarding + match: none + + - name: Remove possibly existing mac + ignore_errors: true + cisco.nxos.nxos_overlay_global: + anycast_gateway_mac: default + when: overlay_global_supported + +- block: + - name: Configure overlay global + register: result + cisco.nxos.nxos_overlay_global: &id001 + anycast_gateway_mac: b.b.b + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Check idempotence + register: result + cisco.nxos.nxos_overlay_global: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Update anycast gateway mac + register: result + cisco.nxos.nxos_overlay_global: &id003 + anycast_gateway_mac: a.a.a + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_overlay_global: *id003 + + - ansible.builtin.assert: *id004 + + - name: Remove anycast gateway mac + register: result + cisco.nxos.nxos_overlay_global: &id005 + anycast_gateway_mac: default + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_overlay_global: *id005 + + - ansible.builtin.assert: *id004 + when: overlay_global_supported + always: + - name: Apply N7K specific cleanup configuration + ansible.builtin.include_tasks: tasks/platform/n7k/cleanup.yaml + when: platform is match('N7K') + + - name: Disable NV overlay EVPN + ignore_errors: true + when: overlay_global_supported + cisco.nxos.nxos_evpn_global: + nv_overlay_evpn: false + + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_overlay_global sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim/tasks/main.yaml new file mode 100644 index 00000000..c9e70304 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim/tasks/main.yaml @@ -0,0 +1,12 @@ +--- +- name: Run the CLI and NX-API tests + block: + - name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + always: + - name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim/tests/common/sanity.yaml new file mode 100644 index 00000000..5b752564 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim/tests/common/sanity.yaml @@ -0,0 +1,83 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_pim sanity test + +- name: "Setup: disable features" + ignore_errors: true + loop: + - pim + - bfd + cisco.nxos.nxos_feature: + feature: "{{ item }}" + state: disabled + +- name: "Setup: enable features" + loop: + - pim + - bfd + cisco.nxos.nxos_feature: + feature: "{{ item }}" + state: enabled + +- name: "Setup: configure ssm_range none" + cisco.nxos.nxos_pim: &id005 + ssm_range: none + +- block: + - name: Initial configuration from none + register: result + cisco.nxos.nxos_pim: &id001 + bfd: enable + ssm_range: + - 239.128.1.0/24 + - 224.0.0.0/8 + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Initial configuration idempotence + register: result + cisco.nxos.nxos_pim: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Configure ssm_range default + register: result + cisco.nxos.nxos_pim: &id003 + bfd: disable + ssm_range: default + + - ansible.builtin.assert: *id002 + + - name: Ssm_range default idempotence + register: result + cisco.nxos.nxos_pim: *id003 + + - ansible.builtin.assert: *id004 + + - name: Configure ssm_range none + register: result + cisco.nxos.nxos_pim: *id005 + + - ansible.builtin.assert: *id002 + + - name: Ssm_range none idempotence + register: result + cisco.nxos.nxos_pim: *id005 + + - ansible.builtin.assert: *id004 + always: + - name: "Teardown: disable features" + ignore_errors: true + loop: + - pim + - bfd + cisco.nxos.nxos_feature: + feature: "{{ item }}" + state: disabled + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_pim sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_interface/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_interface/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_interface/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_interface/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_interface/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_interface/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_interface/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_interface/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_interface/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_interface/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_interface/tasks/main.yaml new file mode 100644 index 00000000..c9e70304 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_interface/tasks/main.yaml @@ -0,0 +1,12 @@ +--- +- name: Run the CLI and NX-API tests + block: + - name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + always: + - name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_interface/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_interface/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_interface/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_interface/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_interface/tests/common/sanity.yaml new file mode 100644 index 00000000..36a4cf45 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_interface/tests/common/sanity.yaml @@ -0,0 +1,198 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_pim_interface sanity test + +- name: "Setup: disable features" + loop: + - pim + - bfd + ignore_errors: true + cisco.nxos.nxos_feature: &id011 + feature: "{{ item }}" + state: disabled + +- name: "Setup: enable features" + loop: + - pim + - bfd + cisco.nxos.nxos_feature: + feature: "{{ item }}" + state: enabled + +- name: Set a fact for 'testint' + ansible.builtin.set_fact: + testint: "{{ nxos_int1 }}" + +- name: "Setup: put interface {{ testint }} into a default state" + ignore_errors: true + cisco.nxos.nxos_config: + lines: + - default interface {{ testint }} + +- name: Ensure {{testint}} is layer3 + cisco.nxos.nxos_interfaces: + config: + - name: "{{ testint }}" + mode: layer3 + description: Configured by Ansible - Layer3 + enabled: true + state: merged + +- block: + - name: Configure nxos_pim_interface state absent + cisco.nxos.nxos_pim_interface: &id010 + interface: "{{ testint }}" + state: absent + + - name: Configure jp policy and type + register: result + cisco.nxos.nxos_pim_interface: &id001 + interface: "{{ testint }}" + jp_policy_in: JPIN + jp_policy_out: JPOUT + jp_type_in: routemap + jp_type_out: routemap + sparse: true + border: true + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Check idempotence + register: result + cisco.nxos.nxos_pim_interface: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Configure neighbor policy and rm + register: result + cisco.nxos.nxos_pim_interface: &id003 + interface: "{{ testint }}" + neighbor_policy: NPR + neighbor_type: routemap + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_pim_interface: *id003 + + - ansible.builtin.assert: *id004 + + - ansible.builtin.pause: + seconds: 5 + + - name: Configure neighbor policy and prefix + register: result + cisco.nxos.nxos_pim_interface: &id005 + interface: "{{ testint }}" + neighbor_policy: NPPF + neighbor_type: prefix + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_pim_interface: *id005 + + - ansible.builtin.assert: *id004 + + - name: Configure hello_auth_key + register: result + cisco.nxos.nxos_pim_interface: + interface: "{{ testint }}" + hello_auth_key: password1 + + - ansible.builtin.assert: *id002 + + - name: Configure PIM other params + register: result + cisco.nxos.nxos_pim_interface: &id006 + interface: "{{ testint }}" + dr_prio: 10 + hello_interval: 40 + sparse: true + border: true + bfd: enable + state: present + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_pim_interface: *id006 + + - ansible.builtin.assert: *id004 + + - name: Configure negative + register: result + cisco.nxos.nxos_pim_interface: &id007 + interface: "{{ testint }}" + sparse: false + border: false + bfd: disable + state: present + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_pim_interface: *id007 + + - ansible.builtin.assert: *id004 + + - ansible.builtin.pause: + seconds: 5 + + - name: Configure state default + register: result + cisco.nxos.nxos_pim_interface: &id008 + interface: "{{ testint }}" + state: default + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_pim_interface: *id008 + + - ansible.builtin.assert: *id004 + + - name: Configure border + register: result + cisco.nxos.nxos_pim_interface: &id009 + interface: "{{ testint }}" + border: true + state: present + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_pim_interface: *id009 + + - ansible.builtin.assert: *id004 + + - name: Configure state absent + register: result + cisco.nxos.nxos_pim_interface: *id010 + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_pim_interface: *id010 + + - ansible.builtin.assert: *id004 + always: + - name: Disable 'feature pim' + loop: + - pim + - bfd + cisco.nxos.nxos_feature: *id011 + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_pim_interface sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_rp_address/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_rp_address/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_rp_address/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_rp_address/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_rp_address/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_rp_address/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_rp_address/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_rp_address/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_rp_address/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_rp_address/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_rp_address/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_rp_address/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_rp_address/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_rp_address/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_rp_address/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_rp_address/tests/common/configure.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_rp_address/tests/common/configure.yaml new file mode 100644 index 00000000..62298058 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_pim_rp_address/tests/common/configure.yaml @@ -0,0 +1,223 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_pim_rp_address sanity + +- block: + - name: Set a fact for 'bidir_true' + ansible.builtin.set_fact: + bidir_true: true + + - name: Set a fact for 'bidir_false' + ansible.builtin.set_fact: + bidir_false: false + when: platform is not search('N3L') + +- block: + - name: Set a fact for 'pim_prefix_list' + ansible.builtin.set_fact: + pim_prefix_list: pim_prefix_list + + - name: Set a fact for 'pim_route_map' + ansible.builtin.set_fact: + pim_route_map: pim_route_map + when: platform is not search('N3L|N7K') + +- block: + - name: Disable 'feature pim' + cisco.nxos.nxos_feature: &id014 + feature: pim + state: disabled + + - name: Enable 'feature pim' + cisco.nxos.nxos_feature: + feature: pim + state: enabled + + - name: 1.0 configure rp_address + group_list + register: result + cisco.nxos.nxos_pim_rp_address: &id001 + rp_address: 10.1.1.1 + group_list: 224.0.0.0/8 + bidir: "{{ bidir_true|default(omit) }}" + state: present + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: 1.0 idempotence rp_address + group_list + register: result + cisco.nxos.nxos_pim_rp_address: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - block: + - name: 1.1 Configure rp_address + group_list (bidir_false) + register: result + cisco.nxos.nxos_pim_rp_address: &id003 + rp_address: 10.1.1.1 + group_list: 224.0.0.0/8 + bidir: false + state: present + + - assert: *id002 + + - name: 1.1 Idempotence rp_address + group_list (bidir_false) + register: result + cisco.nxos.nxos_pim_rp_address: *id003 + + - assert: *id004 + + - name: 1.2 Configure rp_address (bidir_true) + register: result + cisco.nxos.nxos_pim_rp_address: &id005 + rp_address: 10.1.1.1 + bidir: true + state: present + + - assert: *id002 + + - name: 1.2 Idempotence rp_address (bidir_true) + register: result + cisco.nxos.nxos_pim_rp_address: *id005 + + - assert: *id004 + + - name: 1.3 Configure rp_address (bidir_false) + register: result + cisco.nxos.nxos_pim_rp_address: &id006 + rp_address: 10.1.1.1 + bidir: false + state: present + + - assert: *id002 + + - name: 1.3 Idempotence rp_address (bidir_false) + register: result + cisco.nxos.nxos_pim_rp_address: *id006 + + - assert: *id004 + when: bidir_true is defined + + - name: 1.4 remove rp_address + group_list + register: result + cisco.nxos.nxos_pim_rp_address: &id007 + rp_address: 10.1.1.1 + group_list: 224.0.0.0/8 + state: absent + + - ansible.builtin.assert: *id002 + + - name: 1.4 idempotence remove rp_address + group_list + register: result + cisco.nxos.nxos_pim_rp_address: *id007 + + - ansible.builtin.assert: *id004 + + - name: 2.0 configure rp_address + prefix_list (bidir_true) + register: result + cisco.nxos.nxos_pim_rp_address: &id008 + rp_address: 10.1.1.2 + prefix_list: "{{ pim_prefix_list|default(omit) }}" + bidir: "{{ bidir_true|default(omit) }}" + state: present + + - ansible.builtin.assert: *id002 + + - name: 2.0 idempotence rp_address + prefix_list (bidir_true) + register: result + cisco.nxos.nxos_pim_rp_address: *id008 + + - ansible.builtin.assert: *id004 + + - block: + - name: 2.1 Configure rp_address + prefix_list (bidir_false) + register: result + cisco.nxos.nxos_pim_rp_address: &id009 + rp_address: 10.1.1.2 + prefix_list: "{{ pim_prefix_list|default(omit) }}" + bidir: "{{ bidir_false|default(omit) }}" + state: present + + - assert: *id002 + + - name: 2.1 Idempotence rp_address + prefix_list (bidir_false) + register: result + cisco.nxos.nxos_pim_rp_address: *id009 + + - assert: *id004 + when: bidir_false is defined + + - name: 2.2 remove rp_address + prefix_list (bidir_false) + register: result + cisco.nxos.nxos_pim_rp_address: &id010 + rp_address: 10.1.1.2 + prefix_list: "{{ pim_prefix_list|default(omit)}}" + bidir: "{{ bidir_false|default(omit)}}" + state: absent + + - ansible.builtin.assert: *id002 + + - name: 2.2 idempotence remove rp_address + prefix_list (bidir_false) + register: result + cisco.nxos.nxos_pim_rp_address: *id010 + + - ansible.builtin.assert: *id004 + + - name: 3.0 configure rp_address + route_map + (bidir_true) + register: result + cisco.nxos.nxos_pim_rp_address: &id011 + rp_address: 10.1.1.3 + route_map: "{{ pim_route_map|default(omit)}}" + bidir: "{{ bidir_true|default(omit) }}" + state: present + + - ansible.builtin.assert: *id002 + + - name: 3.0 idempotence rp_address + route_map + (bidir_true) + register: result + cisco.nxos.nxos_pim_rp_address: *id011 + + - ansible.builtin.assert: *id004 + + - block: + - name: 3.1 Configure rp_address + route_map (bidir_false) + register: result + cisco.nxos.nxos_pim_rp_address: &id012 + rp_address: 10.1.1.3 + route_map: "{{ pim_route_map|default(omit)}}" + bidir: "{{ bidir_false|default(omit)}}" + state: present + + - assert: *id002 + + - name: 3.1 Idempotence rp_address + route_map + register: result + cisco.nxos.nxos_pim_rp_address: *id012 + + - assert: *id004 + when: bidir_false is defined + + - name: 3.2 remove rp_address + route_map (bidir_false) + register: result + cisco.nxos.nxos_pim_rp_address: &id013 + rp_address: 10.1.1.3 + route_map: "{{ pim_route_map|default(omit)}}" + bidir: "{{ bidir_false|default(omit)}}" + state: absent + + - ansible.builtin.assert: *id002 + + - name: 3.2 idempotence remove rp_address + route_map (bidir_false) + register: result + cisco.nxos.nxos_pim_rp_address: *id013 + + - ansible.builtin.assert: *id004 + always: + - name: Disable 'feature pim' + cisco.nxos.nxos_feature: *id014 + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_pim_rp_address sanity diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/defaults/main.yaml new file mode 100644 index 00000000..871ea460 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "[^_].*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tasks/cli.yaml new file mode 100644 index 00000000..9e4fb34b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tasks/main.yaml new file mode 100644 index 00000000..b62ef52e --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli.yaml + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tasks/nxapi.yaml new file mode 100644 index 00000000..5cb76e67 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/.DS_Store b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/.DS_Store Binary files differnew file mode 100644 index 00000000..49726657 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/.DS_Store diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/.DS_Store b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/.DS_Store Binary files differnew file mode 100644 index 00000000..4a49c629 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/.DS_Store diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/_populate_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/_populate_config.yaml new file mode 100644 index 00000000..0b99bb81 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/_populate_config.yaml @@ -0,0 +1,12 @@ +--- +- name: Populate configuration + cisco.nxos.nxos_config: + lines: + - "ipv6 prefix-list AllowIPv6Prefix description allows engineering IPv6 networks" + - "ipv6 prefix-list AllowIPv6Prefix seq 8 permit 2001:db8:400::/38" + - "ipv6 prefix-list AllowIPv6Prefix seq 20 permit 2001:db8:8000::/35 le 37" + - "ip prefix-list AllowPrefix description allows engineering IPv4 networks" + - "ip prefix-list AllowPrefix seq 10 permit 192.0.2.0/23 eq 24" + - "ip prefix-list AllowPrefix seq 20 permit 198.51.100.128/26" + - "ip prefix-list DenyPrefix description denies lab IPv4 networks" + - "ip prefix-list DenyPrefix seq 20 deny 203.0.113.0/24 le 25" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/_remove_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/_remove_config.yaml new file mode 100644 index 00000000..ea0baec3 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/_remove_config.yaml @@ -0,0 +1,12 @@ +--- +- name: Remove existing prefix-lists + cisco.nxos.nxos_config: + lines: "{{ item }}" + loop: + - "no ip prefix-list AllowPrefix" + - "no ip prefix-list DenyPrefix" + - "no ip prefix-list AllowPrefix2Stub" + - "no ipv6 prefix-list AllowIPv6Prefix" + ignore_errors: true + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/deleted.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/deleted.yaml new file mode 100644 index 00000000..c5647aeb --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/deleted.yaml @@ -0,0 +1,91 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_prefix_lists deleted integration tests connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Delete all prefix-lists for an AFI + cisco.nxos.nxos_prefix_lists: + config: + - afi: ipv4 + state: deleted + register: result + + - name: Assert that before dicts are correctly generated + ansible.builtin.assert: + that: + - "{{ result['before'][0] == merged['after'][0] }}" + - "{{ result['before'][1] == merged['after'][1] }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - '"no ip prefix-list AllowPrefix" in result.commands' + - '"no ip prefix-list DenyPrefix" in result.commands' + - result.commands|length == 2 + + - name: Assert that after dict is correctly generated + ansible.builtin.assert: + that: + - result["after"][0] == merged["after"][1] + - result["after"]|length == 1 + + - ansible.builtin.include_tasks: _remove_config.yaml + + - ansible.builtin.include_tasks: _populate_config.yaml + + - name: Delete a single prefix-list + cisco.nxos.nxos_prefix_lists: + config: + - afi: ipv4 + prefix_lists: + - name: AllowPrefix + state: deleted + register: result + + - name: Assert that before dicts are correctly generated + ansible.builtin.assert: + that: + - "{{ result['before'][0] == merged['after'][0] }}" + - "{{ result['before'][1] == merged['after'][1] }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - '"no ip prefix-list AllowPrefix" in result.commands' + - result.commands|length == 1 + + - ansible.builtin.include_tasks: _remove_config.yaml + + - ansible.builtin.include_tasks: _populate_config.yaml + + - name: Delete all prefix-lists + cisco.nxos.nxos_prefix_lists: &id001 + state: deleted + register: result + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ deleted['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dict is correctly generated + ansible.builtin.assert: + that: + - result["after"] == [] + + - name: Delete all prefix-lists (idempotent) + register: result + cisco.nxos.nxos_prefix_lists: *id001 + + - name: Assert that task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/empty_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/empty_config.yaml new file mode 100644 index 00000000..aca1e30d --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/empty_config.yaml @@ -0,0 +1,61 @@ +--- +- ansible.builtin.debug: + msg: START nxos_prefix_lists empty_config integration tests on connection={{ ansible_connection }} + +- name: Merged with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_prefix_lists: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_prefix_lists: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Overridden with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_prefix_lists: + config: + state: overridden + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Rendered with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_prefix_lists: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' + +- name: Parsed with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_prefix_lists: + running_config: + state: parsed + +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state parsed' + +- ansible.builtin.debug: + msg: END nxos_prefix_lists empty_config integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/fixtures/parsed.cfg b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/fixtures/parsed.cfg new file mode 100644 index 00000000..b212a16e --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/fixtures/parsed.cfg @@ -0,0 +1,8 @@ +ipv6 prefix-list AllowIPv6Prefix description allows engineering IPv6 networks +ipv6 prefix-list AllowIPv6Prefix seq 8 permit 2001:db8:400::/38 +ipv6 prefix-list AllowIPv6Prefix seq 20 permit 2001:db8:8000::/35 le 37 +ip prefix-list AllowPrefix description allows engineering IPv4 networks +ip prefix-list AllowPrefix seq 10 permit 192.0.2.0/23 eq 24 +ip prefix-list AllowPrefix seq 20 permit 198.51.100.128/26 +ip prefix-list DenyPrefix description denies lab IPv4 networks +ip prefix-list DenyPrefix seq 20 deny 203.0.113.0/24 le 25 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/gathered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/gathered.yaml new file mode 100644 index 00000000..056e2737 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/gathered.yaml @@ -0,0 +1,22 @@ +--- +- ansible.builtin.debug: + msg: START nxos_prefix_lists gathered integration tests on connection={{ ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Gather prefix-lists facts using gathered + register: result + cisco.nxos.nxos_prefix_lists: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: + - result["gathered"][0] == merged["after"][0] + - result["gathered"][1] == merged["after"][1] + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/merged.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/merged.yaml new file mode 100644 index 00000000..b8613a00 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/merged.yaml @@ -0,0 +1,89 @@ +--- +- ansible.builtin.debug: + msg: "Start nxos_prefix_lists merged integration tests connection={{ ansible_connection }}" + +- ansible.builtin.include_tasks: _remove_config.yaml + +- block: + - name: Merge the provided configuration with the existing running configuration + cisco.nxos.nxos_prefix_lists: &id001 + config: + - afi: ipv4 + prefix_lists: + - name: AllowPrefix + description: allows engineering IPv4 networks + entries: + - sequence: 10 + action: permit + prefix: 192.0.2.0/23 + eq: 24 + - sequence: 20 + action: permit + prefix: 198.51.100.128/26 + - name: DenyPrefix + description: denies lab IPv4 networks + entries: + - sequence: 20 + action: deny + prefix: 203.0.113.0/24 + le: 25 + + - afi: ipv6 + prefix_lists: + - name: AllowIPv6Prefix + description: allows engineering IPv6 networks + entries: + - sequence: 8 + action: permit + prefix: "2001:db8:400::/38" + - sequence: 20 + action: permit + prefix: "2001:db8:8000::/35" + le: 37 + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ result['before'] == [] }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ merged['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ merged['after'][0] == result['after'][0] }}" + - "{{ merged['after'][1] == result['after'][1] }}" + + - name: Merge the provided configuration with the existing running configuration (idempotent) + cisco.nxos.nxos_prefix_lists: *id001 + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + - name: Attempt to update an existing prefix-list entry (should fail) + cisco.nxos.nxos_prefix_lists: + config: + - afi: ipv4 + prefix_lists: + - name: AllowPrefix + description: allows engineering IPv4 networks + entries: + - sequence: 10 + action: permit + prefix: 198.51.100.128/26 + register: result + ignore_errors: true + + - ansible.builtin.assert: + that: + - result.failed == True + - '"Cannot update existing sequence 10 of prefix list AllowPrefix with state merged. Please use state replaced or overridden." in result.msg' + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/overridden.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/overridden.yaml new file mode 100644 index 00000000..3fbd54c0 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/overridden.yaml @@ -0,0 +1,56 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_prefix_lists overridden integration tests connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Override all prefix-lists configuration with provided configuration + cisco.nxos.nxos_prefix_lists: &id001 + config: + - afi: ipv4 + prefix_lists: + - name: AllowPrefix + description: allows engineering IPv4 networks + entries: + - sequence: 10 + action: permit + prefix: 203.0.113.64/27 + + - sequence: 30 + action: permit + prefix: 203.0.113.96/27 + - name: AllowPrefix2Stub + description: allow other engineering IPv4 network + state: overridden + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ result['before'][0] == merged['after'][0] }}" + - "{{ result['before'][1] == merged['after'][1] }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ overridden['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ overridden['after'][0] == result['after'][0] }}" + + - name: Override all prefix-lists configuration with provided configuration (idempotent) + register: result + cisco.nxos.nxos_prefix_lists: *id001 + + - name: Assert that task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/parsed.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/parsed.yaml new file mode 100644 index 00000000..260fe12e --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/parsed.yaml @@ -0,0 +1,15 @@ +--- +- ansible.builtin.debug: + msg: START nxos_prefix_lists parsed integration tests on connection={{ ansible_connection }} + +- name: Parse externally provided prefix-lists configuration + register: result + cisco.nxos.nxos_prefix_lists: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed + +- name: Assert that configuration was correctly parsed + ansible.builtin.assert: + that: + - "{{ merged['after'][0] == result['parsed'][0] }}" + - "{{ merged['after'][1] == result['parsed'][1] }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/rendered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/rendered.yaml new file mode 100644 index 00000000..1356a83c --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/rendered.yaml @@ -0,0 +1,47 @@ +--- +- ansible.builtin.debug: + msg: START nxos_prefix_lists rendered integration tests on connection={{ ansible_connection }} + +- name: Render platform specific configuration lines with state rendered (without connecting to the device) + cisco.nxos.nxos_prefix_lists: + config: + - afi: ipv4 + prefix_lists: + - name: AllowPrefix + description: allows engineering IPv4 networks + entries: + - sequence: 10 + action: permit + prefix: 192.0.2.0/23 + eq: 24 + - sequence: 20 + action: permit + prefix: 198.51.100.128/26 + - name: DenyPrefix + description: denies lab IPv4 networks + entries: + - sequence: 20 + action: deny + prefix: 203.0.113.0/24 + le: 25 + + - afi: ipv6 + prefix_lists: + - name: AllowIPv6Prefix + description: allows engineering IPv6 networks + entries: + - sequence: 8 + action: permit + prefix: "2001:db8:400::/38" + - sequence: 20 + action: permit + prefix: "2001:db8:8000::/35" + le: 37 + state: rendered + register: result + +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - "{{ merged['commands'] | symmetric_difference(result['rendered']) |length == 0 }}" + - result.changed == False diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/replaced.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/replaced.yaml new file mode 100644 index 00000000..00f9370e --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/tests/common/replaced.yaml @@ -0,0 +1,58 @@ +--- +- ansible.builtin.debug: + msg: "Start nxos_prefix_lists replaced integration tests connection={{ ansible_connection }}" + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Replace prefix-lists configurations of listed prefix-lists with provided configurations + cisco.nxos.nxos_prefix_lists: &id001 + config: + - afi: ipv4 + prefix_lists: + - name: AllowPrefix + description: allows engineering IPv4 networks + entries: + - sequence: 10 + action: permit + prefix: 203.0.113.64/27 + + - sequence: 30 + action: permit + prefix: 203.0.113.96/27 + - name: AllowPrefix2Stub + description: allow other engineering IPv4 network + state: replaced + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ result['before'][0] == merged['after'][0] }}" + - "{{ result['before'][1] == merged['after'][1] }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ replaced['after'][0] == result['after'][0] }}" + - "{{ replaced['after'][1] == result['after'][1] }}" + + - name: Replace prefix-lists configurations of listed prefix-lists with provided configurations (idempotent) + register: result + cisco.nxos.nxos_prefix_lists: *id001 + + - name: Assert that task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/vars/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/vars/main.yml new file mode 100644 index 00000000..afcff706 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_prefix_lists/vars/main.yml @@ -0,0 +1,120 @@ +--- +merged: + before: [] + commands: + - "ipv6 prefix-list AllowIPv6Prefix description allows engineering IPv6 networks" + - "ipv6 prefix-list AllowIPv6Prefix seq 8 permit 2001:db8:400::/38" + - "ipv6 prefix-list AllowIPv6Prefix seq 20 permit 2001:db8:8000::/35 le 37" + - "ip prefix-list AllowPrefix description allows engineering IPv4 networks" + - "ip prefix-list AllowPrefix seq 10 permit 192.0.2.0/23 eq 24" + - "ip prefix-list AllowPrefix seq 20 permit 198.51.100.128/26" + - "ip prefix-list DenyPrefix description denies lab IPv4 networks" + - "ip prefix-list DenyPrefix seq 20 deny 203.0.113.0/24 le 25" + after: + - afi: ipv4 + prefix_lists: + - description: allows engineering IPv4 networks + entries: + - sequence: 10 + action: permit + prefix: 192.0.2.0/23 + eq: 24 + - sequence: 20 + action: permit + prefix: 198.51.100.128/26 + name: AllowPrefix + - description: denies lab IPv4 networks + entries: + - sequence: 20 + action: deny + prefix: 203.0.113.0/24 + le: 25 + name: DenyPrefix + + - afi: ipv6 + prefix_lists: + - description: allows engineering IPv6 networks + entries: + - sequence: 8 + action: permit + prefix: "2001:db8:400::/38" + - sequence: 20 + action: permit + prefix: "2001:db8:8000::/35" + le: 37 + name: AllowIPv6Prefix + +replaced: + commands: + - "no ip prefix-list AllowPrefix seq 10 permit 192.0.2.0/23 eq 24" + - "ip prefix-list AllowPrefix seq 10 permit 203.0.113.64/27" + - "ip prefix-list AllowPrefix seq 30 permit 203.0.113.96/27" + - "no ip prefix-list AllowPrefix seq 20 permit 198.51.100.128/26" + - "ip prefix-list AllowPrefix2Stub description allow other engineering IPv4 network" + + after: + - afi: ipv4 + prefix_lists: + - description: allows engineering IPv4 networks + entries: + - sequence: 10 + action: permit + prefix: 203.0.113.64/27 + - sequence: 30 + action: permit + prefix: 203.0.113.96/27 + name: AllowPrefix + - description: allow other engineering IPv4 network + name: AllowPrefix2Stub + - description: denies lab IPv4 networks + entries: + - sequence: 20 + action: deny + prefix: 203.0.113.0/24 + le: 25 + name: DenyPrefix + + - afi: ipv6 + prefix_lists: + - description: allows engineering IPv6 networks + entries: + - sequence: 8 + action: permit + prefix: "2001:db8:400::/38" + - sequence: 20 + action: permit + prefix: "2001:db8:8000::/35" + le: 37 + name: AllowIPv6Prefix + +overridden: + commands: + - "no ip prefix-list AllowPrefix seq 10 permit 192.0.2.0/23 eq 24" + - "ip prefix-list AllowPrefix seq 10 permit 203.0.113.64/27" + - "ip prefix-list AllowPrefix seq 30 permit 203.0.113.96/27" + - "no ip prefix-list AllowPrefix seq 20 permit 198.51.100.128/26" + - "ip prefix-list AllowPrefix2Stub description allow other engineering IPv4 network" + - "no ip prefix-list DenyPrefix" + - "no ipv6 prefix-list AllowIPv6Prefix" + + after: + - afi: ipv4 + prefix_lists: + - name: AllowPrefix + description: allows engineering IPv4 networks + entries: + - sequence: 10 + action: permit + prefix: 203.0.113.64/27 + + - sequence: 30 + action: permit + prefix: 203.0.113.96/27 + - name: AllowPrefix2Stub + description: allow other engineering IPv4 network + +deleted: + commands: + - "no ip prefix-list AllowPrefix" + - "no ip prefix-list DenyPrefix" + - "no ipv6 prefix-list AllowIPv6Prefix" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_reboot/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_reboot/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_reboot/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_reboot/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_reboot/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_reboot/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_reboot/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_reboot/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_reboot/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_reboot/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_reboot/tasks/main.yaml new file mode 100644 index 00000000..cbbbcb24 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_reboot/tasks/main.yaml @@ -0,0 +1,8 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_reboot/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_reboot/tasks/nxapi.yaml new file mode 100644 index 00000000..57e91e21 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_reboot/tasks/nxapi.yaml @@ -0,0 +1,33 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + tags: nxapi_httpapi + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_reboot/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_reboot/tests/common/sanity.yaml new file mode 100644 index 00000000..6f5bf9b4 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_reboot/tests/common/sanity.yaml @@ -0,0 +1,24 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_reboot sanity test + +- ansible.builtin.debug: + msg: "***WARNING*** Set run_nxos_reboot_test to True to verify this module ***WARNING***" + +- block: + - name: Reboot switch + ignore_errors: true + cisco.nxos.nxos_reboot: + confirm: true + always: + - name: Wait for device to come back up + ansible.builtin.wait_for: + port: 22 + state: started + timeout: 600 + delay: 60 + host: "{{ inventory_hostname }}" + + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_reboot sanity test + when: run_nxos_reboot_test | d(False) diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rollback/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rollback/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rollback/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rollback/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rollback/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rollback/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rollback/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rollback/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rollback/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rollback/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rollback/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rollback/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rollback/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rollback/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rollback/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rollback/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rollback/tests/common/sanity.yaml new file mode 100644 index 00000000..8d02e8c3 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rollback/tests/common/sanity.yaml @@ -0,0 +1,26 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_rollback sanity test + +- name: Delete existing checkpoint file + ignore_errors: true + cisco.nxos.nxos_config: &id001 + commands: + - terminal dont-ask + - delete backup.cfg + match: none + +- name: Create checkpoint file + cisco.nxos.nxos_rollback: + checkpoint_file: backup.cfg + +- name: Rollback to the previously created checkpoint file + cisco.nxos.nxos_rollback: + rollback_to: backup.cfg + +- name: Cleanup checkpoint file + ignore_errors: true + cisco.nxos.nxos_config: *id001 + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_rollback sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/defaults/main.yaml new file mode 100644 index 00000000..871ea460 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "[^_].*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tasks/cli.yaml new file mode 100644 index 00000000..9e4fb34b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tasks/main.yaml new file mode 100644 index 00000000..b62ef52e --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli.yaml + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tasks/nxapi.yaml new file mode 100644 index 00000000..5cb76e67 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/_populate_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/_populate_config.yaml new file mode 100644 index 00000000..3bcd50a7 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/_populate_config.yaml @@ -0,0 +1,26 @@ +--- +- name: Populate configuration + cisco.nxos.nxos_config: + lines: + - "route-map rmap1 permit 10" + - " match as-number 65564" + - " match as-path Allow40" + - " match ip address acl_1" + - " description rmap1-10-permit" + - "route-map rmap1 deny 20" + - " match community BGPCommunity1 BGPCommunity2" + - " match ip address prefix-list AllowPrefix1 AllowPrefix2" + - " description rmap1-20-deny" + - " set dampening 30 1500 10000 120" + - "route-map rmap2 permit 20" + - " match interface Ethernet1/1" + - " match ipv6 address prefix-list AllowIPv6Prefix" + - " set as-path prepend 65563 65568 65569" + - " description rmap2-20-permit" + - " continue 40" + - " set comm-list BGPCommunity delete" + - "route-map rmap2 deny 40" + - " match ip multicast source 203.0.113.0/24 group-range 239.0.0.1 to 239.255.255.255 rp 192.0.2.0/24 rp-type ASM" + - " match route-type level-1 level-2" + - " match tag 2" + - " description rmap2-40-deny" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/_remove_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/_remove_config.yaml new file mode 100644 index 00000000..9b6d58dd --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/_remove_config.yaml @@ -0,0 +1,9 @@ +--- +- name: Remove existing route-maps + cisco.nxos.nxos_config: + lines: + - "no route-map rmap1" + - "no route-map rmap2" + ignore_errors: true + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/_setup.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/_setup.yaml new file mode 100644 index 00000000..319398d5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/_setup.yaml @@ -0,0 +1,12 @@ +--- +- name: "Populate interfaces" + cisco.nxos.nxos_config: + lines: + - "no switchport" + parents: "interface {{ item }}" + loop: + - "{{ nxos_int1 }}" + - "{{ nxos_int2 }}" + - "{{ nxos_int3 }}" + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/deleted.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/deleted.yaml new file mode 100644 index 00000000..a26ae2ff --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/deleted.yaml @@ -0,0 +1,66 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_route_maps deleted integration tests connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Delete single route-map + cisco.nxos.nxos_route_maps: + config: + - route_map: rmap1 + state: deleted + register: result + + - name: Assert that before dicts are correctly generated + ansible.builtin.assert: + that: + - "{{ result['before'][0] == merged['after'][0] }}" + - "{{ result['before'][1] == merged['after'][1] }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - '"no route-map rmap1 permit 10" in result.commands' + - '"no route-map rmap1 deny 20" in result.commands' + - result.commands|length == 2 + + - name: Assert that after dict is correctly generated + ansible.builtin.assert: + that: + - result["after"][0] == merged["after"][1] + - result["after"]|length == 1 + + - ansible.builtin.include_tasks: _remove_config.yaml + + - ansible.builtin.include_tasks: _populate_config.yaml + + - name: Delete all route-maps + cisco.nxos.nxos_route_maps: &id001 + state: deleted + register: result + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ deleted['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dict is correctly generated + ansible.builtin.assert: + that: + - result["after"] == [] + + - name: Delete all route-maps (idempotent) + register: result + cisco.nxos.nxos_route_maps: *id001 + + - name: Assert that task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/empty_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/empty_config.yaml new file mode 100644 index 00000000..898bea2d --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/empty_config.yaml @@ -0,0 +1,61 @@ +--- +- ansible.builtin.debug: + msg: START nxos_route_maps empty_config integration tests on connection={{ ansible_connection }} + +- name: Merged with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_route_maps: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_route_maps: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Overridden with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_route_maps: + config: + state: overridden + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Rendered with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_route_maps: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' + +- name: Parsed with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_route_maps: + running_config: + state: parsed + +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state parsed' + +- ansible.builtin.debug: + msg: END nxos_route_maps empty_config integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/fixtures/parsed.cfg b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/fixtures/parsed.cfg new file mode 100644 index 00000000..df9edee0 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/fixtures/parsed.cfg @@ -0,0 +1,22 @@ +route-map rmap1 permit 10 + match as-number 65564 + match as-path Allow40 + match ip address acl_1 + description rmap1-10-permit +route-map rmap1 deny 20 + match community BGPCommunity1 BGPCommunity2 + match ip address prefix-list AllowPrefix1 AllowPrefix2 + description rmap1-20-deny + set dampening 30 1500 10000 120 +route-map rmap2 permit 20 + match interface Ethernet1/1 + match ipv6 address prefix-list AllowIPv6Prefix + set as-path prepend 65563 65568 65569 + description rmap2-20-permit + continue 40 + set comm-list BGPCommunity delete +route-map rmap2 deny 40 + match ip multicast source 203.0.113.0/24 group-range 239.0.0.1 to 239.255.255.255 rp 192.0.2.0/24 rp-type ASM + match route-type level-1 level-2 + match tag 2 + description rmap2-40-deny diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/gathered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/gathered.yaml new file mode 100644 index 00000000..03171aea --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/gathered.yaml @@ -0,0 +1,22 @@ +--- +- ansible.builtin.debug: + msg: START nxos_route_maps gathered integration tests on connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Gather route-maps facts using gathered + register: result + cisco.nxos.nxos_route_maps: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: + - result["gathered"][0] == merged["after"][0] + - result["gathered"][1] == merged["after"][1] + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/merged.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/merged.yaml new file mode 100644 index 00000000..3e26cd2e --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/merged.yaml @@ -0,0 +1,107 @@ +--- +- ansible.builtin.debug: + msg: "Start nxos_route_maps merged integration tests connection={{ ansible_connection }}" +- ansible.builtin.include_tasks: _remove_config.yaml + +- block: + - name: Merge the provided configuration with the existing running configuration + cisco.nxos.nxos_route_maps: &id001 + config: + - route_map: rmap1 + entries: + - sequence: 10 + action: permit + description: rmap1-10-permit + match: + ip: + address: + access_list: acl_1 + as_path: Allow40 + as_number: + asn: 65564 + + - sequence: 20 + action: deny + description: rmap1-20-deny + match: + community: + community_list: + - BGPCommunity1 + - BGPCommunity2 + ip: + address: + prefix_lists: + - AllowPrefix1 + - AllowPrefix2 + set: + dampening: + half_life: 30 + start_reuse_route: 1500 + start_suppress_route: 10000 + max_suppress_time: 120 + + - route_map: rmap2 + entries: + - sequence: 20 + action: permit + description: rmap2-20-permit + continue_sequence: 40 + match: + ipv6: + address: + prefix_lists: AllowIPv6Prefix + interfaces: "{{ nxos_int1 }}" + set: + as_path: + prepend: + as_number: + - 65563 + - 65568 + - 65569 + comm_list: BGPCommunity + + - sequence: 40 + action: deny + description: rmap2-40-deny + match: + route_types: + - level-1 + - level-2 + tags: 2 + ip: + multicast: + rp: + prefix: 192.0.2.0/24 + rp_type: ASM + source: 203.0.113.0/24 + group_range: + first: 239.0.0.1 + last: 239.255.255.255 + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ result['before'] == [] }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ merged['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ merged['after'][0] == result['after'][0] }}" + - "{{ merged['after'][1] == result['after'][1] }}" + + - name: Merge the provided configuration with the existing running configuration (idempotent) + cisco.nxos.nxos_route_maps: *id001 + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/overridden.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/overridden.yaml new file mode 100644 index 00000000..fc2cc7be --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/overridden.yaml @@ -0,0 +1,59 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_route_maps overridden integration tests connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Override all route-maps configuration with provided configuration + cisco.nxos.nxos_route_maps: &id001 + config: + - route_map: rmap1 + entries: + - sequence: 20 + action: deny + description: rmap1-20-deny + match: + community: + community_list: + - BGPCommunity4 + - BGPCommunity5 + ip: + address: + prefix_lists: + - AllowPrefix1 + set: + community: + local_as: true + state: overridden + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ result['before'][0] == merged['after'][0] }}" + - "{{ result['before'][1] == merged['after'][1] }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ overridden['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ overridden['after'][0] == result['after'][0] }}" + + - name: Override all route-maps configuration with provided configuration (idempotent) + register: result + cisco.nxos.nxos_route_maps: *id001 + + - name: Assert that task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/parsed.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/parsed.yaml new file mode 100644 index 00000000..68b6e410 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/parsed.yaml @@ -0,0 +1,14 @@ +--- +- ansible.builtin.debug: + msg: START nxos_route_maps parsed integration tests on connection={{ ansible_connection }} + +- name: Parse externally provided route-maps configuration + register: result + cisco.nxos.nxos_route_maps: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed + +- name: Assert that configuration was correctly parsed + ansible.builtin.assert: + that: + - "{{ merged['after'] | symmetric_difference(result['parsed']) |length == 0 }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/rendered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/rendered.yaml new file mode 100644 index 00000000..4b8567a4 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/rendered.yaml @@ -0,0 +1,85 @@ +--- +- ansible.builtin.debug: + msg: START nxos_route_maps rendered integration tests on connection={{ ansible_connection }} + +- name: Render platform specific configuration lines with state rendered (without connecting to the device) + cisco.nxos.nxos_route_maps: + config: + - route_map: rmap1 + entries: + - sequence: 10 + action: permit + description: rmap1-10-permit + match: + ip: + address: + access_list: acl_1 + as_path: Allow40 + as_number: + asn: 65564 + + - sequence: 20 + action: deny + description: rmap1-20-deny + match: + community: + community_list: + - BGPCommunity1 + - BGPCommunity2 + ip: + address: + prefix_lists: + - AllowPrefix1 + - AllowPrefix2 + set: + dampening: + half_life: 30 + start_reuse_route: 1500 + start_suppress_route: 10000 + max_suppress_time: 120 + + - route_map: rmap2 + entries: + - sequence: 20 + action: permit + description: rmap2-20-permit + continue_sequence: 40 + match: + ipv6: + address: + prefix_lists: AllowIPv6Prefix + interfaces: "{{ nxos_int1 }}" + set: + as_path: + prepend: + as_number: + - 65563 + - 65568 + - 65569 + comm_list: BGPCommunity + + - sequence: 40 + action: deny + description: rmap2-40-deny + match: + route_types: + - level-1 + - level-2 + tags: 2 + ip: + multicast: + rp: + prefix: 192.0.2.0/24 + rp_type: ASM + source: 203.0.113.0/24 + group_range: + first: 239.0.0.1 + last: 239.255.255.255 + state: rendered + register: result + +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - "{{ merged['commands'] | symmetric_difference(result['rendered']) |length == 0 }}" + - result.changed == False diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/replaced.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/replaced.yaml new file mode 100644 index 00000000..3a03bb76 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/tests/common/replaced.yaml @@ -0,0 +1,61 @@ +--- +- ansible.builtin.debug: + msg: "Start nxos_route_maps replaced integration tests connection={{ ansible_connection }}" + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Replace route-maps configurations of listed route-maps with provided configurations + cisco.nxos.nxos_route_maps: &id001 + config: + - route_map: rmap1 + entries: + - sequence: 20 + action: deny + description: rmap1-20-deny + match: + community: + community_list: + - BGPCommunity4 + - BGPCommunity5 + ip: + address: + prefix_lists: + - AllowPrefix1 + set: + community: + local_as: true + state: replaced + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ result['before'][0] == merged['after'][0] }}" + - "{{ result['before'][1] == merged['after'][1] }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ replaced['after'][0] == result['after'][0] }}" + - "{{ replaced['after'][1] == result['after'][1] }}" + + - name: Replace route-maps configurations of listed route-maps with provided configurations (idempotent) + register: result + cisco.nxos.nxos_route_maps: *id001 + + - name: Assert that task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/vars/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/vars/main.yml new file mode 100644 index 00000000..7e14dc28 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_route_maps/vars/main.yml @@ -0,0 +1,212 @@ +--- +merged: + before: [] + commands: + - "route-map rmap1 permit 10" + - "match as-number 65564" + - "match as-path Allow40" + - "match ip address acl_1" + - "description rmap1-10-permit" + - "route-map rmap1 deny 20" + - "match community BGPCommunity1 BGPCommunity2" + - "match ip address prefix-list AllowPrefix1 AllowPrefix2" + - "description rmap1-20-deny" + - "set dampening 30 1500 10000 120" + - "route-map rmap2 permit 20" + - "match interface Ethernet1/1" + - "match ipv6 address prefix-list AllowIPv6Prefix" + - "set as-path prepend 65563 65568 65569" + - "description rmap2-20-permit" + - "continue 40" + - "set comm-list BGPCommunity delete" + - "route-map rmap2 deny 40" + - "match ip multicast source 203.0.113.0/24 group-range 239.0.0.1 to 239.255.255.255 rp 192.0.2.0/24 rp-type ASM" + - "match route-type level-1 level-2" + - "match tag 2" + - "description rmap2-40-deny" + after: + - entries: + - action: permit + description: rmap1-10-permit + match: + as_number: + asn: + - "65564" + as_path: + - Allow40 + ip: + address: + access_list: acl_1 + sequence: 10 + + - action: deny + description: rmap1-20-deny + match: + community: + community_list: + - BGPCommunity1 + - BGPCommunity2 + ip: + address: + prefix_lists: + - AllowPrefix1 + - AllowPrefix2 + sequence: 20 + set: + dampening: + half_life: 30 + max_suppress_time: 120 + start_reuse_route: 1500 + start_suppress_route: 10000 + route_map: rmap1 + + - route_map: rmap2 + entries: + - action: permit + continue_sequence: 40 + description: rmap2-20-permit + match: + interfaces: + - Ethernet1/1 + ipv6: + address: + prefix_lists: + - AllowIPv6Prefix + sequence: 20 + set: + as_path: + prepend: + as_number: + - "65563" + - "65568" + - "65569" + comm_list: BGPCommunity + + - action: deny + description: rmap2-40-deny + match: + ip: + multicast: + group_range: + first: 239.0.0.1 + last: 239.255.255.255 + rp: + prefix: 192.0.2.0/24 + rp_type: ASM + source: 203.0.113.0/24 + route_types: + - level-1 + - level-2 + tags: + - 2 + sequence: 40 + +replaced: + commands: + - no route-map rmap1 permit 10 + - route-map rmap1 deny 20 + - no match community BGPCommunity1 BGPCommunity2 + - match community BGPCommunity4 BGPCommunity5 + - no match ip address prefix-list AllowPrefix1 AllowPrefix2 + - match ip address prefix-list AllowPrefix1 + - no set dampening 30 1500 10000 120 + - set community local-AS + + after: + - route_map: rmap1 + entries: + - sequence: 20 + action: deny + description: rmap1-20-deny + match: + community: + community_list: + - BGPCommunity4 + - BGPCommunity5 + ip: + address: + prefix_lists: + - AllowPrefix1 + set: + community: + local_as: true + + - route_map: rmap2 + entries: + - action: permit + continue_sequence: 40 + description: rmap2-20-permit + match: + interfaces: + - Ethernet1/1 + ipv6: + address: + prefix_lists: + - AllowIPv6Prefix + sequence: 20 + set: + as_path: + prepend: + as_number: + - "65563" + - "65568" + - "65569" + comm_list: BGPCommunity + + - action: deny + description: rmap2-40-deny + match: + ip: + multicast: + group_range: + first: 239.0.0.1 + last: 239.255.255.255 + rp: + prefix: 192.0.2.0/24 + rp_type: ASM + source: 203.0.113.0/24 + route_types: + - level-1 + - level-2 + tags: + - 2 + sequence: 40 + +overridden: + commands: + - no route-map rmap1 permit 10 + - route-map rmap1 deny 20 + - no match community BGPCommunity1 BGPCommunity2 + - match community BGPCommunity4 BGPCommunity5 + - no match ip address prefix-list AllowPrefix1 AllowPrefix2 + - match ip address prefix-list AllowPrefix1 + - no set dampening 30 1500 10000 120 + - set community local-AS + - no route-map rmap2 permit 20 + - no route-map rmap2 deny 40 + + after: + - route_map: rmap1 + entries: + - sequence: 20 + action: deny + description: rmap1-20-deny + match: + community: + community_list: + - BGPCommunity4 + - BGPCommunity5 + ip: + address: + prefix_lists: + - AllowPrefix1 + set: + community: + local_as: true + +deleted: + commands: + - no route-map rmap1 permit 10 + - no route-map rmap1 deny 20 + - no route-map rmap2 permit 20 + - no route-map rmap2 deny 40 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rpm/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rpm/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rpm/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rpm/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rpm/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rpm/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rpm/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rpm/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rpm/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rpm/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rpm/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rpm/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rpm/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rpm/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rpm/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rpm/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rpm/tests/common/sanity.yaml new file mode 100644 index 00000000..5f7bfd30 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_rpm/tests/common/sanity.yaml @@ -0,0 +1,159 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_rpm sanity test + +- name: Set a fact for 'smu_run' + ansible.builtin.set_fact: + smu_run: false + +- name: Set a fact for 'smu_run' + ansible.builtin.set_fact: + smu_run: true + when: ((platform is search('N9K')) and (imagetag and 'I' in imagetag and (imagetag is version_compare('I2', 'ge')))) + +- name: Set a fact for 'sdk_run' + ansible.builtin.set_fact: + sdk_run: false + +- name: Set a fact for 'sdk_run' + ansible.builtin.set_fact: + sdk_run: true + when: ((platform is search('N9K')) and (imagetag and 'I' in imagetag and (imagetag is version_compare('I6', 'ge')))) + +- ansible.builtin.debug: + msg: "***WARNING*** Set run_nxos_rpm_test to True to verify this module ***WARNING***" + +- block: + - block: + - name: Install smu RPM + register: result + cisco.nxos.nxos_rpm: &id001 + pkg: nxos.sample-n9k_ALL-1.0.0-7.0.3.I6.1.lib32_n9000.rpm + + - assert: &id002 + that: + - result.changed == true + + - name: Check Idempotence + register: result + cisco.nxos.nxos_rpm: *id001 + + - assert: &id004 + that: + - result.changed == false + + - name: Remove smu RPM + register: result + cisco.nxos.nxos_rpm: &id003 + pkg: nxos.sample-n9k_ALL-1.0.0-7.0.3.I6.1.lib32_n9000.rpm + state: absent + + - assert: *id002 + + - name: Check Idempotence + register: result + cisco.nxos.nxos_rpm: *id003 + + - assert: *id004 + when: smu_run + + - block: + - name: Install nxsdk RPM(aggregate) + register: result + cisco.nxos.nxos_rpm: &id005 + aggregate: + - pkg: healthMonitor-1.0-1.5.0.x86_64.rpm + file_system: bootflash + + - pkg: customCliApp-1.0-1.0.0.x86_64.rpm + + - assert: &id006 + that: + - result.changed == true + + - name: Check Idempotence + register: result + cisco.nxos.nxos_rpm: *id005 + + - assert: &id008 + that: + - result.changed == false + + - name: Remove nxsdk RPM(aggregate) + register: result + cisco.nxos.nxos_rpm: &id007 + aggregate: + - pkg: healthMonitor-1.0-1.5.0.x86_64.rpm + + - pkg: customCliApp-1.0-1.0.0.x86_64.rpm + state: absent + + - assert: *id006 + + - name: Check Idempotence + register: result + cisco.nxos.nxos_rpm: *id007 + + - assert: *id008 + when: sdk_run + + - block: + - name: Install reload smu RPM + register: result + cisco.nxos.nxos_rpm: &id009 + pkg: nxos.CSCve91311-n9k_ALL-1.0.0-7.0.3.I6.1.lib32_n9000.rpm + + - assert: *id002 + + - name: Wait for device to come back up + wait_for: + port: 22 + state: started + timeout: 600 + delay: 60 + host: "{{ inventory_hostname_short }}" + + - name: Continue with install reload smu RPM + register: result + cisco.nxos.nxos_rpm: *id009 + + - assert: *id002 + + - name: Check Idempotence + register: result + cisco.nxos.nxos_rpm: *id009 + + - assert: *id004 + + - name: Remove reload smu RPM + register: result + cisco.nxos.nxos_rpm: &id010 + pkg: nxos.CSCve91311-n9k_ALL-1.0.0-7.0.3.I6.1.lib32_n9000.rpm + state: absent + + - assert: *id002 + + - name: Wait for device to come back up + wait_for: + port: 22 + state: started + timeout: 600 + delay: 60 + host: "{{ inventory_hostname_short }}" + + - name: Continue with remove reload smu RPM + register: result + cisco.nxos.nxos_rpm: *id010 + + - assert: *id002 + + - name: Check Idempotence + register: result + cisco.nxos.nxos_rpm: *id010 + + - assert: *id004 + when: smu_run + when: run_nxos_rpm_test|d(False) + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_rpm sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_smoke/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_smoke/defaults/main.yaml new file mode 100644 index 00000000..9ef5ba51 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_smoke/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "*" +test_items: [] diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_smoke/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_smoke/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_smoke/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_smoke/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_smoke/tasks/cli.yaml new file mode 100644 index 00000000..1fa8d4e1 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_smoke/tasks/cli.yaml @@ -0,0 +1,55 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Set a fact for 'cli' + ansible.builtin.set_fact: + cli: + transport: cli + authorize: true + +- name: Run test cases (connection=network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: network_cli + connection: "{{ cli }}" + +# Temporarily disabling connection=local tests for CI issues +# - name: run test cases (connection=local) +# ansible.builtin.include_tasks: "{{ test_case_to_run }} +# vars: +# ansible_connection: local +# connection: "{{ cli }}" +# with_items: "{{ test_items }}" +# loop_control: +# loop_var: test_case_to_run + +- name: Run test cases (connection=network_cli) + ansible.builtin.include_tasks: "{{ role_path }}/tests/common/caching.yaml" + vars: + ansible_connection: ansible.netcommon.network_cli + ansible_network_single_user_mode: true + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_smoke/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_smoke/tasks/main.yaml new file mode 100644 index 00000000..144efbb5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_smoke/tasks/main.yaml @@ -0,0 +1,21 @@ +--- +# Some of the tests in this suite change the hostname to switch. +# This block/always ensures the hostname gets changed back to +# the correct name. +- name: Run the CLI and NX-API tests + block: + - name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - "cli" + - name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - "nxapi" + + always: + - name: "Change hostname back to {{ inventory_hostname_short }}" + cisco.nxos.nxos_config: + lines: + - "hostname {{ inventory_hostname_short }}" + match: none diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_smoke/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_smoke/tasks/nxapi.yaml new file mode 100644 index 00000000..f3a565f9 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_smoke/tasks/nxapi.yaml @@ -0,0 +1,40 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: httpapi + connection: "{{ nxapi }}" +# Temporarily disabling connection=local tests for CI issues +# - name: run test cases (connection=local) +# ansible.builtin.include_tasks: "{{ test_case_to_run }} +# vars: +# ansible_connection: local connection={{ nxapi }} +# with_items: "{{ test_items }}" +# loop_control: +# loop_var: test_case_to_run diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_smoke/tests/cli/misc_tests.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_smoke/tests/cli/misc_tests.yaml new file mode 100644 index 00000000..e26c0c13 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_smoke/tests/cli/misc_tests.yaml @@ -0,0 +1,10 @@ +--- +- ansible.builtin.debug: + msg: START cli/misc_tests.yaml on connection={{ ansible_connection }} + +- block: + - name: Test that provider values are properly ignored + cisco.nxos.nxos_command: + commands: show version + + when: "ansible_connection != 'local'" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_smoke/tests/common/caching.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_smoke/tests/common/caching.yaml new file mode 100644 index 00000000..f0a95deb --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_smoke/tests/common/caching.yaml @@ -0,0 +1,96 @@ +--- +- block: + - ansible.builtin.debug: + msg: START connection={{ ansible_connection }} common/caching.yaml + + - name: Set system defaults for switchports + cisco.nxos.nxos_config: + lines: "no system default switchport\nsystem default switchport shutdown\n" + + - name: Setup + cisco.nxos.nxos_config: &rem + lines: + - "default interface {{ nxos_int1 }}" + - "default interface {{ nxos_int2 }}" + + - name: Merge base interfaces configuration + register: result + cisco.nxos.nxos_interfaces: &merged + config: + - name: "{{ nxos_int1 }}" + description: Configured by Ansible (L2) + mode: layer2 + - name: "{{ nxos_int2 }}" + description: Configured by Ansible (L3) + mode: layer3 + state: merged + + - ansible.builtin.assert: + that: + - '"interface {{ nxos_int1 }}" in result.commands' + - '"description Configured by Ansible (L2)" in result.commands' + - '"switchport" in result.commands' + - '"interface {{ nxos_int2 }}" in result.commands' + - '"description Configured by Ansible (L3)" in result.commands' + - result.commands|length == 5 + + - name: Merge base interfaces configuration (idempotent) + register: result + cisco.nxos.nxos_interfaces: *merged + + - ansible.builtin.assert: + that: + - result.changed == False + + - name: Merge layer 2 interfaces configuration + register: result + cisco.nxos.nxos_l2_interfaces: &mergedl2 + config: + - name: "{{ nxos_int1 }}" + trunk: + native_vlan: 10 + allowed_vlans: 2,4,15 + state: merged + + - ansible.builtin.assert: + that: + - '"interface {{ nxos_int1 }}" in result.commands' + - '"switchport trunk native vlan 10" in result.commands' + - '"switchport trunk allowed vlan 2,4,15" in result.commands' + - result.commands|length == 3 + + - name: Merge layer 2 interfaces configuration (idempotent) + register: result + cisco.nxos.nxos_l2_interfaces: *mergedl2 + + - ansible.builtin.assert: + that: + - result.changed == False + + - name: Merge layer 3 interfaces configuration + register: result + cisco.nxos.nxos_l3_interfaces: &mergedl3 + config: + - name: "{{ nxos_int2 }}" + ipv4: + - address: 203.0.113.1/24 + state: merged + + - ansible.builtin.assert: + that: + - '"interface {{ nxos_int2 }}" in result.commands' + - '"ip address 203.0.113.1/24" in result.commands' + - result.commands|length == 2 + + - name: Merge layer 3 interfaces configuration (idempotent) + register: result + cisco.nxos.nxos_l3_interfaces: *mergedl3 + + - ansible.builtin.assert: + that: + - result.changed == False + + always: + - name: Cleanup + cisco.nxos.nxos_config: *rem + when: ansible_connection == "ansible.netcommon.network_cli" and ansible_network_single_user_mode|d(False) diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_smoke/tests/common/common_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_smoke/tests/common/common_config.yaml new file mode 100644 index 00000000..29c9ea8c --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_smoke/tests/common/common_config.yaml @@ -0,0 +1,103 @@ +--- +# nxos_config -> NetworkConfig, dumps +# nxos_static_route -> CustomNetworkConfig + +# hit NetworkConfig +# Select interface for test +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} common/common_config.yaml + +- name: Set a fact for 'intname' + ansible.builtin.set_fact: + intname: "{{ nxos_int1 }}" + +- name: Setup + cisco.nxos.nxos_config: + commands: + - no description + - no shutdown + parents: + - "interface {{ intname }}" + match: none + +- name: Collect any backup files + ansible.builtin.find: &backups + paths: "{{ role_path }}/backup" + pattern: "{{ inventory_hostname_short }}_config*" + connection: local + register: backup_files + +- name: Delete backup files + ansible.builtin.file: + path: "{{ item.path }}" + state: absent + with_items: "{{backup_files.files|default([])}}" + +- name: Configure device with configuration + cisco.nxos.nxos_config: + commands: + - description this is a test + - shutdown + parents: + - "interface {{ intname }}" + backup: true + register: result + +- ansible.builtin.assert: + that: + - "result.changed == true" + - "result.updates is defined" + +- name: Collect any backup files + ansible.builtin.find: *backups + connection: local + register: backup_files + +- ansible.builtin.assert: + that: + - "backup_files.files is defined" + +# hit block/sublevel sections +- name: Setup + cisco.nxos.nxos_config: &clear + lines: no ip access-list test + match: none + ignore_errors: true + +# hit NetworkConfig._diff_exact +- name: Configure sub level command using block replace - exact + cisco.nxos.nxos_config: + lines: + - 10 permit ip 192.0.2.1/32 any log + - 20 permit ip 192.0.2.2/32 any log + - 30 permit ip 192.0.2.3/32 any log + - 40 permit ip 192.0.2.4/32 any log + parents: ip access-list test + replace: block + match: exact + register: result + +- ansible.builtin.assert: + that: + - "result.changed == true" + - "'ip access-list test' in result.updates" + - "'10 permit ip 192.0.2.1/32 any log' in result.updates" + - "'20 permit ip 192.0.2.2/32 any log' in result.updates" + - "'30 permit ip 192.0.2.3/32 any log' in result.updates" + - "'40 permit ip 192.0.2.4/32 any log' in result.updates" + +# hit NetworkConfig._diff_strict +- name: Configure sub level command using block replace strict + cisco.nxos.nxos_config: + lines: + - 10 permit ip 192.0.2.1/32 any log + - 20 permit ip 192.0.2.2/32 any log + - 30 permit ip 192.0.2.3/32 any log + - 40 permit ip 192.0.2.4/32 any log + parents: ip access-list test + replace: block + match: strict + register: result + +- name: Teardown + nxos_config: *clear diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_smoke/tests/common/common_utils.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_smoke/tests/common/common_utils.yaml new file mode 100644 index 00000000..9472c65c --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_smoke/tests/common/common_utils.yaml @@ -0,0 +1,57 @@ +--- +# nxos_command -> ComplexList +# nxos_config -> to_list + +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} common/common_utils.yaml + +# hit ComplexList +- name: Test contains operator + cisco.nxos.nxos_command: + commands: + - show version + +# hit to_list() +- name: Setup + cisco.nxos.nxos_config: + lines: hostname switch + match: none + +- name: Configure top level command + cisco.nxos.nxos_config: + lines: hostname foo + register: result + +- ansible.builtin.assert: + that: + - "result.changed == true" + - "'hostname foo' in result.updates" + +- name: Setup + cisco.nxos.nxos_config: + lines: hostname switch + match: none + +# hit conditional() +- name: Set a fact for 'testint1' + ansible.builtin.set_fact: + testint1: "{{ nxos_int1 }}" +- name: Set a fact for 'testint2' + ansible.builtin.set_fact: + testint2: "{{ nxos_int2 }}" + +- name: "Setup: put interfaces into a default state" + cisco.nxos.nxos_config: + lines: + - "default interface {{ testint1 }}" + - "default interface {{ testint2 }}" + ignore_errors: true + + register: result + +- name: "Teardown: put interfaces into a default state" + cisco.nxos.nxos_config: + lines: + - "default interface {{ testint1 }}" + - "default interface {{ testint2 }}" + ignore_errors: true diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_smoke/tests/common/misc_tests.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_smoke/tests/common/misc_tests.yaml new file mode 100644 index 00000000..d1f2c441 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_smoke/tests/common/misc_tests.yaml @@ -0,0 +1,27 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} common/misc_tests.yaml + +- name: Hit conditional for lists of 10 or more commands + cisco.nxos.nxos_command: + commands: + - show hostname + - show hostname + - show hostname + - show hostname + - show hostname + - show hostname + - show hostname + - show hostname + - show hostname + - show hostname + register: result + +- ansible.builtin.assert: + that: + - result.stdout|length == 10 + +- name: Combine with provider + cisco.nxos.nxos_command: + commands: + - show hostname diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snapshot/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snapshot/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snapshot/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snapshot/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snapshot/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snapshot/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snapshot/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snapshot/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snapshot/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snapshot/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snapshot/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snapshot/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snapshot/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snapshot/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snapshot/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snapshot/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snapshot/tests/common/sanity.yaml new file mode 100644 index 00000000..7def1590 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snapshot/tests/common/sanity.yaml @@ -0,0 +1,138 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_snapshot sanity test + +- name: Set a fact for 'snapshot_run' + ansible.builtin.set_fact: + snapshot_run: true + +- name: Set a fact for 'snapshot_run' + ansible.builtin.set_fact: + snapshot_run: false + when: titanium and (ansible_connection is match('nxapi')) + +- name: Set a fact for 'snapshot_run' + ansible.builtin.set_fact: + snapshot_run: false + when: platform is match('N35') + +- name: Set a fact for 'add_sec' + ansible.builtin.set_fact: + add_sec: true + +- name: Set a fact for 'add_sec' + ansible.builtin.set_fact: + add_sec: false + when: imagetag is search("D1") + +- block: + - name: Create snapshot + register: result + cisco.nxos.nxos_snapshot: &id001 + action: create + snapshot_name: test_snapshot1 + description: Ansible + save_snapshot_locally: true + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Configure idempotence + register: result + cisco.nxos.nxos_snapshot: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - block: + - name: Add section + register: result + cisco.nxos.nxos_snapshot: &id003 + action: add + section: myshow + show_command: show ip interface brief + row_id: ROW_intf + element_key1: intf-name + element_key2: intf-name + + - assert: *id002 + + - name: Conf Idempotence + register: result + cisco.nxos.nxos_snapshot: *id003 + + - assert: *id004 + when: add_sec + + - name: Create another snapshot + register: result + cisco.nxos.nxos_snapshot: &id005 + action: create + snapshot_name: test_snapshot2 + description: row + section: myshow + show_command: show ip interface brief + row_id: ROW_intf + element_key1: intf-name + + - ansible.builtin.assert: *id002 + + - name: Configure idempotence + register: result + cisco.nxos.nxos_snapshot: *id005 + + - ansible.builtin.assert: *id004 + + - name: Compare snapshots + cisco.nxos.nxos_snapshot: + action: compare + snapshot1: test_snapshot1 + snapshot2: test_snapshot2 + comparison_results_file: compare_snapshots.txt + compare_option: summary + path: . + + - name: Delete snapshot + register: result + cisco.nxos.nxos_snapshot: &id006 + snapshot_name: test_snapshot2 + action: delete + + - ansible.builtin.assert: *id002 + + - name: Configure idempotence + register: result + cisco.nxos.nxos_snapshot: *id006 + + - ansible.builtin.assert: *id004 + + - name: Delete all snapshots + register: result + cisco.nxos.nxos_snapshot: &id007 + action: delete_all + + - ansible.builtin.assert: *id002 + + - name: Configure idempotence + register: result + cisco.nxos.nxos_snapshot: *id007 + + - ansible.builtin.assert: *id004 + when: snapshot_run + always: + - name: Delete all sections + ignore_errors: true + cisco.nxos.nxos_config: + commands: + - snapshot section delete myshow + match: none + + - name: Delete all snapshots + ignore_errors: true + cisco.nxos.nxos_snapshot: + action: delete_all + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_snapshot sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_community/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_community/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_community/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_community/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_community/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_community/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_community/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_community/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_community/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_community/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_community/tasks/main.yaml new file mode 100644 index 00000000..c9e70304 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_community/tasks/main.yaml @@ -0,0 +1,12 @@ +--- +- name: Run the CLI and NX-API tests + block: + - name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + always: + - name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_community/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_community/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_community/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_community/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_community/tests/common/sanity.yaml new file mode 100644 index 00000000..c83ec617 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_community/tests/common/sanity.yaml @@ -0,0 +1,161 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_snmp_community sanity test + +- name: Setup - remove snmp_community if configured - 1 + ignore_errors: true + cisco.nxos.nxos_snmp_community: &id005 + community: TESTING7 + group: network-operator + state: absent + +- name: Setup - remove snmp_community if configured - 2 + ignore_errors: true + cisco.nxos.nxos_snmp_community: &id010 + community: TEST + group: network-operator + state: absent + +- block: + - name: Configure snmp_community group + register: result + cisco.nxos.nxos_snmp_community: &id001 + community: TESTING7 + group: network-operator + state: present + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Idempotence check + register: result + cisco.nxos.nxos_snmp_community: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Change snmp_community group + register: result + cisco.nxos.nxos_snmp_community: &id003 + community: TESTING7 + group: network-admin + state: present + + - ansible.builtin.assert: *id002 + + - name: Idempotence check + register: result + cisco.nxos.nxos_snmp_community: *id003 + + - ansible.builtin.assert: *id004 + + - name: Remove snmp_community + register: result + cisco.nxos.nxos_snmp_community: *id005 + + - ansible.builtin.assert: *id002 + + - name: Idempotence check + register: result + cisco.nxos.nxos_snmp_community: *id005 + + - ansible.builtin.assert: *id004 + + - name: Configure snmp_community access read-only + register: result + cisco.nxos.nxos_snmp_community: &id006 + community: TESTING7 + access: ro + state: present + + - ansible.builtin.assert: *id002 + + - name: Idempotence check + register: result + cisco.nxos.nxos_snmp_community: *id006 + + - ansible.builtin.assert: *id004 + + - name: Remove snmp_community + register: result + cisco.nxos.nxos_snmp_community: *id005 + + - ansible.builtin.assert: *id002 + + - name: Idempotence check + register: result + cisco.nxos.nxos_snmp_community: *id005 + + - ansible.builtin.assert: *id004 + + - name: Configure snmp_community access read-write + register: result + cisco.nxos.nxos_snmp_community: &id007 + community: TESTING7 + access: rw + acl: ansible_acl + state: present + + - ansible.builtin.assert: *id002 + + - name: Idempotence check + register: result + cisco.nxos.nxos_snmp_community: *id007 + + - ansible.builtin.assert: *id004 + + - name: Change ACL + register: result + cisco.nxos.nxos_snmp_community: &id008 + community: TESTING7 + access: rw + acl: new_acl + state: present + + - ansible.builtin.assert: *id002 + + - name: Idempotence check + register: result + cisco.nxos.nxos_snmp_community: *id008 + + - ansible.builtin.assert: *id004 + + - name: Remove ACL + register: result + cisco.nxos.nxos_snmp_community: &id009 + community: TESTING7 + access: rw + acl: default + state: present + + - ansible.builtin.assert: *id002 + + - name: Idempotence check + register: result + cisco.nxos.nxos_snmp_community: *id009 + + - ansible.builtin.assert: *id004 + + - name: Add partial match community + register: result + cisco.nxos.nxos_snmp_community: + community: TEST + access: rw + acl: default + state: present + + - ansible.builtin.assert: + that: + - result.changed == True + - "'snmp-server community TEST group network-admin' in result.commands" + always: + - name: Cleanup + cisco.nxos.nxos_snmp_community: *id005 + + - name: Cleanup + cisco.nxos.nxos_snmp_community: *id010 + + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_snmp_community sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_contact/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_contact/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_contact/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_contact/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_contact/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_contact/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_contact/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_contact/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_contact/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_contact/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_contact/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_contact/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_contact/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_contact/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_contact/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_contact/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_contact/tests/common/sanity.yaml new file mode 100644 index 00000000..a5757c89 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_contact/tests/common/sanity.yaml @@ -0,0 +1,59 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_snmp_community sanity test + +- name: Setup - remove snmp_contact if configured + cisco.nxos.nxos_snmp_contact: &id005 + contact: Test + state: absent + +- block: + - name: Configure SNMP contact + register: result + cisco.nxos.nxos_snmp_contact: &id001 + contact: Testing + state: present + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Idempotence check + register: result + cisco.nxos.nxos_snmp_contact: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Change SNMP contact + register: result + cisco.nxos.nxos_snmp_contact: &id003 + contact: Test + state: present + + - ansible.builtin.assert: *id002 + + - name: Idempotence check + register: result + cisco.nxos.nxos_snmp_contact: *id003 + + - ansible.builtin.assert: *id004 + + - name: Remove SNMP contact + register: result + cisco.nxos.nxos_snmp_contact: *id005 + + - ansible.builtin.assert: *id002 + + - name: Idempotence check + register: result + cisco.nxos.nxos_snmp_contact: *id005 + + - ansible.builtin.assert: *id004 + always: + - name: Cleanup + cisco.nxos.nxos_snmp_contact: *id005 + + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_snmp_community sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_host/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_host/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_host/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_host/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_host/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_host/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_host/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_host/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_host/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_host/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_host/tasks/main.yaml new file mode 100644 index 00000000..c9e70304 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_host/tasks/main.yaml @@ -0,0 +1,12 @@ +--- +- name: Run the CLI and NX-API tests + block: + - name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + always: + - name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_host/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_host/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_host/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_host/tests/common/sanity_snmp_v1_trap.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_host/tests/common/sanity_snmp_v1_trap.yaml new file mode 100644 index 00000000..f0420f99 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_host/tests/common/sanity_snmp_v1_trap.yaml @@ -0,0 +1,127 @@ +--- +- name: Set a fact for 'snmp_type' + ansible.builtin.set_fact: + snmp_type: trap + +- name: Set a fact for 'snmp_version' + ansible.builtin.set_fact: + snmp_version: v1 + +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_snmp_host {{ snmp_type }} {{ snmp_version }} sanity test + +- name: Set a fact for 'intname' + ansible.builtin.set_fact: + intname: "{{ nxos_int1 }}" + when: platform is not search('N5K|N6K') + +- name: Setup - remove snmp_host if configured + ignore_errors: true + cisco.nxos.nxos_snmp_host: &id007 + snmp_host: 192.0.2.3 + community: TESTING + version: "{{ snmp_version }}" + snmp_type: "{{ snmp_type }}" + vrf: management + vrf_filter: management + src_intf: "{{ intname|default(omit) }}" + udp: 222 + state: absent + +- block: + - name: Configure SNMP host + register: result + cisco.nxos.nxos_snmp_host: &id001 + snmp_host: 192.0.2.3 + community: TESTING + version: "{{ snmp_version }}" + snmp_type: "{{ snmp_type }}" + vrf: management + vrf_filter: management + src_intf: "{{ intname|default(omit) }}" + udp: 222 + state: present + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Idempotence check + register: result + cisco.nxos.nxos_snmp_host: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - block: + - name: Add another vrf to filter + register: result + cisco.nxos.nxos_snmp_host: &id003 + snmp_host: 192.0.2.3 + vrf_filter: default + udp: 222 + state: present + + - assert: *id002 + + - name: Idempotence Check + register: result + cisco.nxos.nxos_snmp_host: *id003 + + - assert: *id004 + when: platform is not search('N35|N5K|N6K') + + - name: Remove some configuration + register: result + cisco.nxos.nxos_snmp_host: &id005 + snmp_host: 192.0.2.3 + udp: 222 + src_intf: "{{ intname|default(omit) }}" + vrf: management + vrf_filter: management + state: absent + + - ansible.builtin.assert: *id002 + + - name: Idempotence check + register: result + cisco.nxos.nxos_snmp_host: *id005 + + - ansible.builtin.assert: *id004 + + - block: + - name: remove some more configuration + register: result + cisco.nxos.nxos_snmp_host: &id006 + snmp_host: 192.0.2.3 + udp: 222 + vrf_filter: default + state: absent + + - assert: *id002 + + - name: Idempotence Check + register: result + cisco.nxos.nxos_snmp_host: *id006 + + - assert: *id004 + when: platform is not search('N35|N5K|N6K') + + - name: Cleanup + register: result + cisco.nxos.nxos_snmp_host: *id007 + + - ansible.builtin.assert: *id002 + + - name: Cleanup idempotence + register: result + cisco.nxos.nxos_snmp_host: *id007 + + - ansible.builtin.assert: *id004 + always: + - name: Cleanup + cisco.nxos.nxos_snmp_host: *id007 + + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_snmp_host {{ snmp_type }} {{ snmp_version }} sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_host/tests/common/sanity_snmp_v2_inform.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_host/tests/common/sanity_snmp_v2_inform.yaml new file mode 100644 index 00000000..664bea9e --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_host/tests/common/sanity_snmp_v2_inform.yaml @@ -0,0 +1,127 @@ +--- +- name: Set a fact for 'snmp_type' + ansible.builtin.set_fact: + snmp_type: inform + +- name: Set a fact for 'snmp_version' + ansible.builtin.set_fact: + snmp_version: v2c + +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_snmp_host {{ snmp_type }} {{ snmp_version }} sanity test + +- name: Set a fact for 'intname' + ansible.builtin.set_fact: + intname: "{{ nxos_int1 }}" + when: platform is not search('N5K|N6K') + +- name: Setup - remove snmp_host if configured + ignore_errors: true + cisco.nxos.nxos_snmp_host: &id007 + snmp_host: 192.0.2.3 + community: TESTING + version: "{{ snmp_version }}" + snmp_type: "{{ snmp_type }}" + vrf: management + vrf_filter: management + src_intf: "{{ intname|default(omit) }}" + udp: 222 + state: absent + +- block: + - name: Configure SNMP host + register: result + cisco.nxos.nxos_snmp_host: &id001 + snmp_host: 192.0.2.3 + community: TESTING + version: "{{ snmp_version }}" + snmp_type: "{{ snmp_type }}" + vrf: management + vrf_filter: management + src_intf: "{{ intname|default(omit) }}" + udp: 222 + state: present + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Idempotence check + register: result + cisco.nxos.nxos_snmp_host: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - block: + - name: Add another vrf to filter + register: result + cisco.nxos.nxos_snmp_host: &id003 + snmp_host: 192.0.2.3 + vrf_filter: default + udp: 222 + state: present + + - assert: *id002 + + - name: Idempotence Check + register: result + cisco.nxos.nxos_snmp_host: *id003 + + - assert: *id004 + when: platform is not search('N35|N5K|N6K') + + - name: Remove some configuration + register: result + cisco.nxos.nxos_snmp_host: &id005 + snmp_host: 192.0.2.3 + udp: 222 + src_intf: "{{ intname|default(omit) }}" + vrf: management + vrf_filter: management + state: absent + + - ansible.builtin.assert: *id002 + + - name: Idempotence check + register: result + cisco.nxos.nxos_snmp_host: *id005 + + - ansible.builtin.assert: *id004 + + - block: + - name: remove some more configuration + register: result + cisco.nxos.nxos_snmp_host: &id006 + snmp_host: 192.0.2.3 + udp: 222 + vrf_filter: default + state: absent + + - assert: *id002 + + - name: Idempotence Check + register: result + cisco.nxos.nxos_snmp_host: *id006 + + - assert: *id004 + when: platform is not search('N35|N5K|N6K') + + - name: Cleanup + register: result + cisco.nxos.nxos_snmp_host: *id007 + + - ansible.builtin.assert: *id002 + + - name: Cleanup idempotence + register: result + cisco.nxos.nxos_snmp_host: *id007 + + - ansible.builtin.assert: *id004 + always: + - name: Cleanup + cisco.nxos.nxos_snmp_host: *id007 + + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_snmp_host {{ snmp_type }} {{ snmp_version }} sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_host/tests/common/sanity_snmp_v3_inform.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_host/tests/common/sanity_snmp_v3_inform.yaml new file mode 100644 index 00000000..03dcbd33 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_host/tests/common/sanity_snmp_v3_inform.yaml @@ -0,0 +1,139 @@ +--- +- name: Set a fact for 'snmp_type' + ansible.builtin.set_fact: + snmp_type: inform + +- name: Set a fact for 'snmp_version' + ansible.builtin.set_fact: + snmp_version: v3 + +- name: Set a fact for 'snmp_auth' + ansible.builtin.set_fact: + snmp_auth: priv + +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_snmp_host {{ snmp_type }} {{ snmp_version }} sanity test + +- name: Set a fact for 'intname' + ansible.builtin.set_fact: + intname: "{{ nxos_int1 }}" + when: platform is not search('N5K|N6K') + +- name: Set a fact for 'run' + ansible.builtin.set_fact: + run: true + +- name: Set a fact for 'run' + ansible.builtin.set_fact: + run: false + when: platform is match('N35') + +- name: Setup - remove snmp_host if configured + ignore_errors: true + cisco.nxos.nxos_snmp_host: &id007 + snmp_host: 192.0.2.3 + community: TESTING + version: "{{ snmp_version }}" + snmp_type: "{{ snmp_type }}" + v3: "{{ snmp_auth }}" + vrf: management + vrf_filter: management + src_intf: "{{ intname|default(omit) }}" + state: absent + +- block: + - name: Configure SNMP host + register: result + cisco.nxos.nxos_snmp_host: &id001 + snmp_host: 192.0.2.3 + community: TESTING + v3: "{{ snmp_auth|default(omit) }}" + version: "{{ snmp_version }}" + snmp_type: "{{ snmp_type }}" + vrf: management + vrf_filter: management + src_intf: "{{ intname|default(omit) }}" + state: present + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Idempotence check + register: result + cisco.nxos.nxos_snmp_host: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - block: + - name: Add another vrf to filter + register: result + cisco.nxos.nxos_snmp_host: &id003 + snmp_host: 192.0.2.3 + vrf_filter: default + state: present + + - assert: *id002 + + - name: Idempotence Check + register: result + cisco.nxos.nxos_snmp_host: *id003 + + - assert: *id004 + when: platform is not search('N35|N5K|N6K') + + - name: Remove some configuration + register: result + cisco.nxos.nxos_snmp_host: &id005 + snmp_host: 192.0.2.3 + src_intf: "{{ intname|default(omit) }}" + vrf: management + vrf_filter: management + state: absent + + - ansible.builtin.assert: *id002 + + - name: Idempotence check + register: result + cisco.nxos.nxos_snmp_host: *id005 + + - ansible.builtin.assert: *id004 + + - block: + - name: remove some more configuration + register: result + cisco.nxos.nxos_snmp_host: &id006 + snmp_host: 192.0.2.3 + vrf_filter: default + state: absent + + - assert: *id002 + + - name: Idempotence Check + register: result + cisco.nxos.nxos_snmp_host: *id006 + + - assert: *id004 + when: platform is not search('N35|N5K|N6K') + + - name: Cleanup + register: result + cisco.nxos.nxos_snmp_host: *id007 + + - ansible.builtin.assert: *id002 + + - name: Cleanup idempotence + register: result + cisco.nxos.nxos_snmp_host: *id007 + + - ansible.builtin.assert: *id004 + when: run + always: + - name: Cleanup + register: result + cisco.nxos.nxos_snmp_host: *id007 + + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_snmp_host {{ snmp_type }} {{ snmp_version }} sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_host/tests/common/sanity_snmp_v3_trap.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_host/tests/common/sanity_snmp_v3_trap.yaml new file mode 100644 index 00000000..a77318d3 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_host/tests/common/sanity_snmp_v3_trap.yaml @@ -0,0 +1,134 @@ +--- +- name: Set a fact for 'snmp_type' + ansible.builtin.set_fact: + snmp_type: trap + +- name: Set a fact for 'snmp_version' + ansible.builtin.set_fact: + snmp_version: v3 + +- name: Set a fact for 'snmp_auth' + ansible.builtin.set_fact: + snmp_auth: priv + +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_snmp_host {{ snmp_type }} {{ snmp_version }} sanity test + +- name: Set a fact for 'intname' + ansible.builtin.set_fact: + intname: "{{ nxos_int1 }}" + when: platform is not search('N5K|N6K') + +- name: Setup - remove snmp_host if configured + ignore_errors: true + cisco.nxos.nxos_snmp_host: &id007 + snmp_host: 192.0.2.3 + community: TESTING + udp: 222 + v3: "{{ snmp_auth|default(omit) }}" + version: "{{ snmp_version }}" + snmp_type: "{{ snmp_type }}" + vrf: management + vrf_filter: management + src_intf: "{{ intname|default(omit) }}" + state: absent + +- block: + - name: Configure SNMP host + register: result + cisco.nxos.nxos_snmp_host: &id001 + snmp_host: 192.0.2.3 + community: TESTING + udp: 222 + v3: "{{ snmp_auth|default(omit) }}" + version: "{{ snmp_version }}" + snmp_type: "{{ snmp_type }}" + vrf: management + vrf_filter: management + src_intf: "{{ intname|default(omit) }}" + state: present + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Idempotence check + register: result + cisco.nxos.nxos_snmp_host: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - block: + - name: Add another vrf to filter + register: result + cisco.nxos.nxos_snmp_host: &id003 + snmp_host: 192.0.2.3 + udp: 222 + vrf_filter: default + state: present + + - assert: *id002 + + - name: Idempotence Check + register: result + cisco.nxos.nxos_snmp_host: *id003 + + - assert: *id004 + when: platform is not search('N35|N5K|N6K') + + - name: Remove some configuration + register: result + cisco.nxos.nxos_snmp_host: &id005 + snmp_host: 192.0.2.3 + udp: 222 + src_intf: "{{ intname|default(omit) }}" + vrf: management + vrf_filter: management + state: absent + + - ansible.builtin.assert: *id002 + + - name: Idempotence check + register: result + cisco.nxos.nxos_snmp_host: *id005 + + - ansible.builtin.assert: *id004 + + - block: + - name: remove some more configuration + register: result + cisco.nxos.nxos_snmp_host: &id006 + snmp_host: 192.0.2.3 + udp: 222 + vrf_filter: default + state: absent + + - assert: *id002 + + - name: Idempotence Check + register: result + cisco.nxos.nxos_snmp_host: *id006 + + - assert: *id004 + when: platform is not search('N35|N5K|N6K') + + - name: Cleanup + register: result + cisco.nxos.nxos_snmp_host: *id007 + + - ansible.builtin.assert: *id002 + + - name: Cleanup idempotence + register: result + cisco.nxos.nxos_snmp_host: *id007 + + - ansible.builtin.assert: *id004 + always: + - name: Cleanup + register: result + cisco.nxos.nxos_snmp_host: *id007 + + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_snmp_host {{ snmp_type }} {{ snmp_version }} sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_location/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_location/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_location/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_location/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_location/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_location/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_location/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_location/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_location/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_location/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_location/tasks/main.yaml new file mode 100644 index 00000000..c9e70304 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_location/tasks/main.yaml @@ -0,0 +1,12 @@ +--- +- name: Run the CLI and NX-API tests + block: + - name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + always: + - name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_location/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_location/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_location/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_location/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_location/tests/common/sanity.yaml new file mode 100644 index 00000000..4e8ecf0b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_location/tests/common/sanity.yaml @@ -0,0 +1,60 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_snmp_location sanity test + +- name: Setup - remove snmp_location if configured + cisco.nxos.nxos_snmp_location: &id005 + location: Test + state: absent + +- block: + - name: Configure SNMP location + register: result + cisco.nxos.nxos_snmp_location: &id001 + location: Testing + state: present + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Idempotence check + register: result + cisco.nxos.nxos_snmp_location: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Change SNMP location + register: result + cisco.nxos.nxos_snmp_location: &id003 + location: Test + state: present + + - ansible.builtin.assert: *id002 + + - name: Idempotence check + register: result + cisco.nxos.nxos_snmp_location: *id003 + + - ansible.builtin.assert: *id004 + + - name: Remove SNMP location + register: result + cisco.nxos.nxos_snmp_location: *id005 + + - ansible.builtin.assert: *id002 + + - name: Remove idempotence + register: result + cisco.nxos.nxos_snmp_location: *id005 + + - ansible.builtin.assert: *id004 + always: + - name: Cleanup + register: result + cisco.nxos.nxos_snmp_location: *id005 + + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_snmp_location sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/defaults/main.yaml new file mode 100644 index 00000000..871ea460 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "[^_].*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tasks/cli.yaml new file mode 100644 index 00000000..9e4fb34b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tasks/main.yaml new file mode 100644 index 00000000..cb885dee --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tasks/main.yaml @@ -0,0 +1,49 @@ +--- +- name: Get admin user SNMP data + cisco.nxos.nxos_command: + commands: show running | section '^snmp-server user' + register: result + +- name: Grep admin user SNMP localized key + ansible.builtin.set_fact: + # noqa var-spacing + admin_snmp_passwd: "{{ result['stdout'][0] | regex_search('snmp-server user admin network-admin auth (md5|sha|sha-256) (\\S+)', '\\2') }}" + +- name: Find admin user SNMP localized key + ansible.builtin.set_fact: + admin_snmp_passwd: "{{ admin_snmp_passwd[0] }}" + +- name: Grep admin user SNMP localized key (second) + ansible.builtin.set_fact: + admin_snmp_passwd_2: "{{ result['stdout'][0] | regex_search('snmp-server user admin auth (md5|sha|sha-256) (\\S+)', '\\2') }}" # noqa var-spacing + +- name: Find admin user SNMP localized key (second) + ansible.builtin.set_fact: + admin_snmp_passwd_2: "{{ admin_snmp_passwd_2[0] }}" + +- name: Grep admin user SNMP engineid (second) + ansible.builtin.set_fact: + # noqa var-spacing + admin_snmp_engineid_2: "{{ result['stdout'][0] | regex_search('admin auth (md5|sha|sha-256) (\\S+) priv (\\S+) localizedkey engineID (\\S+)', '\\4') }}" + +- name: Find admin user SNMP engineid (second) + ansible.builtin.set_fact: + admin_snmp_engineid_2: "{{ admin_snmp_engineid_2[0] }}" + +- name: Grep zuul user SNMP localized key + ansible.builtin.set_fact: + zuul_snmp_passwd: "{{ result['stdout'][0] | regex_search('zuul network-admin auth (md5|sha) (\\S+)', '\\2') }}" + +- name: Find zuul user SNMP localized key + ansible.builtin.set_fact: + zuul_snmp_passwd: "{{ zuul_snmp_passwd[0] }}" + +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli.yaml + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tasks/nxapi.yaml new file mode 100644 index 00000000..5cb76e67 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tests/common/_populate_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tests/common/_populate_config.yaml new file mode 100644 index 00000000..08cf504a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tests/common/_populate_config.yaml @@ -0,0 +1,18 @@ +--- +- name: Populate configuration + cisco.nxos.nxos_config: + lines: + - snmp-server contact nxosswitchadmin@localhost + - snmp-server location serverroom-1 + - snmp-server aaa-user cache-timeout 36000 + - snmp-server user snmp_user_1 network-operator auth md5 0x5632724fb8ac3699296af26281e1d0f1 localizedkey + - snmp-server user snmp_user_2 network-operator auth md5 0x5632724fb8ac3699296af26281e1d0f1 priv aes-128 0x5632724fb8ac3699296af26281e1d0f1 localizedkey + - snmp-server user snmp_user_1 use-ipv4acl acl1 use-ipv6acl acl2 + - snmp-server user snmp_user_2 use-ipv4acl acl3 use-ipv6acl acl4 + - snmp-server host 192.0.2.1 traps version 1 public + - snmp-server host 192.0.2.1 source-interface Ethernet1/1 + - snmp-server host 192.0.2.2 informs version 3 auth NMS + - snmp-server community private group network-admin + - snmp-server community public group network-operator + - snmp-server enable traps aaa server-state-change + - snmp-server enable traps system Clock-change-notification diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tests/common/_remove_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tests/common/_remove_config.yaml new file mode 100644 index 00000000..ce86eaec --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tests/common/_remove_config.yaml @@ -0,0 +1,23 @@ +--- +- name: Remove snmp-server + cisco.nxos.nxos_config: + lines: + - no snmp-server contact nxosswitchadmin@localhost + - no snmp-server contact nxosswitchadmin2@localhost + - no snmp-server location serverroom-1 + - no snmp-server location serverroom-2 + - no snmp-server aaa-user cache-timeout 36000 + - no snmp-server user snmp_user_1 network-operator auth md5 0x5632724fb8ac3699296af26281e1d0f1 localizedkey + - no snmp-server user snmp_user_2 network-admin auth md5 0x5632724fb8ac3699296af26281e1d0f1 priv aes-128 0x5632724fb8ac3699296af26281e1d0f1 localizedkey + - no snmp-server user snmp_user_1 + - no snmp-server user snmp_user_2 + - no snmp-server community private group network-admin + - no snmp-server community public group network-operator + - no snmp-server community secret group network-operator + - no snmp-server enable traps aaa server-state-change + - no snmp-server enable traps system Clock-change-notification + - no snmp-server host 192.0.2.1 traps version 1 public + - no snmp-server host 192.0.2.1 source-interface Ethernet1/1 + - no snmp-server host 192.0.2.2 informs version 3 auth NMS + - no snmp-server host 192.0.3.2 informs version 3 auth NMS + ignore_errors: true diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tests/common/_setup.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tests/common/_setup.yaml new file mode 100644 index 00000000..319398d5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tests/common/_setup.yaml @@ -0,0 +1,12 @@ +--- +- name: "Populate interfaces" + cisco.nxos.nxos_config: + lines: + - "no switchport" + parents: "interface {{ item }}" + loop: + - "{{ nxos_int1 }}" + - "{{ nxos_int2 }}" + - "{{ nxos_int3 }}" + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tests/common/empty_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tests/common/empty_config.yaml new file mode 100644 index 00000000..b83d1f94 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tests/common/empty_config.yaml @@ -0,0 +1,61 @@ +--- +- ansible.builtin.debug: + msg: START nxos_snmp_server empty_config integration tests on connection={{ ansible_connection }} + +- name: Merged with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_snmp_server: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_snmp_server: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Overridden with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_snmp_server: + config: + state: overridden + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Rendered with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_snmp_server: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' + +- name: Parsed with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_snmp_server: + running_config: + state: parsed + +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state parsed' + +- ansible.builtin.debug: + msg: END nxos_snmp_server empty_config integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tests/common/fixtures/parsed.cfg b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tests/common/fixtures/parsed.cfg new file mode 100644 index 00000000..4ed23d38 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tests/common/fixtures/parsed.cfg @@ -0,0 +1,14 @@ +snmp-server contact nxosswitchadmin@localhost +snmp-server location serverroom-1 +snmp-server aaa-user cache-timeout 36000 +snmp-server user snmp_user_1 network-operator auth md5 0x5632724fb8ac3699296af26281e1d0f1 localizedkey +snmp-server user snmp_user_2 network-operator auth md5 0x5632724fb8ac3699296af26281e1d0f1 priv aes-128 0x5632724fb8ac3699296af26281e1d0f1 localizedkey +snmp-server user snmp_user_1 use-ipv4acl acl1 use-ipv6acl acl2 +snmp-server user snmp_user_2 use-ipv4acl acl3 use-ipv6acl acl4 +snmp-server host 192.0.2.1 traps version 1 public +snmp-server host 192.0.2.1 source-interface Ethernet1/1 +snmp-server host 192.0.2.2 informs version 3 auth NMS +snmp-server community private group network-admin +snmp-server community public group network-operator +snmp-server enable traps aaa server-state-change +snmp-server enable traps system Clock-change-notification diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tests/common/gathered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tests/common/gathered.yaml new file mode 100644 index 00000000..e55908b0 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tests/common/gathered.yaml @@ -0,0 +1,21 @@ +--- +- ansible.builtin.debug: + msg: START nxos_snmp_server gathered integration tests on connection={{ ansible_connection}} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Gather snmp-server facts using gathered + register: result + cisco.nxos.nxos_snmp_server: + state: gathered + + - name: Assert that facts were correctly generated + ansible.builtin.assert: + that: + - result["gathered"] == merged["after"] + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tests/common/merged.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tests/common/merged.yaml new file mode 100644 index 00000000..c58152f5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tests/common/merged.yaml @@ -0,0 +1,94 @@ +--- +- ansible.builtin.debug: + msg: "Start nxos_snmp_server merged integration tests connection={{ ansible_connection }}" + +- ansible.builtin.include_tasks: _remove_config.yaml + +- block: + - name: Merge the provided configuration with the existing running configuration + cisco.nxos.nxos_snmp_server: &id001 + config: + aaa_user: + cache_timeout: 36000 + communities: + - name: private + group: network-admin + - name: public + group: network-operator + contact: nxosswitchadmin@localhost + location: serverroom-1 + traps: + aaa: + server_state_change: true + system: + clock_change_notification: true + hosts: + - host: 192.0.2.1 + traps: true + version: "1" + community: public + - host: 192.0.2.1 + source_interface: Ethernet1/1 + - host: 192.0.2.2 + informs: true + version: "3" + auth: NMS + users: + auth: + - user: snmp_user_1 + group: network-operator + authentication: + algorithm: md5 + password: "0x5632724fb8ac3699296af26281e1d0f1" + localized_key: true + - user: snmp_user_2 + group: network-operator + authentication: + algorithm: md5 + password: "0x5632724fb8ac3699296af26281e1d0f1" + localized_key: true + priv: + privacy_password: "0x5632724fb8ac3699296af26281e1d0f1" + aes_128: true + use_acls: + - user: snmp_user_1 + ipv4: acl1 + ipv6: acl2 + - user: snmp_user_2 + ipv4: acl3 + ipv6: acl4 + register: result + + - name: Show before + ansible.builtin.debug: + msg: "{{ merged['before'] }}" + + - name: Show after + ansible.builtin.debug: + msg: "{{ merged['after'] }}" + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: "{{ result['before'] == merged['before'] }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ merged['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ merged['after'] == result['after'] }}" + + - name: Merge the provided configuration with the existing running configuration (idempotent) + cisco.nxos.nxos_snmp_server: *id001 + register: result + + - name: Assert that the previous task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tests/common/overridden.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tests/common/overridden.yaml new file mode 100644 index 00000000..7438475a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tests/common/overridden.yaml @@ -0,0 +1,115 @@ +--- +- ansible.builtin.debug: + msg: "Start nxos_snmp_server overridden integration tests connection={{ ansible_connection }}" + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Override snmp-server configurations of listed snmp-server with provided configurations + cisco.nxos.nxos_snmp_server: &id001 + config: + aaa_user: + cache_timeout: 36000 + communities: + - name: public + group: network-operator + - name: secret + group: network-operator + contact: nxosswitchadmin2@localhost + location: serverroom-2 + traps: + aaa: + server_state_change: true + hosts: + - host: 192.0.2.1 + traps: true + version: "1" + community: public + - host: 192.0.2.1 + source_interface: Ethernet1/1 + - host: 192.0.3.2 + informs: true + version: "3" + auth: NMS + users: + auth: + - user: admin + group: network-admin + authentication: + algorithm: md5 + password: "{{ admin_snmp_passwd }}" + localized_key: true + priv: + privacy_password: "{{ admin_snmp_passwd }}" + + - user: admin + authentication: + algorithm: md5 + engine_id: "{{ admin_snmp_engineid_2 }}" + localized_key: true + password: "{{ admin_snmp_passwd_2 }}" + priv: + privacy_password: "{{ admin_snmp_passwd_2 }}" + + - user: snmp_user_1 + group: network-operator + authentication: + algorithm: md5 + password: "0x5632724fb8ac3699296af26281e1d0f1" + localized_key: true + + - user: snmp_user_2 + group: network-operator + authentication: + algorithm: md5 + password: "0x5632724fb8ac3699296af26281e1d0f1" + localized_key: true + priv: + privacy_password: "0x5632724fb8ac3699296af26281e1d0f1" + aes_128: true + + - authentication: + algorithm: md5 + localized_key: true + password: "{{ zuul_snmp_passwd }}" + priv: + privacy_password: "{{ zuul_snmp_passwd }}" + group: network-admin + user: zuul + + use_acls: + - user: snmp_user_1 + ipv4: acl1 + ipv6: acl2 + state: overridden + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ result['before'] == merged['after'] }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ replaced['after'] == result['after'] }}" + + - name: Override snmp-server configurations of listed snmp-server with provided configurations (idempotent) + register: result + cisco.nxos.nxos_snmp_server: *id001 + + - name: Assert that task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tests/common/parsed.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tests/common/parsed.yaml new file mode 100644 index 00000000..aecccf9b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tests/common/parsed.yaml @@ -0,0 +1,14 @@ +--- +- ansible.builtin.debug: + msg: START nxos_snmp_server parsed integration tests on connection={{ ansible_connection }} + +- name: Parse externally provided snmp-server configuration + register: result + cisco.nxos.nxos_snmp_server: + running_config: "{{ lookup('file', './fixtures/parsed.cfg') }}" + state: parsed + +- name: Assert that configuration was correctly parsed + ansible.builtin.assert: + that: + - "{{ parsed == result['parsed'] }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tests/common/rendered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tests/common/rendered.yaml new file mode 100644 index 00000000..58246602 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tests/common/rendered.yaml @@ -0,0 +1,64 @@ +--- +- ansible.builtin.debug: + msg: START nxos_snmp_server rendered integration tests on connection={{ ansible_connection }} + +- name: Render platform specific configuration lines with state rendered (without connecting to the device) + cisco.nxos.nxos_snmp_server: + config: + aaa_user: + cache_timeout: 36000 + communities: + - name: public + group: network-operator + - name: private + group: network-admin + contact: nxosswitchadmin@localhost + location: serverroom-1 + traps: + aaa: + server_state_change: true + system: + clock_change_notification: true + hosts: + - host: 192.0.2.1 + traps: true + version: "1" + community: public + - host: 192.0.2.1 + source_interface: Ethernet1/1 + - host: 192.0.2.2 + informs: true + version: "3" + auth: NMS + users: + auth: + - user: snmp_user_1 + group: network-operator + authentication: + algorithm: md5 + password: "0x5632724fb8ac3699296af26281e1d0f1" + localized_key: true + - user: snmp_user_2 + group: network-operator + authentication: + algorithm: md5 + password: "0x5632724fb8ac3699296af26281e1d0f1" + localized_key: true + priv: + privacy_password: "0x5632724fb8ac3699296af26281e1d0f1" + aes_128: true + use_acls: + - user: snmp_user_1 + ipv4: acl1 + ipv6: acl2 + - user: snmp_user_2 + ipv4: acl3 + ipv6: acl4 + state: rendered + register: result + +- name: Assert that correct set of commands were rendered + ansible.builtin.assert: + that: + - "{{ merged['commands'] | symmetric_difference(result['rendered']) |length == 0 }}" + - result.changed == False diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tests/common/replaced.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tests/common/replaced.yaml new file mode 100644 index 00000000..590657d9 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/tests/common/replaced.yaml @@ -0,0 +1,115 @@ +--- +- ansible.builtin.debug: + msg: "Start nxos_snmp_server replaced integration tests connection={{ ansible_connection }}" + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Replace snmp-server configurations of listed snmp-server with provided configurations + cisco.nxos.nxos_snmp_server: &id001 + config: + aaa_user: + cache_timeout: 36000 + communities: + - name: public + group: network-operator + - name: secret + group: network-operator + contact: nxosswitchadmin2@localhost + location: serverroom-2 + traps: + aaa: + server_state_change: true + hosts: + - host: 192.0.2.1 + traps: true + version: "1" + community: public + - host: 192.0.2.1 + source_interface: Ethernet1/1 + - host: 192.0.3.2 + informs: true + version: "3" + auth: NMS + users: + auth: + - user: admin + group: network-admin + authentication: + algorithm: md5 + password: "{{ admin_snmp_passwd }}" + localized_key: true + priv: + privacy_password: "{{ admin_snmp_passwd }}" + + - user: admin + authentication: + algorithm: md5 + engine_id: "{{ admin_snmp_engineid_2 }}" + localized_key: true + password: "{{ admin_snmp_passwd_2 }}" + priv: + privacy_password: "{{ admin_snmp_passwd_2 }}" + + - user: snmp_user_1 + group: network-operator + authentication: + algorithm: md5 + password: "0x5632724fb8ac3699296af26281e1d0f1" + localized_key: true + + - user: snmp_user_2 + group: network-operator + authentication: + algorithm: md5 + password: "0x5632724fb8ac3699296af26281e1d0f1" + localized_key: true + priv: + privacy_password: "0x5632724fb8ac3699296af26281e1d0f1" + aes_128: true + + - authentication: + algorithm: md5 + localized_key: true + password: "{{ zuul_snmp_passwd }}" + priv: + privacy_password: "{{ zuul_snmp_passwd }}" + group: network-admin + user: zuul + + use_acls: + - user: snmp_user_1 + ipv4: acl1 + ipv6: acl2 + state: replaced + register: result + + - name: Assert that before dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ result['before'] == merged['after'] }}" + + - name: Assert that correct set of commands were generated + ansible.builtin.assert: + that: + - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dicts were correctly generated + ansible.builtin.assert: + that: + - "{{ replaced['after'] == result['after'] }}" + + - name: Replace snmp-server configurations of listed snmp-server with provided configurations (idempotent) + register: result + cisco.nxos.nxos_snmp_server: *id001 + + - name: Assert that task was idempotent + ansible.builtin.assert: + that: + - result['changed'] == false + - result.commands|length == 0 + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/vars/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/vars/main.yml new file mode 100644 index 00000000..33b13d45 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_server/vars/main.yml @@ -0,0 +1,254 @@ +--- +merged: + before: + users: + auth: + - user: admin + group: network-admin + authentication: + algorithm: md5 + password: "{{ admin_snmp_passwd }}" + localized_key: true + priv: + privacy_password: "{{ admin_snmp_passwd }}" + - authentication: + algorithm: md5 + engine_id: "{{ admin_snmp_engineid_2 }}" + localized_key: true + password: "{{ admin_snmp_passwd_2 }}" + priv: + privacy_password: "{{ admin_snmp_passwd_2 }}" + user: admin + - authentication: + algorithm: md5 + localized_key: true + password: "{{ zuul_snmp_passwd }}" + priv: + privacy_password: "{{ zuul_snmp_passwd }}" + group: network-admin + user: zuul + commands: + - snmp-server contact nxosswitchadmin@localhost + - snmp-server location serverroom-1 + - snmp-server aaa-user cache-timeout 36000 + - snmp-server user snmp_user_1 network-operator auth md5 0x5632724fb8ac3699296af26281e1d0f1 localizedkey + - snmp-server user snmp_user_2 network-operator auth md5 0x5632724fb8ac3699296af26281e1d0f1 priv aes-128 0x5632724fb8ac3699296af26281e1d0f1 localizedkey + - snmp-server user snmp_user_1 use-ipv4acl acl1 use-ipv6acl acl2 + - snmp-server user snmp_user_2 use-ipv4acl acl3 use-ipv6acl acl4 + - snmp-server host 192.0.2.1 traps version 1 public + - snmp-server host 192.0.2.1 source-interface Ethernet1/1 + - snmp-server host 192.0.2.2 informs version 3 auth NMS + - snmp-server community private group network-admin + - snmp-server community public group network-operator + - snmp-server enable traps aaa server-state-change + - snmp-server enable traps system Clock-change-notification + after: + aaa_user: + cache_timeout: 36000 + communities: + - group: network-admin + name: private + - group: network-operator + name: public + contact: nxosswitchadmin@localhost + hosts: + - community: public + host: 192.0.2.1 + traps: true + version: "1" + - host: 192.0.2.1 + source_interface: Ethernet1/1 + - auth: NMS + host: 192.0.2.2 + informs: true + version: "3" + location: serverroom-1 + traps: + aaa: + server_state_change: true + system: + clock_change_notification: true + users: + auth: + - authentication: + algorithm: md5 + localized_key: true + password: "{{ admin_snmp_passwd }}" + priv: + privacy_password: "{{ admin_snmp_passwd }}" + group: network-admin + user: admin + - authentication: + algorithm: md5 + engine_id: "{{ admin_snmp_engineid_2 }}" + localized_key: true + password: "{{ admin_snmp_passwd_2 }}" + priv: + privacy_password: "{{ admin_snmp_passwd_2 }}" + user: admin + - authentication: + algorithm: md5 + localized_key: true + password: "0x5632724fb8ac3699296af26281e1d0f1" + group: network-operator + user: snmp_user_1 + - authentication: + algorithm: md5 + localized_key: true + password: "0x5632724fb8ac3699296af26281e1d0f1" + priv: + aes_128: true + privacy_password: "0x5632724fb8ac3699296af26281e1d0f1" + group: network-operator + user: snmp_user_2 + - authentication: + algorithm: md5 + localized_key: true + password: "{{ zuul_snmp_passwd }}" + priv: + privacy_password: "{{ zuul_snmp_passwd }}" + group: network-admin + user: zuul + use_acls: + - ipv4: acl1 + ipv6: acl2 + user: snmp_user_1 + - ipv4: acl3 + ipv6: acl4 + user: snmp_user_2 + +replaced: + commands: + - snmp-server contact nxosswitchadmin2@localhost + - no snmp-server enable traps system Clock-change-notification + - snmp-server location serverroom-2 + - no snmp-server user snmp_user_2 use-ipv4acl acl3 use-ipv6acl acl4 + - no snmp-server host 192.0.2.2 informs version 3 auth NMS + - snmp-server host 192.0.3.2 informs version 3 auth NMS + - no snmp-server community private group network-admin + - snmp-server community secret group network-operator + after: + aaa_user: + cache_timeout: 36000 + communities: + - name: public + group: network-operator + - name: secret + group: network-operator + contact: nxosswitchadmin2@localhost + location: serverroom-2 + traps: + aaa: + server_state_change: true + hosts: + - host: 192.0.2.1 + traps: true + version: "1" + community: public + - host: 192.0.2.1 + source_interface: Ethernet1/1 + - host: 192.0.3.2 + informs: true + version: "3" + auth: NMS + users: + auth: + - user: admin + group: network-admin + authentication: + algorithm: md5 + password: "{{ admin_snmp_passwd }}" + localized_key: true + priv: + privacy_password: "{{ admin_snmp_passwd }}" + + - user: admin + authentication: + algorithm: md5 + engine_id: "{{ admin_snmp_engineid_2 }}" + localized_key: true + password: "{{ admin_snmp_passwd_2 }}" + priv: + privacy_password: "{{ admin_snmp_passwd_2 }}" + + - user: snmp_user_1 + group: network-operator + authentication: + algorithm: md5 + password: "0x5632724fb8ac3699296af26281e1d0f1" + localized_key: true + + - user: snmp_user_2 + group: network-operator + authentication: + algorithm: md5 + password: "0x5632724fb8ac3699296af26281e1d0f1" + localized_key: true + priv: + privacy_password: "0x5632724fb8ac3699296af26281e1d0f1" + aes_128: true + + - authentication: + algorithm: md5 + localized_key: true + password: "{{ zuul_snmp_passwd }}" + priv: + privacy_password: "{{ zuul_snmp_passwd }}" + group: network-admin + user: zuul + + use_acls: + - user: snmp_user_1 + ipv4: acl1 + ipv6: acl2 + +parsed: + aaa_user: + cache_timeout: 36000 + communities: + - name: private + group: network-admin + - name: public + group: network-operator + contact: nxosswitchadmin@localhost + location: serverroom-1 + traps: + aaa: + server_state_change: true + system: + clock_change_notification: true + hosts: + - host: 192.0.2.1 + traps: true + version: "1" + community: public + - host: 192.0.2.1 + source_interface: Ethernet1/1 + - host: 192.0.2.2 + informs: true + version: "3" + auth: NMS + users: + auth: + - user: snmp_user_1 + group: network-operator + authentication: + algorithm: md5 + password: "0x5632724fb8ac3699296af26281e1d0f1" + localized_key: true + - user: snmp_user_2 + group: network-operator + authentication: + algorithm: md5 + password: "0x5632724fb8ac3699296af26281e1d0f1" + localized_key: true + priv: + privacy_password: "0x5632724fb8ac3699296af26281e1d0f1" + aes_128: true + use_acls: + - user: snmp_user_1 + ipv4: acl1 + ipv6: acl2 + - user: snmp_user_2 + ipv4: acl3 + ipv6: acl4 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_traps/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_traps/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_traps/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_traps/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_traps/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_traps/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_traps/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_traps/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_traps/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_traps/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_traps/tasks/main.yaml new file mode 100644 index 00000000..c9e70304 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_traps/tasks/main.yaml @@ -0,0 +1,12 @@ +--- +- name: Run the CLI and NX-API tests + block: + - name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + always: + - name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_traps/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_traps/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_traps/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_traps/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_traps/tests/common/sanity.yaml new file mode 100644 index 00000000..787d223b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_traps/tests/common/sanity.yaml @@ -0,0 +1,75 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_snmp_traps sanity test + +- name: Setup - remove snmp_traps if configured + cisco.nxos.nxos_snmp_traps: &id006 + group: all + state: disabled + +- block: + - name: Configure one SNMP trap group + register: result + cisco.nxos.nxos_snmp_traps: &id001 + group: bridge + state: enabled + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Idempotence check + register: result + cisco.nxos.nxos_snmp_traps: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Remove SNMP trap group + register: result + cisco.nxos.nxos_snmp_traps: &id003 + group: bridge + state: disabled + + - ansible.builtin.assert: *id002 + + - name: Idempotence check + register: result + cisco.nxos.nxos_snmp_traps: *id003 + + - ansible.builtin.assert: *id004 + + - name: Configure all SNMP trap groups + register: result + cisco.nxos.nxos_snmp_traps: &id005 + group: all + state: enabled + + - ansible.builtin.assert: *id002 + + - block: + - name: Idempotence Check + register: result + cisco.nxos.nxos_snmp_traps: *id005 + + - assert: *id004 + when: imagetag is not search("I2|I7|D1") + + - name: Cleanup + register: result + cisco.nxos.nxos_snmp_traps: *id006 + + - ansible.builtin.assert: *id002 + + - name: Cleanup idempotence + register: result + cisco.nxos.nxos_snmp_traps: *id006 + + - ansible.builtin.assert: *id004 + always: + - name: Cleanup + cisco.nxos.nxos_snmp_traps: *id006 + + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_snmp_traps sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_user/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_user/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_user/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_user/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_user/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_user/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_user/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_user/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_user/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_user/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_user/tasks/main.yaml new file mode 100644 index 00000000..c9e70304 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_user/tasks/main.yaml @@ -0,0 +1,12 @@ +--- +- name: Run the CLI and NX-API tests + block: + - name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + always: + - name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_user/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_user/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_user/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_user/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_user/tests/common/sanity.yaml new file mode 100644 index 00000000..ed6ca2c9 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_snmp_user/tests/common/sanity.yaml @@ -0,0 +1,114 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_snmp_user sanity test + +- name: Set a fact for 'delete_last_user_allowed' + ansible.builtin.set_fact: + delete_last_user_allowed: true + +- name: Set a fact for 'delete_last_user_allowed' + ansible.builtin.set_fact: + delete_last_user_allowed: false + when: imagetag and (major_version is version_compare('9.1', 'ge')) + +- name: Set a fact for 'delete_last_user_allowed' + ansible.builtin.set_fact: + delete_last_user_allowed: false + when: platform is search('N5K|N6K|N9K-F') + +- name: Remove SNMP user + ignore_errors: true + when: platform is not search('N5K|N6K|N9K-F') + cisco.nxos.nxos_snmp_user: &id006 + user: ntc + state: absent + +- name: Remove user workaround + ignore_errors: true + when: platform is search('N5K|N6K|N9K-F') + cisco.nxos.nxos_user: &id007 + name: ntc + state: absent + +- ansible.builtin.pause: + seconds: 5 + +- block: + - name: Create SNMP user + register: result + cisco.nxos.nxos_snmp_user: + user: ntc + group: network-operator + authentication: md5 + pwd: N$tOpe%1 + privacy: HelloU$er1 + encrypt: true + + - ansible.builtin.assert: &id001 + that: + - result.changed == true + + - name: Add another group to user + register: result + cisco.nxos.nxos_snmp_user: &id002 + user: ntc + group: network-admin + + - ansible.builtin.assert: *id001 + + - name: Check idempotence + register: result + cisco.nxos.nxos_snmp_user: *id002 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Remove group from user + register: result + cisco.nxos.nxos_snmp_user: &id003 + user: ntc + group: network-admin + state: absent + + - ansible.builtin.assert: *id001 + + - ansible.builtin.pause: + seconds: 5 + + - name: Check idempotence + register: result + cisco.nxos.nxos_snmp_user: *id003 + + - ansible.builtin.assert: *id004 + + - block: + - name: delete snmp user + register: result + cisco.nxos.nxos_snmp_user: &id005 + user: ntc + group: network-operator + state: absent + + - assert: *id001 + + - pause: + seconds: 5 + + - name: Remove Idempotence + register: result + cisco.nxos.nxos_snmp_user: *id005 + + - assert: *id004 + when: delete_last_user_allowed + always: + - name: Delete SNMP user + when: platform is not search('N5K|N6K|N9K-F') + cisco.nxos.nxos_snmp_user: *id006 + + - name: Remove user workaround + when: platform is search('N5K|N6K|N9K-F') + cisco.nxos.nxos_user: *id007 + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_snmp_user sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/defaults/main.yaml new file mode 100644 index 00000000..871ea460 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "[^_].*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tasks/cli.yaml new file mode 100644 index 00000000..e22d5c62 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yml" + use_regex: true + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tasks/main.yaml new file mode 100644 index 00000000..159ffa2b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tasks/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - "cli" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tests/common/_populate_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tests/common/_populate_config.yaml new file mode 100644 index 00000000..e4de1e60 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tests/common/_populate_config.yaml @@ -0,0 +1,11 @@ +--- +- name: Populate configuration + cisco.nxos.nxos_config: + lines: + - "ip route 192.0.2.16/28 192.0.2.24 name new_route" + - "ip route 192.0.2.80/28 192.0.2.26 tag 12" + - "vrf context trial_vrf" + - " ip route 192.0.2.64/28 192.0.2.22 tag 4" + - " ip route 192.0.2.64/28 192.0.2.23 name merged_route 1" + - "interface {{ nxos_int2 }}" + - " no switchport" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tests/common/_remove_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tests/common/_remove_config.yaml new file mode 100644 index 00000000..dcc3f18a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tests/common/_remove_config.yaml @@ -0,0 +1,15 @@ +--- +- name: Remove configuration + cisco.nxos.nxos_config: + lines: + - "no ip route 192.0.2.16/28 192.0.2.24 name new_route" + - "no ip route 192.0.2.80/28 192.0.2.26 tag 12" + - "no ip route 192.0.2.44/30 192.0.2.55 tag 1 1" + - "no ip route 192.0.2.16/28 192.0.2.23 name replaced_route1 3" + - "no ip route 192.0.2.16/28 {{ nxos_int2 }} 192.0.2.45 vrf destinationVRF name replaced_route2" + - "no ip route 192.0.2.36/30 192.0.2.32 name test_route1 tag 14" + - "no ip route 192.0.2.36/30 192.0.2.48 name test_route2 2" + - "no vrf context trial_vrf" + - "default interface {{ nxos_int2 }}" + ignore_errors: true + # error is thrown if we deleted trial_vrf when it is not present already. ignore_errors circumvents it diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tests/common/deleted.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tests/common/deleted.yml new file mode 100644 index 00000000..67c89cc3 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tests/common/deleted.yml @@ -0,0 +1,81 @@ +--- +- ansible.builtin.debug: + msg: "Start nxos_static_routes deleted integration tests connection = {{ ansible_connection }}" + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Gather static_routes facts + cisco.nxos.nxos_facts: &facts + gather_subset: + - "!all" + - "!min" + gather_network_resources: static_routes + + - name: Delete all routes based on VRF + cisco.nxos.nxos_static_routes: + config: + - vrf: trial_vrf + state: deleted + register: result + + - ansible.builtin.assert: + that: + - "result.changed == true" + - "'vrf context trial_vrf' in result.commands" + - "'no ip route 192.0.2.64/28 192.0.2.22 tag 4' in result.commands" + - "'no ip route 192.0.2.64/28 192.0.2.23 name merged_route 1' in result.commands" + - "result.commands | length == 3" + + - ansible.builtin.include_tasks: _populate_config.yaml + + - name: Delete routes based on AFI in a VRF + cisco.nxos.nxos_static_routes: + config: + - vrf: trial_vrf + address_families: + - afi: ipv4 + state: deleted + register: result + + - ansible.builtin.assert: + that: + - "result.changed == true" + - "'vrf context trial_vrf' in result.commands" + - "'no ip route 192.0.2.64/28 192.0.2.22 tag 4' in result.commands" + - "'no ip route 192.0.2.64/28 192.0.2.23 name merged_route 1' in result.commands" + - "result.commands | length == 3" + + - ansible.builtin.include_tasks: _remove_config.yaml + + - ansible.builtin.include_tasks: _populate_config.yaml + + - name: Deleted (all routes) + cisco.nxos.nxos_static_routes: &deleted + state: deleted + register: result + + - name: Gather static_routes post facts + cisco.nxos.nxos_facts: *facts + + - ansible.builtin.assert: + that: + - "'vrf context trial_vrf' in result.commands" + - "'no ip route 192.0.2.64/28 192.0.2.22 tag 4' in result.commands" + - "'no ip route 192.0.2.64/28 192.0.2.23 name merged_route 1' in result.commands" + - "'configure terminal' in result.commands" + - "'no ip route 192.0.2.16/28 192.0.2.24 name new_route' in result.commands" + - "'no ip route 192.0.2.80/28 192.0.2.26 tag 12' in result.commands" + - "result.changed == true" + - "result.commands | length == 6" + + - name: Idempotence - deleted + cisco.nxos.nxos_static_routes: *deleted + register: result + + - ansible.builtin.assert: + that: + - "result.changed == false" + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tests/common/gathered.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tests/common/gathered.yml new file mode 100644 index 00000000..24c06959 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tests/common/gathered.yml @@ -0,0 +1,34 @@ +--- +- ansible.builtin.debug: + msg: "Start nxos_static_routes gathered tests connection={{ ansible_connection }}" + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Gather static_routes facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: static_routes + + - name: Gathered + cisco.nxos.nxos_static_routes: &gathered + state: gathered + register: result + + - ansible.builtin.assert: + that: + - "result.changed == false" + - "ansible_facts.network_resources.static_routes == result.gathered" + + - name: Idempotence - gathered + cisco.nxos.nxos_static_routes: *gathered + register: result + + - ansible.builtin.assert: + that: + - "result.changed == false" + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tests/common/merged.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tests/common/merged.yml new file mode 100644 index 00000000..6ba0a1b6 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tests/common/merged.yml @@ -0,0 +1,61 @@ +--- +- ansible.builtin.debug: + msg: "Start nxos_static_routes merged integration tests connection={{ansible_connection}}" + +- ansible.builtin.include_tasks: _populate_config.yaml + +- ansible.builtin.include_tasks: _remove_config.yaml + +- block: + - name: Merged + cisco.nxos.nxos_static_routes: &merged + config: + - vrf: trial_vrf + address_families: + - afi: ipv4 + routes: + - dest: 192.0.2.64/28 + next_hops: + - forward_router_address: 192.0.2.22 + tag: 4 + + - forward_router_address: 192.0.2.23 + route_name: merged_route + admin_distance: 1 + + - address_families: + - afi: ipv4 + routes: + - dest: 192.0.2.16/28 + next_hops: + - forward_router_address: 192.0.2.24 + route_name: new_route + + - dest: 192.0.2.80/28 + next_hops: + - forward_router_address: 192.0.2.26 + tag: 12 + state: merged + register: result + + - ansible.builtin.assert: + that: + - "result.changed == true" + - "'configure terminal' in result.commands" + - "'ip route 192.0.2.16/28 192.0.2.24 name new_route' in result.commands" + - "'ip route 192.0.2.80/28 192.0.2.26 tag 12' in result.commands" + - "'vrf context trial_vrf' in result.commands" + - "'ip route 192.0.2.64/28 192.0.2.22 tag 4' in result.commands" + - "'ip route 192.0.2.64/28 192.0.2.23 name merged_route 1' in result.commands" + - "result.commands | length == 6" + + - name: Idempotence - merged + cisco.nxos.nxos_static_routes: *merged + register: result + + - ansible.builtin.assert: + that: + - "result.changed == false" + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tests/common/overridden.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tests/common/overridden.yml new file mode 100644 index 00000000..ae03e947 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tests/common/overridden.yml @@ -0,0 +1,60 @@ +--- +- ansible.builtin.debug: + msg: "Start nxos_static_routes overridden tests connection={{ ansible_connection }}" + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Gather static_routes facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: static_routes + + - name: Overridden + cisco.nxos.nxos_static_routes: &overridden + config: + - vrf: trial_vrf + address_families: + - afi: ipv4 + routes: + - dest: 192.0.2.16/28 + next_hops: + - forward_router_address: 192.0.2.23 + route_name: overridden_route1 + admin_distance: 3 + + - forward_router_address: 192.0.2.45 + route_name: overridden_route2 + dest_vrf: destinationVRF + interface: "{{ nxos_int2 }}" + + state: overridden + register: result + + - ansible.builtin.assert: + that: + - "result.changed == true" + - "'vrf context trial_vrf' in result.commands" + - "'no ip route 192.0.2.64/28 192.0.2.22 tag 4' in result.commands" + - "'no ip route 192.0.2.64/28 192.0.2.23 name merged_route 1' in result.commands" + - "'ip route 192.0.2.16/28 192.0.2.23 name overridden_route1 3' in result.commands" + - "'ip route 192.0.2.16/28 {{ nxos_int2 }} 192.0.2.45 vrf destinationVRF name overridden_route2' in result.commands" + - "'configure terminal' in result.commands" + - "'no ip route 192.0.2.16/28 192.0.2.24 name new_route' in result.commands" + - "'no ip route 192.0.2.80/28 192.0.2.26 tag 12' in result.commands" + - "result.commands | length == 8" + + - name: Idempotence - overridden + cisco.nxos.nxos_static_routes: *overridden + register: result + + - ansible.builtin.assert: + that: + - "result.changed == false" + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tests/common/parsed.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tests/common/parsed.yml new file mode 100644 index 00000000..32cd5bd8 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tests/common/parsed.yml @@ -0,0 +1,26 @@ +--- +- ansible.builtin.debug: + msg: "Start nxos_static_routes parsed tests connection={{ ansible_connection }}" + +- name: Parsed + cisco.nxos.nxos_static_routes: &parsed + running_config: | + ip route 192.0.2.16/28 192.0.2.24 name new_route + ip route 192.0.2.80/28 192.0.2.26 tag 12 + vrf context trial_vrf + ip route 192.0.2.64/28 192.0.2.22 tag 4 + ip route 192.0.2.64/28 192.0.2.23 name merged_route 1 + state: parsed + register: result + +- ansible.builtin.assert: + that: + - "result.changed == false" + - "result.parsed == parsed" + +- name: Idempotence - parsed + cisco.nxos.nxos_static_routes: *parsed + register: result + +- ansible.builtin.assert: + that: "result.changed == false" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tests/common/rendered.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tests/common/rendered.yml new file mode 100644 index 00000000..2348a64b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tests/common/rendered.yml @@ -0,0 +1,49 @@ +--- +- ansible.builtin.debug: + msg: "Start nxos_static_routes rendered tests connection={{ ansible_connection }}" + +- name: Rendered + nxos_static_routes: &rendered + config: + - vrf: trial_vrf + address_families: + - afi: ipv6 + routes: + - dest: 2001:db8:12::/32 + next_hops: + - forward_router_address: 2001:db8::1001 + route_name: rendered_route + admin_distance: 3 + + - address_families: + - afi: ipv4 + routes: + - dest: 192.0.2.16/28 + next_hops: + - forward_router_address: 192.0.2.24 + route_name: new_route + + - dest: 192.0.2.80/28 + next_hops: + - forward_router_address: 192.0.2.26 + tag: 12 + state: rendered + register: result + +- ansible.builtin.assert: + that: + - "result.changed == false" + - "'configure terminal' in result.rendered" + - "'ip route 192.0.2.16/28 192.0.2.24 name new_route' in result.rendered" + - "'ip route 192.0.2.80/28 192.0.2.26 tag 12' in result.rendered" + - "'vrf context trial_vrf' in result.rendered" + - "'ipv6 route 2001:db8:12::/32 2001:db8::1001 name rendered_route 3' in result.rendered" + - "result.rendered | length == 5" + +- name: Idempotence - rendered + nxos_static_routes: *rendered + register: result + +- ansible.builtin.assert: + that: + - "result.changed == false" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tests/common/replaced.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tests/common/replaced.yml new file mode 100644 index 00000000..73c12219 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tests/common/replaced.yml @@ -0,0 +1,52 @@ +--- +- ansible.builtin.debug: + msg: "Start nxos_static_routes replaced integration tests connection = {{ansible_connection}}" + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Gather static_routes post facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: static_routes + + - name: Replaced + cisco.nxos.nxos_static_routes: &replaced + config: + - address_families: + - afi: ipv4 + routes: + - dest: 192.0.2.16/28 + next_hops: + - forward_router_address: 192.0.2.23 + route_name: replaced_route1 + admin_distance: 3 + + - forward_router_address: 192.0.2.45 + route_name: replaced_route2 + dest_vrf: destinationVRF + interface: "{{ nxos_int2 }}" + state: replaced + register: result + + - ansible.builtin.assert: + that: + - "result.changed == true" + - "'configure terminal' in result.commands" + - "'no ip route 192.0.2.16/28 192.0.2.24 name new_route' in result.commands" + - "'ip route 192.0.2.16/28 192.0.2.23 name replaced_route1 3' in result.commands" + - "'ip route 192.0.2.16/28 {{ nxos_int2 }} 192.0.2.45 vrf destinationVRF name replaced_route2' in result.commands" + - "result.commands | length == 4" + + - name: Idempotence - replaced + cisco.nxos.nxos_static_routes: *replaced + register: result + + - ansible.builtin.assert: + that: + - "result.changed == false" + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tests/common/rtt.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tests/common/rtt.yml new file mode 100644 index 00000000..1ee36a93 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/tests/common/rtt.yml @@ -0,0 +1,80 @@ +--- +- ansible.builtin.debug: + msg: "Start nxos_static_routes round trip integration tests on connection={{ ansible_connection }}" + +- block: + - ansible.builtin.include_tasks: _remove_config.yaml + + - name: Apply the provided configuration(base config) + cisco.nxos.nxos_static_routes: + config: + - address_families: + - afi: ipv4 + routes: + - dest: 192.0.2.36/30 + next_hops: + - forward_router_address: 192.0.2.32 + route_name: test_route1 + tag: 14 + + - forward_router_address: 192.0.2.48 + route_name: test_route2 + admin_distance: 2 + + - vrf: trial_vrf + address_families: + - afi: ipv4 + routes: + - dest: 192.0.2.32/30 + next_hops: + - forward_router_address: 192.0.2.105 + dest_vrf: test_dest_vrf + state: merged + register: base_config + + - name: Gather interfaces facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: + - static_routes + + - name: Apply provided configuration(this will be reverted) + cisco.nxos.nxos_static_routes: + config: + - address_families: + - afi: ipv4 + routes: + - dest: 192.0.2.44/30 + next_hops: + - forward_router_address: 192.0.2.55 + tag: 1 + admin_distance: 1 + state: overridden + register: result + + - name: Assert that changes are applied + ansible.builtin.assert: + that: + - "result.changed == true" + - "'configure terminal' in result.commands" + - "'no ip route 192.0.2.36/30 192.0.2.32 name test_route1 tag 14' in result.commands" + - "'no ip route 192.0.2.36/30 192.0.2.48 name test_route2 2'" + - "'ip route 192.0.2.44/30 192.0.2.55 tag 1 1' in result.commands" + - "'vrf context trial_vrf' in result.commands" + - "'no ip route 192.0.2.32/30 192.0.2.105 vrf test_dest_vrf' in result.commands" + - "result.commands | length == 6" + + - name: Revert back to base configuration + cisco.nxos.nxos_static_routes: + config: "{{ ansible_facts['network_resources']['static_routes'] }}" + state: overridden + register: revert + + - ansible.builtin.assert: + that: + - " base_config['after'] | symmetric_difference(revert['after']) | length == 0" + + always: + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/vars/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/vars/main.yml new file mode 100644 index 00000000..95877325 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_static_routes/vars/main.yml @@ -0,0 +1,24 @@ +--- +"parsed": + - "address_families": + - "afi": "ipv4" + "routes": + - "dest": "192.0.2.64/28" + "next_hops": + - "forward_router_address": "192.0.2.22" + "tag": 4 + - "admin_distance": 1 + "forward_router_address": "192.0.2.23" + "route_name": "merged_route" + "vrf": "trial_vrf" + - "address_families": + - "afi": "ipv4" + "routes": + - "dest": "192.0.2.16/28" + "next_hops": + - "forward_router_address": "192.0.2.24" + "route_name": "new_route" + - "dest": "192.0.2.80/28" + "next_hops": + - "forward_router_address": "192.0.2.26" + "tag": 12 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/tests/cli/set_domain_list.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/tests/cli/set_domain_list.yaml new file mode 100644 index 00000000..60272a10 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/tests/cli/set_domain_list.yaml @@ -0,0 +1,114 @@ +--- +- ansible.builtin.debug: + msg: START cli/set_domain_list.yaml + +- name: Setup + cisco.nxos.nxos_config: + lines: + - no ip domain-list ansible.com + - no ip domain-list redhat.com + match: none + +- name: Configure domain_list + register: result + cisco.nxos.nxos_system: + domain_search: + - ansible.com + - redhat.com + +- ansible.builtin.assert: + that: + - result.changed == true + - "'ip domain-list ansible.com' in result.commands" + - "'ip domain-list redhat.com' in result.commands" + +- name: Verify domain_list + register: result + cisco.nxos.nxos_system: + domain_search: + - ansible.com + - redhat.com + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Remove one entry + register: result + cisco.nxos.nxos_system: + domain_search: + - ansible.com + +- ansible.builtin.assert: + that: + - result.changed == true + - "'no ip domain-list redhat.com' in result.commands" + +- name: Verify remove one entry + register: result + cisco.nxos.nxos_system: + domain_search: + - ansible.com + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Add one entry + register: result + cisco.nxos.nxos_system: + domain_search: + - ansible.com + - redhat.com + +- ansible.builtin.assert: + that: + - result.changed == true + - "'ip domain-list redhat.com' in result.commands" + +- name: Verify add one entry + register: result + cisco.nxos.nxos_system: + domain_search: + - ansible.com + - redhat.com + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Add and remove one entry + register: result + cisco.nxos.nxos_system: + domain_search: + - ansible.com + - eng.ansible.com + +- ansible.builtin.assert: + that: + - result.changed == true + - "'no ip domain-list redhat.com' in result.commands" + - "'ip domain-list eng.ansible.com' in result.commands" + - result.commands|length == 2 + +- name: Verify add and remove one entry + register: result + cisco.nxos.nxos_system: + domain_search: + - ansible.com + - eng.ansible.com + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Teardown + cisco.nxos.nxos_config: + lines: + - no ip domain-list ansible.com + - no ip domain-list redhat.com + - no ip domain-list eng.ansible.com + match: none + +- ansible.builtin.debug: + msg: END cli/set_domain_search.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/tests/cli/set_domain_name.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/tests/cli/set_domain_name.yaml new file mode 100644 index 00000000..505f7df5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/tests/cli/set_domain_name.yaml @@ -0,0 +1,34 @@ +--- +- ansible.builtin.debug: + msg: START cli/set_domain_name.yaml + +- name: Setup + cisco.nxos.nxos_config: + lines: no ip domain-name eng.ansible.com + match: none + +- name: Configure domain_name + register: result + cisco.nxos.nxos_system: + domain_name: eng.ansible.com + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: Verify domain_name + register: result + cisco.nxos.nxos_system: + domain_name: eng.ansible.com + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Teardown + cisco.nxos.nxos_config: + lines: no ip domain-name eng.ansible.com + match: none + +- ansible.builtin.debug: + msg: END cli/set_domain_name.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/tests/cli/set_name_servers.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/tests/cli/set_name_servers.yaml new file mode 100644 index 00000000..d9a7ef18 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/tests/cli/set_name_servers.yaml @@ -0,0 +1,75 @@ +--- +- ansible.builtin.debug: + msg: START cli/set_name_servers.yaml + +- name: Setup + cisco.nxos.nxos_config: &id002 + lines: + - no ip name-server 192.0.2.1 + - no ip name-server 192.0.2.2 + - no ip name-server 192.0.2.3 + match: none + +- name: Configure name_servers + register: result + cisco.nxos.nxos_system: + name_servers: + - 192.0.2.1 + - 192.0.2.2 + - 192.0.2.3 + +- ansible.builtin.assert: + that: + - result.changed == true + - "'ip name-server 192.0.2.1' in result.commands" + - "'ip name-server 192.0.2.2' in result.commands" + - "'ip name-server 192.0.2.3' in result.commands" + +- name: Verify name_servers + register: result + cisco.nxos.nxos_system: + name_servers: + - 192.0.2.1 + - 192.0.2.2 + - 192.0.2.3 + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Remove one + register: result + cisco.nxos.nxos_system: + name_servers: + - 192.0.2.1 + - 192.0.2.2 + +- ansible.builtin.assert: + that: + - result.changed == true + - result.commands|length == 1 + - "'no ip name-server 192.0.2.3' in result.commands" + +- name: Default name server + register: result + cisco.nxos.nxos_system: &id001 + name_servers: default + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: Idempotent check + register: result + cisco.nxos.nxos_system: *id001 + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Teardown + ignore_errors: true + cisco.nxos.nxos_config: *id002 + +- ansible.builtin.debug: + msg: END cli/set_name_servers.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/tests/common/sanity.yaml new file mode 100644 index 00000000..ffd325c0 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/tests/common/sanity.yaml @@ -0,0 +1,130 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }}/sanity.yaml + +- block: + - name: Remove configuration + register: result + ignore_errors: true + cisco.nxos.nxos_system: &id010 + state: absent + + - name: Configure domain lookup + register: result + cisco.nxos.nxos_system: &id007 + domain_lookup: true + state: present + + - name: Configure hostname and domain-name + register: result + cisco.nxos.nxos_system: &id001 + hostname: switch + domain_name: test.example.com + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Idempotence check + register: result + cisco.nxos.nxos_system: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Configure name servers + register: result + cisco.nxos.nxos_system: &id003 + name_servers: + - 8.8.8.8 + - 8.8.4.4 + + - ansible.builtin.assert: *id002 + + - name: Idempotence check + register: result + cisco.nxos.nxos_system: *id003 + + - ansible.builtin.assert: *id004 + + - name: Configure name servers with VRF support + register: result + cisco.nxos.nxos_system: &id005 + name_servers: + - server: 8.8.8.8 + vrf: management + + - server: 8.8.4.4 + vrf: management + + - ansible.builtin.assert: *id002 + + - name: Idempotence check + register: result + cisco.nxos.nxos_system: *id005 + + - ansible.builtin.assert: *id004 + + - name: Configure domain lookup1 + register: result + cisco.nxos.nxos_system: &id006 + domain_lookup: false + + - ansible.builtin.assert: *id002 + + - name: Idempotence check + register: result + cisco.nxos.nxos_system: *id006 + + - ansible.builtin.assert: *id004 + + - name: Configure domain lookup2 + register: result + cisco.nxos.nxos_system: *id007 + + - ansible.builtin.assert: *id002 + + - name: Idempotence check + register: result + cisco.nxos.nxos_system: *id007 + + - ansible.builtin.assert: *id004 + + - name: Configure system mtu + register: result + cisco.nxos.nxos_system: &id008 + system_mtu: 3000 + + - ansible.builtin.assert: *id002 + + - name: Idempotence check + register: result + cisco.nxos.nxos_system: *id008 + + - ansible.builtin.assert: *id004 + + - name: Default configuration + register: result + cisco.nxos.nxos_system: &id009 + hostname: default + domain_name: default + name_servers: default + system_mtu: default + + - ansible.builtin.assert: *id002 + + - name: Idempotence check + register: result + cisco.nxos.nxos_system: *id009 + + - ansible.builtin.assert: *id004 + always: + - name: Remove configuration + cisco.nxos.nxos_system: *id010 + + - name: Re-configure hostname + cisco.nxos.nxos_system: *id001 + + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }}/sanity.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/tests/common/set_hostname.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/tests/common/set_hostname.yaml new file mode 100644 index 00000000..69f800cc --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/tests/common/set_hostname.yaml @@ -0,0 +1,35 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }}/set_hostname.yaml + +- block: + - name: Setup + cisco.nxos.nxos_config: + lines: hostname switch + match: none + + - name: Configure hostname + register: result + cisco.nxos.nxos_system: + hostname: foo + + - ansible.builtin.assert: + that: + - result.changed == true + + - name: Verify hostname + register: result + cisco.nxos.nxos_system: + hostname: foo + + - ansible.builtin.assert: + that: + - result.changed == false + always: + - name: Teardown + cisco.nxos.nxos_config: + lines: hostname switch + match: none + + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }}/set_hostname.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/tests/nxapi/set_domain_list.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/tests/nxapi/set_domain_list.yaml new file mode 100644 index 00000000..5f13e370 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/tests/nxapi/set_domain_list.yaml @@ -0,0 +1,120 @@ +--- +- ansible.builtin.debug: + msg: START nxapi/set_domain_list.yaml + +- name: Setup + ignore_errors: true + with_items: + - ansible.com + - redhat.com + cisco.nxos.nxos_config: + lines: + - no ip domain-list {{ item }} + match: none + +- name: Configure domain_list + register: result + cisco.nxos.nxos_system: + domain_search: + - ansible.com + - redhat.com + +- ansible.builtin.assert: + that: + - result.changed == true + - "'ip domain-list ansible.com' in result.commands" + - "'ip domain-list redhat.com' in result.commands" + +- name: Verify domain_list + register: result + cisco.nxos.nxos_system: + domain_search: + - ansible.com + - redhat.com + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Remove one entry + register: result + cisco.nxos.nxos_system: + domain_search: + - ansible.com + +- ansible.builtin.assert: + that: + - result.changed == true + - "'no ip domain-list redhat.com' in result.commands" + +- name: Verify remove one entry + register: result + cisco.nxos.nxos_system: + domain_search: + - ansible.com + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Add one entry + register: result + cisco.nxos.nxos_system: + domain_search: + - ansible.com + - redhat.com + +- ansible.builtin.assert: + that: + - result.changed == true + - "'ip domain-list redhat.com' in result.commands" + +- name: Verify add one entry + register: result + cisco.nxos.nxos_system: + domain_search: + - ansible.com + - redhat.com + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Add and remove one entry + register: result + cisco.nxos.nxos_system: + domain_search: + - ansible.com + - eng.ansible.com + +- ansible.builtin.assert: + that: + - result.changed == true + - "'no ip domain-list redhat.com' in result.commands" + - "'ip domain-list eng.ansible.com' in result.commands" + - result.commands|length == 2 + +- name: Verify add and remove one entry + register: result + cisco.nxos.nxos_system: + domain_search: + - ansible.com + - eng.ansible.com + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Teardown + ignore_errors: true + with_items: + - ansible.com + - redhat.com + - eng.ansible.com + cisco.nxos.nxos_config: + lines: + - no ip domain-list {{ item }} + match: none + +- ansible.builtin.debug: + msg: END nxapi/set_domain_search.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/tests/nxapi/set_domain_name.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/tests/nxapi/set_domain_name.yaml new file mode 100644 index 00000000..bbbe5906 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/tests/nxapi/set_domain_name.yaml @@ -0,0 +1,35 @@ +--- +- ansible.builtin.debug: + msg: START nxapi/set_domain_name.yaml + +- name: Setup + ignore_errors: true + cisco.nxos.nxos_config: + lines: no ip domain-name eng.ansible.com + match: none + +- name: Configure domain_name + register: result + cisco.nxos.nxos_system: + domain_name: eng.ansible.com + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: Verify domain_name + register: result + cisco.nxos.nxos_system: + domain_name: eng.ansible.com + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Teardown + cisco.nxos.nxos_config: + lines: no ip domain-name eng.ansible.com + match: none + +- ansible.builtin.debug: + msg: END nxapi/set_domain_name.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/tests/nxapi/set_name_servers.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/tests/nxapi/set_name_servers.yaml new file mode 100644 index 00000000..8916d512 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_system/tests/nxapi/set_name_servers.yaml @@ -0,0 +1,82 @@ +--- +- ansible.builtin.debug: + msg: START nxapi/set_name_servers.yaml + +- name: Setup + ignore_errors: true + with_items: + - 192.0.2.1 + - 192.0.2.2 + - 192.0.2.3 + cisco.nxos.nxos_config: &id002 + lines: + - no ip name-server {{ item }} + match: none + +- name: Configure name_servers + register: result + cisco.nxos.nxos_system: + name_servers: + - 192.0.2.1 + - 192.0.2.2 + - 192.0.2.3 + +- ansible.builtin.assert: + that: + - result.changed == true + - "'ip name-server 192.0.2.1' in result.commands" + - "'ip name-server 192.0.2.2' in result.commands" + - "'ip name-server 192.0.2.3' in result.commands" + +- name: Verify name_servers + register: result + cisco.nxos.nxos_system: + name_servers: + - 192.0.2.1 + - 192.0.2.2 + - 192.0.2.3 + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Remove one + register: result + cisco.nxos.nxos_system: + name_servers: + - 192.0.2.1 + - 192.0.2.2 + +- ansible.builtin.assert: + that: + - result.changed == true + - result.commands|length == 1 + - "'no ip name-server 192.0.2.3' in result.commands" + +- name: Default name server + register: result + cisco.nxos.nxos_system: &id001 + name_servers: default + +- ansible.builtin.assert: + that: + - result.changed == true + +- name: Idempotent check + register: result + cisco.nxos.nxos_system: *id001 + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Teardown + with_items: + - 192.0.2.1 + - 192.0.2.2 + - 192.0.2.3 + ignore_errors: true + cisco.nxos.nxos_config: *id002 + +- ansible.builtin.debug: + msg: END nxapi/set_name_servers.yaml diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/tasks/cli.yaml new file mode 100644 index 00000000..311e3941 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/tasks/cli.yaml @@ -0,0 +1,31 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/tasks/main.yaml new file mode 100644 index 00000000..cb0d4085 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/tasks/main.yaml @@ -0,0 +1,98 @@ +--- +- name: Set a fact for 'run_test' + ansible.builtin.set_fact: + run_test: true + +- name: Set a fact for 'run_test' + ansible.builtin.set_fact: + run_test: false + when: platform is not search("N9K") + +- name: Set a fact for 'run_test' + ansible.builtin.set_fact: + run_test: false + when: imagetag is search("I2|I3|I4|I5|I6") + +- name: Fetch mgmt interface information + cisco.nxos.nxos_command: + commands: show interface mgmt 0 | json + register: result + +- name: Store mgmt interface IP address + ansible.builtin.set_fact: + mgmt0_ip: "{{ result['stdout'][0]['TABLE_interface']['ROW_interface']['eth_ip_addr'] }}" + +- name: Generate and store random password for temp user + ansible.builtin.set_fact: + temp_passwd: "{{ lookup('password', '/dev/null length=15 chars=ascii_letters') }}" + delegate_to: localhost + no_log: true + +- name: Configure temporary user for test + cisco.nxos.nxos_user: + name: temp_user + configured_password: "{{ temp_passwd }}" + no_log: true + +- name: Setup - turn on 'feature scp-server' + cisco.nxos.nxos_feature: + feature: scp-server + state: enabled + +- name: Setup - backup admin password if ansible_user is not admin + cisco.nxos.nxos_command: + commands: + - command: show running-config | include "username admin password" + register: nxos_admin_password + no_log: true + when: ansible_user != "admin" + +- name: Setup - change admin password if ansible_user is not admin + cisco.nxos.nxos_user: + name: admin + configured_password: "{{ temp_passwd }}" + when: ansible_user != "admin" + +- name: Copy crt file from ansible controller to bootflash + register: result + cisco.nxos.nxos_file_copy: + local_file: "{{ role_path }}/tests/common/fixtures/{{ item }}" + file_system: "bootflash:" + connect_ssh_port: "{{ ansible_ssh_port | d(22) }}" + loop: + - server.crt + - new_server.crt + - local_server.crt + vars: + ansible_connection: ansible.netcommon.network_cli + +- name: Run the CLI and NX-API tests + block: + - name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: cli + when: run_test + + - name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: nxapi + when: run_test + always: + - name: Remove temporary user + cisco.nxos.nxos_user: + name: temp_user + state: absent + + - name: Turn off 'feature scp-server' + cisco.nxos.nxos_feature: + feature: scp-server + state: disabled + + - name: Setup - remove existing file + ignore_errors: true # noqa ignore-errors + cisco.nxos.nxos_command: + commands: + - terminal dont-ask + - delete server.crt + - delete new_server.crt + - delete local_server.crt diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/tasks/nxapi.yaml new file mode 100644 index 00000000..18bf1b6e --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/tasks/nxapi.yaml @@ -0,0 +1,31 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/templates/populate_config.cfg b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/templates/populate_config.cfg new file mode 100644 index 00000000..8a8ad677 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/templates/populate_config.cfg @@ -0,0 +1,38 @@ +telemetry + certificate /bootflash/local_server.crt host.example.com + destination-profile + use-vrf blue + use-compression gzip + destination-group 2 + ip address 192.168.0.1 port 50001 protocol gRPC encoding GPB + ip address 192.168.0.2 port 60001 protocol gRPC encoding GPB + destination-group 10 + ip address 192.168.0.1 port 50001 protocol gRPC encoding GPB + ip address 192.168.0.2 port 60001 protocol gRPC encoding GPB + ip address 192.168.1.1 port 55 protocol HTTP encoding JSON + ip address 192.168.1.2 port 100 protocol gRPC encoding GPB + destination-group 99 + sensor-group 2 + data-source NX-API + path "show bgp l2vpn evpn summary" depth unbounded query-condition foo filter-condition foo + sensor-group 8 + data-source NX-API + path "show ip bgp neighbors" depth 0 query-condition foo filter-condition foo + sensor-group 55 + data-source DME + path sys/bgp/inst/dom-default/peer-[10.10.10.11]/ent-[10.10.10.11] depth 0 query-condition foo filter-condition foo + path sys/ospf depth 0 query-condition foo filter-condition or(eq(ethpmPhysIf.operSt,"down"),eq(ethpmPhysIf.operSt,"up")) + sensor-group 77 + subscription 44 + dst-grp 2 + dst-grp 10 + snsr-grp 2 sample-interval 2000 + snsr-grp 8 sample-interval 2000 + subscription 55 + dst-grp 10 + snsr-grp 55 sample-interval 2000 + subscription 99 + dst-grp 2 + dst-grp 99 + snsr-grp 8 sample-interval 90000 + snsr-grp 77 sample-interval 2000 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/tests/common/deleted.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/tests/common/deleted.yaml new file mode 100644 index 00000000..3c9556b9 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/tests/common/deleted.yaml @@ -0,0 +1,159 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_telemetry deleted sanity test + +- name: Set a fact for 'source_interface' + ansible.builtin.set_fact: + source_interface: Loopback55 + when: imagetag and (major_version is version_compare('9.1', 'ge')) + +- name: Set a fact for 'before_keys_length' + ansible.builtin.set_fact: + before_keys_length: 6 + +- name: Set a fact for 'before_keys_length' + ansible.builtin.set_fact: + before_keys_length: 7 + when: imagetag and (major_version is version_compare('9.1', 'ge')) + +- name: Setup + ignore_errors: true + cisco.nxos.nxos_feature: &id003 + feature: telemetry + state: disabled + +- name: Setup - configure telemetry + cisco.nxos.nxos_telemetry: + state: merged + config: + certificate: + key: /bootflash/server.crt + hostname: localhost + compression: gzip + source_interface: "{{source_interface|default(omit)}}" + vrf: RED + destination_groups: + - id: 2 + destination: + ip: 192.168.0.1 + port: 50001 + protocol: grpc + encoding: gpb + + - id: 2 + destination: + ip: 192.168.0.2 + port: 60001 + protocol: gRPC + encoding: GPB + + - id: 10 + destination: + ip: 192.168.0.1 + port: 50001 + protocol: Grpc + encoding: gPB + + - id: 10 + destination: + ip: 192.168.0.2 + port: 60001 + protocol: gRPC + encoding: gpb + sensor_groups: + - id: 8 + data_source: NX-API + path: + name: '"show bgp l2vpn evpn summary"' + depth: 0 + query_condition: foo + filter_condition: foo + + - id: 2 + data_source: NX-API + path: + name: '"show ip bgp neighbors"' + depth: unbounded + query_condition: foo + filter_condition: foo + + - id: 55 + data_source: DME + path: + name: sys/bgp/inst/dom-default/peer-[10.10.10.11]/ent-[10.10.10.11] + depth: 0 + query_condition: foo + filter_condition: foo + + - id: 55 + data_source: DME + path: + name: sys/ospf + depth: 0 + query_condition: foo + filter_condition: or(eq(ethpmPhysIf.operSt,"down"),eq(ethpmPhysIf.operSt,"up")) + subscriptions: + - id: 44 + destination_group: 10 + sensor_group: + id: 8 + sample_interval: 2000 + + - id: 44 + destination_group: 2 + sensor_group: + id: 2 + sample_interval: 2000 + + - id: 55 + destination_group: 10 + sensor_group: + id: 55 + sample_interval: 2000 + +- block: + - name: Gather telemetry facts before changes + cisco.nxos.nxos_facts: &id001 + gather_subset: + - "!all" + - "!min" + gather_network_resources: + - telemetry + + - name: Telemetry - deleted + register: result + cisco.nxos.nxos_telemetry: &id002 + state: deleted + + - ansible.builtin.assert: + that: + - result.changed == true + - "'no telemetry' in result.commands" + - result.before|dict2items|length == {{ before_keys_length }} + + - ansible.builtin.assert: + that: + - (ansible_facts.network_resources.telemetry|dict2items)|symmetric_difference(result.before|dict2items)|length == 0 + + - name: Gather telemetry facts after changes + cisco.nxos.nxos_facts: *id001 + + - ansible.builtin.assert: + that: + - (ansible_facts.network_resources.telemetry|dict2items)|symmetric_difference(result.after|dict2items)|length == 0 + + - name: Telemetry - deleted - idempotence + register: result + cisco.nxos.nxos_telemetry: *id002 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + always: + - name: Teardown + ignore_errors: true + cisco.nxos.nxos_feature: *id003 + + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_telemetry deleted sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/tests/common/fixtures/local_server.crt b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/tests/common/fixtures/local_server.crt new file mode 100644 index 00000000..2409dd90 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/tests/common/fixtures/local_server.crt @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICpDCCAYwCCQDCn9ZcKfu3PTANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAls +b2NhbGhvc3QwHhcNMjEwMTIwMTIwMzA1WhcNMzEwMTE4MTIwMzA1WjAUMRIwEAYD +VQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDV +vEw0Tgw0vkJg7id8TpByxC5HSCbXqlx6q4/ua0kbzRG8TX4nsks1sqliQEHqx9k7 +brmCg7F0uL+w4mb+ODRP3mVCNldZPb2kFEXKslRUigtgGb19gbkjG+dT5Jg67zly +x3kp6OcMeuRarkHCwsMlp1L6wpjOPg8aeKzoz91tIFspGpnv7NcdPyRXNhJ4AShB +n66Hx9ZLXd4em03UZP13lFV6fWh6dnxUhjKbQj5DK5HV2TbRFk4LbLfNIhanUQ7a +3qZOoDv1scgRyFt0syDHH2LhfQro3rd1nz6jI9hmIV9ZIxgNs7yCxNehx0UTRD3g +xAUKr5EuU5BH9DJqvU1lAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAHAYv8sLNJl2 ++xDQLwlUgBEjV0aEDWsGgBUNJ+mmPR46JYOzRY53IBQs6CsLSs61AzS9xdpX9lM7 +Z5aa110nPz83s0/fPNtdoN5EKWuvZHqCUuQImeDiMcYLj9XLYGfneTl/R0t/uOqO +yJ+U4Tp/r8VFs4Id73aroGeFI74t6eqt22GRoqwmoPJxsE6Fjiuc8TPtNMOezvIn +DUcN8woUCZfpMNegGdhobaT5exdL8QoZ9czJbroxQ5DnFRSIXs9Mtg8DHehDbGkA +SnVqqia8hf7JYxA7RZdnhtJej+sOYHTCahw0C74PchoXDxoD8E5M+naGt13ROGVJ +6zlhNbVqmC4= +-----END CERTIFICATE----- diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/tests/common/fixtures/new_server.crt b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/tests/common/fixtures/new_server.crt new file mode 100644 index 00000000..f47ea953 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/tests/common/fixtures/new_server.crt @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICpDCCAYwCCQDMZTEJF38oQzANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAls +b2NhbGhvc3QwHhcNMjEwMTIwMTE1NDU3WhcNMzEwMTE4MTE1NDU3WjAUMRIwEAYD +VQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDV +vEw0Tgw0vkJg7id8TpByxC5HSCbXqlx6q4/ua0kbzRG8TX4nsks1sqliQEHqx9k7 +brmCg7F0uL+w4mb+ODRP3mVCNldZPb2kFEXKslRUigtgGb19gbkjG+dT5Jg67zly +x3kp6OcMeuRarkHCwsMlp1L6wpjOPg8aeKzoz91tIFspGpnv7NcdPyRXNhJ4AShB +n66Hx9ZLXd4em03UZP13lFV6fWh6dnxUhjKbQj5DK5HV2TbRFk4LbLfNIhanUQ7a +3qZOoDv1scgRyFt0syDHH2LhfQro3rd1nz6jI9hmIV9ZIxgNs7yCxNehx0UTRD3g +xAUKr5EuU5BH9DJqvU1lAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAIYzQeowrmua +s3D73VREPz9KNqhIdwFfkW57N+kJHzOJrOgCIA1Hx5X6kQrueNDZDBFcFOqjrSjb +Sa+fx3+yu7BwCxnUrcDr1fdTrl6XHY86exuXC2/5OhCvm0NrcFX1i1BX43zbObzq +y0IcSnmXbl3lO0yusbvYFYh3J+p/SIVCAsX6+uzxFM8pG9asQ7+qQ9Dn7nCQrpME +JbOrnWo2BkPRNJSPm7wAjy36/C6m3C+NZwYNful4I5GkcmWSSV7zAwjrqPRU7fyR +34I2PxE6hGE11litTfTvx61sp/Fvme3Fn6OQE94nh51GlbunlufipYzsprYNs/Qz +MD163VLdDqU= +-----END CERTIFICATE----- diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/tests/common/fixtures/server.crt b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/tests/common/fixtures/server.crt new file mode 100644 index 00000000..f66d6c6e --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/tests/common/fixtures/server.crt @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICpDCCAYwCCQCg8A5VMWotHjANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAls +b2NhbGhvc3QwHhcNMjEwMTIwMDkwNjEyWhcNMzEwMTE4MDkwNjEyWjAUMRIwEAYD +VQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDJ +c84R3/r/ZMEyFv5b+bsf72X4jAnvHbwU7W0hjpp8bAKaMJVB76G8VLXP1sSsPYX5 +PqJQ38Fslfu/f85aINY2D5VYhdHW4Ocz89DzP+oO225fpljD5SMM13l1A3qRdSVJ +dfsn/ncLA1DpOUdeJBniEGv9o6kCam7Op1nLUD+oYbnfr5vYAJ+tGd8GmYEsK+ek +xxt4+jt2r6fStKndw7CBkrDZeD0m65DV0sItt8VOthPvz6smPtYkJGWoWyfFuDLu +6s9uCnigGMP7Jj/7ppvuKa7SOy1T9fzI8s4BDmVfbKyd8A4NVbjtp7K0O6B4Len9 ++E3dfAhvFOiNacOxJrTNAgMBAAEwDQYJKoZIhvcNAQELBQADggEBACLPu8GW7emf +D/ir0v4VD5CGgeN9IB3WHdheNca8e+5beOGvK4sWBEIC0kNNxj8THjailcOxyO62 +WQ5ebq9eN7NfE4lISoivDd5yaELL9s1FFMM6LaHsnLy98uxi+JD0nCbfQvxhVNB7 +nZXMMjYQozxntLYgw9WDu4dGUO9/rq4jG28mySfoIX/GPWL/+OdKRGy5Xb+lNdFo +LhEDmj7iPJi+jjEt/1EPgAPhF96aJGNdgr+OfwIfoqp6zuKCZcBJJZs+a7BZkciF +PwT6RkqQGc5AqaCLz0Upweu281TLQcut8ypNj8xOzRFBs+QyDuNVmW0VMpvdmrF1 +FenwsKpMZeA= +-----END CERTIFICATE----- diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/tests/common/gathered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/tests/common/gathered.yaml new file mode 100644 index 00000000..0e65d525 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/tests/common/gathered.yaml @@ -0,0 +1,43 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_telemetry gathered sanity test + +- name: Setup 1 + ignore_errors: true + cisco.nxos.nxos_feature: &id001 + feature: telemetry + state: disabled + +- block: + - name: Setup 2 + cisco.nxos.nxos_feature: + feature: telemetry + state: enabled + + - name: Populate telemetry data + cisco.nxos.nxos_config: + lines: + - "telemetry" + - "destination-group 2" + - "ip address 192.168.0.1 port 50001 protocol grpc encoding gpb" + - "ip address 192.168.0.2 port 60001 protocol grpc encoding gpb" + - "destination-group 10" + - "ip address 192.168.0.1 port 50001 protocol grpc encoding gpb" + - "ip address 192.168.0.2 port 60001 protocol grpc encoding gpb" + - "sensor-group 8" + - "sensor-group 2" + - "subscription 100" + - "snsr-grp 8 sample-interval 15000" + + - name: Gather telemetry facts using gathered + cisco.nxos.nxos_telemetry: + state: gathered + register: result + + - ansible.builtin.assert: + that: + - "{{ result['gathered'] == gathered }}" + always: + - name: Setup 1 + ignore_errors: true + cisco.nxos.nxos_feature: *id001 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/tests/common/merged.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/tests/common/merged.yaml new file mode 100644 index 00000000..37109e9e --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/tests/common/merged.yaml @@ -0,0 +1,302 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_telemetry merged sanity test + +- name: Set a fact for 'source_interface' + ansible.builtin.set_fact: + source_interface: Loopback55 + when: imagetag and (major_version is version_compare('9.1', 'ge')) + +- name: Set a fact for 'command_list_length' + ansible.builtin.set_fact: + command_list_length: 30 + +- name: Set a fact for 'command_list_length' + ansible.builtin.set_fact: + command_list_length: 31 + when: imagetag and (major_version is version_compare('9.1', 'ge')) + +- name: Setup + ignore_errors: true + cisco.nxos.nxos_feature: &id004 + feature: telemetry + state: disabled + +- block: + - name: Gather telemetry facts before changes + cisco.nxos.nxos_facts: &id001 + gather_subset: + - "!all" + - "!min" + gather_network_resources: + - telemetry + + - name: Telemetry - merged + register: result + cisco.nxos.nxos_telemetry: &id002 + state: merged + config: + certificate: + key: /bootflash/server.crt + hostname: localhost + compression: gzip + source_interface: "{{source_interface|default(omit)}}" + vrf: RED + destination_groups: + - id: 2 + destination: + ip: 192.168.0.1 + port: 50001 + protocol: grpc + encoding: gpb + + - id: 2 + destination: + ip: 192.168.0.2 + port: 60001 + protocol: gRPC + encoding: GPB + + - id: 10 + destination: + ip: 192.168.0.1 + port: 50001 + protocol: Grpc + encoding: gPB + + - id: 10 + destination: + ip: 192.168.0.2 + port: 60001 + protocol: gRPC + encoding: gpb + sensor_groups: + - id: 8 + data_source: NX-API + path: + name: '"show bgp l2vpn evpn summary"' + depth: 0 + query_condition: foo + filter_condition: foo + + - id: 2 + data_source: NX-API + path: + name: '"show ip bgp neighbors"' + depth: unbounded + query_condition: foo + filter_condition: foo + + - id: 55 + data_source: DME + path: + name: sys/bgp/inst/dom-default/peer-[10.10.10.11]/ent-[10.10.10.11] + depth: 0 + query_condition: foo + filter_condition: foo + + - id: 55 + data_source: DME + path: + name: sys/ospf + depth: 0 + query_condition: foo + filter_condition: or(eq(ethpmPhysIf.operSt,"down"),eq(ethpmPhysIf.operSt,"up")) + subscriptions: + - id: 44 + destination_group: 10 + sensor_group: + id: 8 + sample_interval: 2000 + + - id: 44 + destination_group: 2 + sensor_group: + id: 2 + sample_interval: 2000 + + - id: 55 + destination_group: 10 + sensor_group: + id: 55 + sample_interval: 2000 + + - ansible.builtin.assert: + that: + - result.changed == true + - result.before|length == 0 + - "'feature telemetry' in result.commands" + - "'telemetry' in result.commands" + - "'certificate /bootflash/server.crt localhost' in result.commands" + - "'destination-profile' in result.commands" + - "'use-compression gzip' in result.commands" + - "'use-vrf RED' in result.commands" + - "'destination-group 2' in result.commands" + - "'ip address 192.168.0.1 port 50001 protocol grpc encoding gpb' in result.commands" + - "'ip address 192.168.0.2 port 60001 protocol grpc encoding gpb' in result.commands" + - "'destination-group 10' in result.commands" + - "'ip address 192.168.0.1 port 50001 protocol grpc encoding gpb' in result.commands" + - "'ip address 192.168.0.2 port 60001 protocol grpc encoding gpb' in result.commands" + - "'sensor-group 8' in result.commands" + - "'data-source NX-API' in result.commands" + - result.commands is search("path .*show bgp l2vpn evpn summary.* depth 0 query-condition foo filter-condition foo") + - "'sensor-group 2' in result.commands" + - "'data-source NX-API' in result.commands" + - result.commands is search("path .*show ip bgp neighbors.* depth unbounded query-condition foo filter-condition foo") + - "'sensor-group 55' in result.commands" + - "'data-source DME' in result.commands" + - "'path sys/bgp/inst/dom-default/peer-[10.10.10.11]/ent-[10.10.10.11] depth 0 query-condition foo filter-condition foo' in result.commands" + - '''path sys/ospf depth 0 query-condition foo filter-condition or(eq(ethpmPhysIf.operSt,"down"),eq(ethpmPhysIf.operSt,"up"))'' in result.commands' + - "'subscription 44' in result.commands" + - "'dst-grp 10' in result.commands" + - "'dst-grp 2' in result.commands" + - "'snsr-grp 8 sample-interval 2000' in result.commands" + - "'snsr-grp 2 sample-interval 2000' in result.commands" + - "'subscription 55' in result.commands" + - "'dst-grp 10' in result.commands" + - "'snsr-grp 55 sample-interval 2000' in result.commands" + - result.commands|length == {{ command_list_length }} + + - ansible.builtin.assert: + that: + - "'source-interface loopback55' in result.commands" + when: imagetag and (major_version is version_compare('9.1', 'ge')) + + - ansible.builtin.assert: + that: + - (ansible_facts.network_resources.telemetry|dict2items)|symmetric_difference(result.before|dict2items)|length == 0 + + - name: Gather telemetry facts after changes + cisco.nxos.nxos_facts: *id001 + + - ansible.builtin.assert: + that: + - (ansible_facts.network_resources.telemetry|dict2items)|symmetric_difference(result.after|dict2items)|length == 0 + + - name: Telemetry - merged - idempotence + register: result + cisco.nxos.nxos_telemetry: *id002 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + + - name: Telemetry - change values + register: result + cisco.nxos.nxos_telemetry: &id003 + state: merged + config: + certificate: + key: /bootflash/local_server.crt + hostname: localhost + compression: gzip + source_interface: "{{source_interface|default(omit)}}" + vrf: RED + destination_groups: + - id: 2 + destination: + ip: 192.168.0.1 + port: 50001 + protocol: grpc + encoding: gpb + + - id: 2 + destination: + ip: 192.168.0.2 + port: 60001 + protocol: gRPC + encoding: GPB + + - id: 10 + destination: + ip: 192.168.0.1 + port: 50001 + protocol: Grpc + encoding: gPB + + - id: 10 + destination: + ip: 192.168.0.2 + port: 60001 + protocol: gRPC + encoding: gpb + sensor_groups: + - id: 8 + data_source: NX-API + path: + name: '"show bgp l2vpn evpn summary"' + depth: 0 + query_condition: foo + filter_condition: foo + + - id: 2 + data_source: NX-API + path: + name: '"show ip bgp neighbors"' + depth: unbounded + query_condition: foo + filter_condition: foo + + - id: 55 + data_source: DME + path: + name: sys/bgp/inst/dom-default/peer-[10.10.10.11]/ent-[10.10.10.11] + depth: 0 + query_condition: foo + filter_condition: foo + + - id: 55 + data_source: DME + path: + name: sys/ospf + depth: 0 + query_condition: foo + filter_condition: or(eq(ethpmPhysIf.operSt,"down"),eq(ethpmPhysIf.operSt,"up")) + subscriptions: + - id: 44 + destination_group: 10 + sensor_group: + id: 8 + sample_interval: 1000 + + - id: 44 + destination_group: 2 + sensor_group: + id: 2 + sample_interval: 2000 + + - id: 55 + destination_group: 10 + sensor_group: + id: 55 + sample_interval: 2000 + + - name: Set a fact for 'test_list' + ansible.builtin.set_fact: + test_list: + - telemetry + - certificate /bootflash/local_server.crt localhost + - subscription 44 + - snsr-grp 8 sample-interval 1000 + + - ansible.builtin.assert: + that: + - result.changed == true + - test_list|symmetric_difference(result.commands)|length == 0 + + - name: Telemetry - change values - idempotent + register: result + cisco.nxos.nxos_telemetry: *id003 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + always: + - name: Teardown + ignore_errors: true + cisco.nxos.nxos_feature: *id004 + + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_telemetry merged sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/tests/common/replaced.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/tests/common/replaced.yaml new file mode 100644 index 00000000..e3b6ce0f --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/tests/common/replaced.yaml @@ -0,0 +1,166 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_telemetry replaced sanity test + +- name: Set a fact for 'source_interface' + ansible.builtin.set_fact: + source_interface: Loopback55 + when: imagetag and (major_version is version_compare('9.1', 'ge')) + +- name: Set a fact for 'command_list_length' + ansible.builtin.set_fact: + command_list_length: 27 + +- name: Set a fact for 'command_list_length' + ansible.builtin.set_fact: + command_list_length: 28 + when: imagetag and (major_version is version_compare('9.1', 'ge')) + +- name: Set a fact for 'dict_facts_length' + ansible.builtin.set_fact: + dict_facts_length: 6 + +- name: Set a fact for 'dict_facts_length' + ansible.builtin.set_fact: + dict_facts_length: 7 + when: imagetag and (major_version is version_compare('9.1', 'ge')) + +- name: Setup - disable 'feature telemetry' + ignore_errors: true + cisco.nxos.nxos_feature: &id003 + feature: telemetry + state: disabled + +- name: Setup - enable 'feature telemetry' + cisco.nxos.nxos_feature: + feature: telemetry + state: enabled + +- name: Setup - add initial telemetry configuration + cisco.nxos.nxos_config: + src: populate_config.cfg + +- name: Setup - add initial source-interface telemetry configuration + when: imagetag and (major_version is version_compare('9.1', 'ge')) + cisco.nxos.nxos_config: + lines: + - "telemetry" + - " destination-profile" + - " source-interface loopback55" + +- block: + - name: Gather telemetry facts before changes + cisco.nxos.nxos_facts: &id001 + gather_subset: + - "!all" + - "!min" + gather_network_resources: + - telemetry + + - name: Telemetry - replaced + register: result + cisco.nxos.nxos_telemetry: &id002 + state: replaced + config: + certificate: + key: /bootflash/new_server.crt + hostname: newhost.example.com + vrf: management + compression: gzip + destination_groups: + - id: 2 + destination: + ip: 192.168.0.1 + port: 65001 + protocol: grpc + encoding: gpb + + - id: 2 + destination: + ip: 192.168.0.3 + port: 55001 + protocol: grpc + encoding: gpb + sensor_groups: + - id: 100 + data_source: NX-API + path: + name: '"show bgp l2vpn evpn summary"' + depth: unbounded + query_condition: foo + filter_condition: foo + subscriptions: + - id: 99 + destination_group: 2 + sensor_group: + id: 100 + sample_interval: 2000 + + - ansible.builtin.assert: + that: + - result.changed == true + - result.before|length == {{ dict_facts_length }} + - result.before.certificate|length == 2 + - result.before.destination_groups|length == 7 + - result.before.sensor_groups|length == 8 + - result.before.subscriptions|length == 10 + - "'telemetry' in result.commands" + - "'no subscription 55' in result.commands" + - "'subscription 99' in result.commands" + - "'no dst-grp 99' in result.commands" + - "'no snsr-grp 8 sample-interval 90000' in result.commands" + - "'no snsr-grp 77 sample-interval 2000' in result.commands" + - "'no subscription 44' in result.commands" + - "'no sensor-group 55' in result.commands" + - "'no sensor-group 8' in result.commands" + - "'no sensor-group 2' in result.commands" + - "'no sensor-group 77' in result.commands" + - "'no destination-group 99' in result.commands" + - "'no destination-group 10' in result.commands" + - "'destination-group 2' in result.commands" + - "'no ip address 192.168.0.1 port 50001 protocol grpc encoding gpb' in result.commands" + - "'no ip address 192.168.0.2 port 60001 protocol grpc encoding gpb' in result.commands" + - "'destination-group 2' in result.commands" + - "'ip address 192.168.0.1 port 65001 protocol grpc encoding gpb' in result.commands" + - "'ip address 192.168.0.3 port 55001 protocol grpc encoding gpb' in result.commands" + - "'sensor-group 100' in result.commands" + - result.commands is search("path .*show bgp l2vpn evpn summary.* depth unbounded query-condition foo filter-condition foo") + - "'data-source NX-API' in result.commands" + - "'subscription 99' in result.commands" + - "'snsr-grp 100 sample-interval 2000' in result.commands" + - "'certificate /bootflash/new_server.crt newhost.example.com' in result.commands" + - "'destination-profile' in result.commands" + - "'use-vrf management' in result.commands" + - result.commands|length == {{ command_list_length }} + + - ansible.builtin.assert: + that: + - "'no source-interface loopback55' in result.commands" + when: imagetag and (major_version is version_compare('9.1', 'ge')) + + - ansible.builtin.assert: + that: + - (ansible_facts.network_resources.telemetry|dict2items)|symmetric_difference(result.before|dict2items)|length == 0 + + - name: Gather telemetry facts after changes + cisco.nxos.nxos_facts: *id001 + + - ansible.builtin.assert: + that: + - (ansible_facts.network_resources.telemetry|dict2items)|symmetric_difference(result.after|dict2items)|length == 0 + + - name: Telemetry - replaced - idempotence + register: result + cisco.nxos.nxos_telemetry: *id002 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + always: + - name: Teardown + ignore_errors: true + cisco.nxos.nxos_feature: *id003 + + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_telemetry replaced sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/vars/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/vars/main.yaml new file mode 100644 index 00000000..92825d4d --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_telemetry/vars/main.yaml @@ -0,0 +1,25 @@ +--- +gathered: + destination_groups: + - destination: + encoding: gpb + ip: 192.168.0.1 + port: "50001" + protocol: grpc + id: "2" + - destination: + encoding: gpb + ip: 192.168.0.2 + port: "60001" + protocol: grpc + id: "2" + - id: "10" + sensor_groups: + - id: "2" + - id: "8" + subscriptions: + - id: "100" + - id: "100" + sensor_group: + id: "8" + sample_interval: "15000" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld/tasks/main.yaml new file mode 100644 index 00000000..c9e70304 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld/tasks/main.yaml @@ -0,0 +1,12 @@ +--- +- name: Run the CLI and NX-API tests + block: + - name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + always: + - name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld/tests/common/sanity.yaml new file mode 100644 index 00000000..114792d0 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld/tests/common/sanity.yaml @@ -0,0 +1,100 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_udld sanity test + +- name: Set a fact for 'udld_run' + ansible.builtin.set_fact: + udld_run: true + +- name: Set a fact for 'udld_run' + ansible.builtin.set_fact: + udld_run: false + when: ((platform is search('N9K-F')) and (imagetag and (imagetag is version_compare('F3', 'lt')))) + +- name: Set a fact for 'udld_run' + ansible.builtin.set_fact: + udld_run: false + when: titanium + +- block: + - name: Enable 'feature udld' + cisco.nxos.nxos_feature: + feature: udld + state: enabled + + - name: Configure udld + register: result + cisco.nxos.nxos_udld: &id001 + aggressive: enabled + msg_time: 20 + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Check idempotence + register: result + cisco.nxos.nxos_udld: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Reset udld + cisco.nxos.nxos_udld: + reset: true + + - name: Configure udld2 + register: result + cisco.nxos.nxos_udld: &id003 + aggressive: disabled + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_udld: *id003 + + - ansible.builtin.assert: *id004 + + - name: Configure udld3 + register: result + cisco.nxos.nxos_udld: &id005 + msg_time: default + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_udld: *id005 + + - ansible.builtin.assert: *id004 + + - name: Configure udld again + register: result + cisco.nxos.nxos_udld: *id001 + + - ansible.builtin.assert: *id002 + + - name: Remove udld configuration + register: result + cisco.nxos.nxos_udld: &id006 + state: absent + + - ansible.builtin.assert: *id002 + + - name: Check idempotence + register: result + cisco.nxos.nxos_udld: *id006 + + - ansible.builtin.assert: *id004 + when: udld_run + always: + - name: Disable udld + ignore_errors: true + cisco.nxos.nxos_feature: + feature: udld + state: disabled + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_udld sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld_interface/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld_interface/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld_interface/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld_interface/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld_interface/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld_interface/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld_interface/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld_interface/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld_interface/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld_interface/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld_interface/tasks/main.yaml new file mode 100644 index 00000000..c9e70304 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld_interface/tasks/main.yaml @@ -0,0 +1,12 @@ +--- +- name: Run the CLI and NX-API tests + block: + - name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + always: + - name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld_interface/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld_interface/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld_interface/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld_interface/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld_interface/tests/common/sanity.yaml new file mode 100644 index 00000000..9ad5f697 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_udld_interface/tests/common/sanity.yaml @@ -0,0 +1,121 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_udld_interface sanity test + +- name: Set a fact for 'udld_run' + ansible.builtin.set_fact: + udld_run: true + +- name: Set a fact for 'udld_enable' + ansible.builtin.set_fact: + udld_enable: true + +- name: Set a fact for 'udld_run' + ansible.builtin.set_fact: + udld_run: false + when: ((platform is search('N9K-F')) and (imagetag and (imagetag is version_compare('F3', 'lt')))) + +- name: Set a fact for 'udld_run' + ansible.builtin.set_fact: + udld_run: false + when: titanium + +- name: Set a fact for 'udld_enable' + ansible.builtin.set_fact: + udld_enable: false + when: imagetag and imagetag is search("N1") + +- name: Set a fact for 'intname' + ansible.builtin.set_fact: + intname: "{{ nxos_int1 }}" + +- block: + - name: Enable 'feature udld' + cisco.nxos.nxos_feature: + feature: udld + state: enabled + + - name: Put the interface into default state + cisco.nxos.nxos_config: + commands: + - default interface {{intname}} + match: none + + - name: Ensure interface is configured to be in aggressive mode + register: result + cisco.nxos.nxos_udld_interface: &id001 + interface: "{{ intname }}" + mode: aggressive + state: present + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Conf1 idempotence + register: result + cisco.nxos.nxos_udld_interface: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - block: + - name: ensure interface has mode enabled + register: result + cisco.nxos.nxos_udld_interface: &id003 + interface: "{{ intname }}" + mode: enabled + state: present + + - assert: *id002 + + - name: Conf2 Idempotence + register: result + cisco.nxos.nxos_udld_interface: *id003 + + - assert: *id004 + + - name: ensure interface has mode aggressive + register: result + cisco.nxos.nxos_udld_interface: *id001 + + - assert: *id002 + + - name: Conf1 Idempotence + register: result + cisco.nxos.nxos_udld_interface: *id001 + + - assert: *id004 + + - name: ensure interface has mode disabled + register: result + cisco.nxos.nxos_udld_interface: &id005 + interface: "{{ intname }}" + mode: disabled + state: present + + - assert: *id002 + + - name: Conf3 Idempotence + register: result + cisco.nxos.nxos_udld_interface: *id005 + + - assert: *id004 + when: udld_enable + + - name: Remove the configuration + cisco.nxos.nxos_udld_interface: + interface: "{{ intname }}" + mode: enabled + state: absent + when: udld_run + always: + - name: Disable udld + ignore_errors: true + cisco.nxos.nxos_feature: + feature: udld + state: disabled + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_udld_interface sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_user/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_user/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_user/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_user/meta/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_user/meta/main.yaml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_user/meta/main.yaml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_user/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_user/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_user/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_user/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_user/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_user/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_user/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_user/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_user/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_user/tests/common/auth.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_user/tests/common/auth.yaml new file mode 100644 index 00000000..99903b6b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_user/tests/common/auth.yaml @@ -0,0 +1,45 @@ +--- +- block: + - name: Create user with password + cisco.nxos.nxos_user: + name: auth_user + role: network-operator + state: present + configured_password: pasS!123 + + - name: Test login + ansible.builtin.expect: + command: >- + ssh auth_user@{{ ansible_ssh_host }} + -p {{ ansible_ssh_port|default(22) }} + -o UserKnownHostsFile=/dev/null + -o StrictHostKeyChecking=no + -o PubkeyAuthentication=no + show version + responses: + (?i)password: pasS!123 + + - name: Test login with invalid password (should fail) + ansible.builtin.expect: + command: >- + ssh auth_user@{{ ansible_ssh_host }} + -p {{ ansible_ssh_port|default(22) }} + -o UserKnownHostsFile=/dev/null + -o StrictHostKeyChecking=no + -o PubkeyAuthentication=no + show version + responses: + (?i)password: badpass + ignore_errors: true + register: results + + - name: Check that attempt failed + ansible.builtin.assert: + that: + - results.failed + always: + - name: Delete user + register: result + cisco.nxos.nxos_user: + name: auth_user + state: absent diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_user/tests/common/basic.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_user/tests/common/basic.yaml new file mode 100644 index 00000000..2ab31ec3 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_user/tests/common/basic.yaml @@ -0,0 +1,145 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_user basic test + +- name: Remove old entries of user + cisco.nxos.nxos_user: &rem + aggregate: + - name: ansibletest1 + + - name: ansibletest2 + + - name: ansibletest3 + + - name: ansibletest_failed + + - name: ansibletest_warn + + - name: ansibletest_role + state: absent + +- name: Create user + register: result + cisco.nxos.nxos_user: + name: ansibletest1 + roles: network-operator + state: present + +- ansible.builtin.debug: + msg: "{{result}}" + +- ansible.builtin.assert: + that: + - result.changed == true + - '"username" in result.commands[0]' + - '"role network-operator" in result.commands[0]' + +- name: Collection of users + register: result + cisco.nxos.nxos_user: + aggregate: + - name: ansibletest2 + + - name: ansibletest3 + state: present + roles: network-admin + +- ansible.builtin.assert: + that: + - result.changed == true + +- cisco.nxos.nxos_command: + commands: show password strength-check + register: pwd + +- name: Set a fact for 'pwdchck' + ansible.builtin.set_fact: + pwdchck: "{{ True if pwd is search('enabled') else False }}" + +- name: Enable password check (if disabled by default) for failure test + cisco.nxos.nxos_config: &enable + lines: password strength-check + when: not pwdchck + +- name: Attempt to create user with weak password with pwd check enabled (should fail) + cisco.nxos.nxos_user: + name: ansibletest_failed + configured_password: abc + register: result + ignore_errors: true + +- ansible.builtin.assert: + that: + - result.failed == True + - result.msg is search('Wrong Password') + +- name: Disable password check (will be always enabled at this stage) for warnings test + cisco.nxos.nxos_config: + lines: no password strength-check + +- name: Attempt to create user with weak password without pwd check enabled (should warn) + cisco.nxos.nxos_user: + name: ansibletest_warn + configured_password: abc + register: result + +- ansible.builtin.assert: + that: + - result.changed == True + - result.failed == False + - '"Minimum recommended length of 8 characters" in result.warnings[1]' + - '"Password should contain characters from at least three of the following classes:" in result.warnings[2]' + - '"it is WAY too short" in result.warnings[3]' + - '"Configuration accepted because password strength check is disabled" in result.warnings[4]' + +- name: Enable password check (if that was the default) + cisco.nxos.nxos_config: *enable + when: pwdchck + +- name: Create a custom role + cisco.nxos.nxos_config: + lines: + - role name customrole + +- name: Attempt to create a user with a valid custom role + cisco.nxos.nxos_user: + name: ansibletest_role + role: customrole + state: present + register: result + +- ansible.builtin.assert: + that: + - result.changed == True + - result.failed == False + - '"username ansibletest_role role customrole" in result.commands' + +- name: Attempt to create user with invalid role (should fail) + cisco.nxos.nxos_user: + name: ansibletest_role + role: invalid_role + state: present + register: result + ignore_errors: true + +- ansible.builtin.assert: + that: + - result.failed == True + - '"invalid role specified" in result.msg' + +- name: Teardown + register: result + cisco.nxos.nxos_user: *rem + +- ansible.builtin.assert: + that: + - result.changed == true + - '"no username" in result.commands[0]' + +- name: Delete custom role + cisco.nxos.nxos_config: + lines: + - no role name customrole + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_user basic test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_user/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_user/tests/common/sanity.yaml new file mode 100644 index 00000000..fcf773c6 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_user/tests/common/sanity.yaml @@ -0,0 +1,99 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_user parameter test + +- name: Set a fact for 'idem' + ansible.builtin.set_fact: + idem: true + +- name: Set a fact for 'idem' + ansible.builtin.set_fact: + idem: false + when: ((platform is search('N7K')) and (imagetag and imagetag is search("D1"))) + +- block: + - name: Create user + register: result + cisco.nxos.nxos_user: &id001 + name: netend + configured_password: Hello!23$ + update_password: on_create + roles: network-operator + state: present + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - block: + - name: conf idempotency + register: result + cisco.nxos.nxos_user: *id001 + + - assert: &id004 + that: + - result.changed == false + when: idem + + - name: Remove user + register: result + cisco.nxos.nxos_user: &id003 + name: netend + state: absent + + - ansible.builtin.assert: *id002 + + - name: Remove idempotency + register: result + cisco.nxos.nxos_user: *id003 + + - ansible.builtin.assert: *id004 + + - ansible.builtin.debug: + msg: skipping sshkey test as the key needs to be created on the server first + + - name: Collection of users + register: result + cisco.nxos.nxos_user: &id005 + users: + - name: test1 + + - name: test2 + configured_password: Hello!23$ + update_password: on_create + state: present + roles: + - network-admin + - network-operator + + - ansible.builtin.assert: *id002 + + - block: + - name: users idempotency + register: result + cisco.nxos.nxos_user: *id005 + + - assert: *id004 + when: idem + + - name: Teardown + register: result + cisco.nxos.nxos_user: &id006 + name: "{{ ansible_user }}" + purge: true + + - ansible.builtin.assert: *id002 + + - name: Teardown idempotency + register: result + cisco.nxos.nxos_user: *id006 + + - ansible.builtin.assert: *id004 + always: + - name: Teardown + register: result + ignore_errors: true + cisco.nxos.nxos_user: *id006 + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_user parameter test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/defaults/main.yaml new file mode 100644 index 00000000..871ea460 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "[^_].*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/fixtures/parsed.cfg b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/fixtures/parsed.cfg new file mode 100644 index 00000000..b3ae7a1c --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/fixtures/parsed.cfg @@ -0,0 +1,67 @@ +{ + "TABLE_vlanbrief": { + "ROW_vlanbrief": [ + { + "vlanshowbr-vlanid": "1", + "vlanshowbr-vlanid-utf": "1", + "vlanshowbr-vlanname": "default", + "vlanshowbr-vlanstate": "active", + "vlanshowbr-shutstate": "noshutdown" + }, + { + "vlanshowbr-vlanid": "5", + "vlanshowbr-vlanid-utf": "5", + "vlanshowbr-vlanname": "vlan5", + "vlanshowbr-vlanstate": "suspend", + "vlanshowbr-shutstate": "noshutdown" + }, + { + "vlanshowbr-vlanid": "6", + "vlanshowbr-vlanid-utf": "6", + "vlanshowbr-vlanname": "VLAN0006", + "vlanshowbr-vlanstate": "active", + "vlanshowbr-shutstate": "noshutdown" + }, + { + "vlanshowbr-vlanid": "7", + "vlanshowbr-vlanid-utf": "7", + "vlanshowbr-vlanname": "vlan7", + "vlanshowbr-vlanstate": "active", + "vlanshowbr-shutstate": "noshutdown" + } + ] + }, + "TABLE_mtuinfo": { + "ROW_mtuinfo": [ + { + "vlanshowinfo-vlanid": "1", + "vlanshowinfo-media-type": "enet", + "vlanshowinfo-vlanmode": "ce-vlan" + }, + { + "vlanshowinfo-vlanid": "5", + "vlanshowinfo-media-type": "enet", + "vlanshowinfo-vlanmode": "ce-vlan" + }, + { + "vlanshowinfo-vlanid": "6", + "vlanshowinfo-media-type": "enet", + "vlanshowinfo-vlanmode": "ce-vlan" + }, + { + "vlanshowinfo-vlanid": "7", + "vlanshowinfo-media-type": "enet", + "vlanshowinfo-vlanmode": "ce-vlan" + } + ] + } +} + + +vlan 1,5-7 +vlan 5 + state suspend + name vlan5 +vlan 7 + name vlan7 + vn-segment 100 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/meta/main.yml new file mode 100644 index 00000000..23d65c7e --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/meta/main.yml @@ -0,0 +1,2 @@ +--- +dependencies: [] diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tasks/cli.yaml new file mode 100644 index 00000000..9e4fb34b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + use_regex: true + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tests/common/_populate_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tests/common/_populate_config.yaml new file mode 100644 index 00000000..63d297e1 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tests/common/_populate_config.yaml @@ -0,0 +1,14 @@ +--- +- name: Populate configuration + cisco.nxos.nxos_config: + lines: + - "feature vn-segment-vlan-based" + - "vlan 5" + - "name vlan5" + - "state suspend" + - "vlan 6" + - "state active" + - "vlan 7" + - "name vlan7" + - "vn-segment 190" + - "shutdown" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tests/common/_remove_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tests/common/_remove_config.yaml new file mode 100644 index 00000000..0fc5ff73 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tests/common/_remove_config.yaml @@ -0,0 +1,7 @@ +--- +- name: Remove configuration + cisco.nxos.nxos_config: + lines: + - "no vlan 2-100" + - "no feature vn-segment-vlan-based" + ignore_errors: true diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tests/common/deleted.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tests/common/deleted.yaml new file mode 100644 index 00000000..85dfd515 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tests/common/deleted.yaml @@ -0,0 +1,50 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_vlans deleted integration tests connection={{ ansible_connection }} + +- name: Setup + cisco.nxos.nxos_config: + lines: + - "no vlan 2-100" + - "vlan 5" + - "vlan 6" + +- block: + - name: Gather vlans facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: vlans + + - name: Deleted + register: result + cisco.nxos.nxos_vlans: &id001 + config: + - vlan_id: 5 + - vlan_id: 6 + state: deleted + + - ansible.builtin.assert: + that: + - result.before|length == ansible_facts.network_resources.vlans|length + - result.after|length == 1 + - result.changed == true + - "'no vlan 5' in result.commands" + - "'no vlan 6' in result.commands" + - result.commands|length == 2 + + - name: Idempotence - deleted + register: result + cisco.nxos.nxos_vlans: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + always: + - name: Teardown + cisco.nxos.nxos_config: + lines: + - "no vlan 5" + - "no vlan 6" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tests/common/empty_config.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tests/common/empty_config.yaml new file mode 100644 index 00000000..1f8b1042 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tests/common/empty_config.yaml @@ -0,0 +1,61 @@ +--- +- ansible.builtin.debug: + msg: START nxos_vlans empty_config integration tests on connection={{ ansible_connection }} + +- name: Merged with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_vlans: + config: + state: merged + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_vlans: + config: + state: replaced + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Overridden with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_vlans: + config: + state: overridden + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Rendered with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_vlans: + config: + state: rendered + +- ansible.builtin.assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' + +- name: Parsed with empty configuration should give appropriate error message + register: result + ignore_errors: true + cisco.nxos.nxos_vlans: + running_config: + state: parsed + +- ansible.builtin.assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state parsed' + +- ansible.builtin.debug: + msg: END nxos_vlans empty_config integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tests/common/gathered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tests/common/gathered.yaml new file mode 100644 index 00000000..e46bf10e --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tests/common/gathered.yaml @@ -0,0 +1,21 @@ +--- +- ansible.builtin.debug: + msg: START nxos_vlans gathered integration tests on connection={{ ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + - name: Gather vlans facts from the device using nxos_vlans + register: result + cisco.nxos.nxos_vlans: + state: gathered + + - ansible.builtin.assert: + that: "{{ result['gathered'] | symmetric_difference(gathered) |length == 0 }}" + always: + - ansible.builtin.include_tasks: _remove_config.yaml + + - ansible.builtin.debug: + msg: END nxos_vlans gathered integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tests/common/merged.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tests/common/merged.yaml new file mode 100644 index 00000000..3c3c8e5f --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tests/common/merged.yaml @@ -0,0 +1,56 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_vlans merged integration tests connection={{ ansible_connection }} + +- name: Setup + cisco.nxos.nxos_config: &id002 + lines: + - "no vlan 2-100" + +- block: + - name: Merged + register: result + cisco.nxos.nxos_vlans: &id001 + config: + - vlan_id: 5 + name: vlan5 + + - vlan_id: 6 + name: vlan6 + state: suspend + state: merged + + - ansible.builtin.assert: + that: + - result.changed == true + # default vlan + - result.before|length == 1 + - "'vlan 5' in result.commands" + - "'name vlan5' in result.commands" + - "'vlan 6' in result.commands" + - "'name vlan6' in result.commands" + - "'state suspend' in result.commands" + - result.commands|length == 5 + + - name: Gather vlans facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: vlans + + - ansible.builtin.assert: + that: + - result.after|length == ansible_facts.network_resources.vlans|length + + - name: Idempotence - merged + register: result + cisco.nxos.nxos_vlans: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + always: + - name: Teardown + cisco.nxos.nxos_config: *id002 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tests/common/overridden.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tests/common/overridden.yaml new file mode 100644 index 00000000..38690794 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tests/common/overridden.yaml @@ -0,0 +1,68 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_vlans overridden integration tests connection={{ ansible_connection }} + +- name: Setup1 + cisco.nxos.nxos_config: &id003 + lines: + - "no vlan 2-100" + +- block: + - name: Setup + cisco.nxos.nxos_config: + lines: + - "vlan 5" + - " name test-vlan5" + - " state suspend" + - "vlan 6" + + - name: Gather vlans facts + cisco.nxos.nxos_facts: &id001 + gather_subset: + - "!all" + - "!min" + gather_network_resources: vlans + + - name: Set default VLAN (vlan1) configuration and configuration to revert + ansible.builtin.set_fact: + default_vlan: "{{ ansible_facts.network_resources.vlans|selectattr('vlan_id', 'equalto', 1)|list }}" + config_to_override: + - vlan_id: 9 + name: test-vlan9 + enabled: false + + - name: Overridden + register: result + cisco.nxos.nxos_vlans: &id002 + config: "{{ default_vlan + config_to_override }}" + state: overridden + + - ansible.builtin.assert: + that: + - result.before|length == ansible_facts.network_resources.vlans|length + - result.changed == true + - "'no vlan 5' in result.commands" + - "'no vlan 6' in result.commands" + - "'vlan 9' in result.commands" + - "'name test-vlan9' in result.commands" + - "'shutdown' in result.commands" + - result.commands|length == 5 + + - name: Gather vlans post facts + cisco.nxos.nxos_facts: *id001 + + - ansible.builtin.assert: + that: + - result.after|length == ansible_facts.network_resources.vlans|length + + - name: Idempotence - overridden + register: result + cisco.nxos.nxos_vlans: *id002 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + always: + - name: Teardown + cisco.nxos.nxos_config: *id003 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tests/common/parsed.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tests/common/parsed.yaml new file mode 100644 index 00000000..4bb03d42 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tests/common/parsed.yaml @@ -0,0 +1,16 @@ +--- +- ansible.builtin.debug: + msg: START nxos_vlans parsed integration tests on connection={{ ansible_connection }} + +- block: + - name: Use parsed state to convert externally supplied configuration to structured format + register: result + cisco.nxos.nxos_vlans: + running_config: "{{ lookup('file', '{{ role_path }}/fixtures/parsed.cfg') }}" + state: parsed + + - ansible.builtin.assert: + that: "{{ parsed | symmetric_difference(result['parsed']) |length==0 }}" + +- ansible.builtin.debug: + msg: END nxos_vlans parsed integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tests/common/rendered.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tests/common/rendered.yaml new file mode 100644 index 00000000..87120be3 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tests/common/rendered.yaml @@ -0,0 +1,43 @@ +--- +- ansible.builtin.debug: + msg: START nxos_vlans rendered integration tests on connection={{ ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- name: Gather pre facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: "vlans" + +- block: + - name: Use rendered state to convert task input to device specific commands + register: result + cisco.nxos.nxos_vlans: + config: + - vlan_id: 5 + name: vlan5 + mapped_vni: 100 + + - vlan_id: 6 + name: vlan6 + state: suspend + state: rendered + + - ansible.builtin.assert: + that: "{{ rendered | symmetric_difference(result['rendered']) |length==0 }}" + + - name: Gather vlans facts from the device and assert that its empty + register: result + cisco.nxos.nxos_vlans: + state: gathered + + - name: Make sure that rendered task actually did not make any changes to the device + ansible.builtin.assert: + that: "{{ result['gathered'] == ansible_facts['network_resources']['vlans'] }}" + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: END nxos_vlans rendered integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tests/common/replaced.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tests/common/replaced.yaml new file mode 100644 index 00000000..f2acc3be --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tests/common/replaced.yaml @@ -0,0 +1,60 @@ +--- +- ansible.builtin.debug: + msg: Start nxos_vlans replaced integration tests connection={{ ansible_connection }} + +- name: Setup1 + cisco.nxos.nxos_config: &id003 + lines: + - "no vlan 2-100" + +- block: + - name: Setup2 + cisco.nxos.nxos_config: + lines: + - "vlan 5" + - " name test-vlan5" + - "vlan 6" + - " name test-vlan6" + + - name: Gather vlans facts + cisco.nxos.nxos_facts: &id001 + gather_subset: + - "!all" + - "!min" + gather_network_resources: vlans + + - name: Replaced + register: result + cisco.nxos.nxos_vlans: &id002 + config: + - vlan_id: 6 + state: suspend + state: replaced + + - ansible.builtin.assert: + that: + - result.before|length == ansible_facts.network_resources.vlans|length + - result.changed == true + - "'vlan 6' in result.commands" + - "'no name' in result.commands" + - "'state suspend' in result.commands" + - result.commands|length == 3 + + - name: Gather vlans post facts + cisco.nxos.nxos_facts: *id001 + + - ansible.builtin.assert: + that: + - result.after|length == ansible_facts.network_resources.vlans|length + + - name: Idempotence - replaced + register: result + cisco.nxos.nxos_vlans: *id002 + + - ansible.builtin.assert: + that: + - result.changed == false + - result.commands|length == 0 + always: + - name: Teardown + cisco.nxos.nxos_config: *id003 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tests/common/rtt.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tests/common/rtt.yaml new file mode 100644 index 00000000..fc5a6604 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/tests/common/rtt.yaml @@ -0,0 +1,65 @@ +--- +- ansible.builtin.debug: + msg: START nxos_vlans round trip integration tests on connection={{ ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- block: + - name: Apply the provided configuration (base config) + register: base_config + cisco.nxos.nxos_vlans: + config: + - vlan_id: 2 + name: test-vlan2 + enabled: false + - vlan_id: 4 + name: test-vlan3 + enabled: true + state: active + state: merged + tags: base_config + + - name: Gather vlans facts + cisco.nxos.nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: + - "vlans" + + - name: Set default VLAN (vlan1) configuration and configuration to revert + ansible.builtin.set_fact: + default_vlan: "{{ ansible_facts.network_resources.vlans|selectattr('vlan_id', 'equalto', 1)|list }}" + config_to_revert: + - vlan_id: 3 + name: test-vlan3 + enabled: true + state: suspend + - vlan_id: 5 + name: test-vlan5 + enabled: false + + - name: Apply the provided configuration (config to be reverted) + register: result + cisco.nxos.nxos_vlans: + config: "{{ config_to_revert + default_vlan }}" + state: overridden + + - ansible.builtin.assert: + that: + - result.changed == true + + - name: Revert back to base configuration using facts round trip + register: revert + cisco.nxos.nxos_vlans: + config: "{{ ansible_facts['network_resources']['vlans'] }}" + state: overridden + + - ansible.builtin.assert: + that: + - base_config['after'] == revert['after'] + always: + - ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.debug: + msg: END nxos_vlans round trip integration tests on connection={{ ansible_connection }} diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/vars/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/vars/main.yml new file mode 100644 index 00000000..8e7fb87b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vlans/vars/main.yml @@ -0,0 +1,58 @@ +--- +gathered: + - vlan_id: 1 + enabled: true + mode: "ce" + state: active + name: default + + - vlan_id: 5 + enabled: true + mode: "ce" + name: "vlan5" + state: suspend + + - vlan_id: 6 + enabled: true + mode: "ce" + state: active + + - vlan_id: 7 + enabled: false + mode: "ce" + name: "vlan7" + state: active + mapped_vni: 190 + +parsed: + - vlan_id: 1 + enabled: true + mode: "ce" + state: active + name: default + + - vlan_id: 5 + enabled: true + mode: "ce" + name: "vlan5" + state: suspend + + - vlan_id: 6 + enabled: true + mode: "ce" + state: active + + - vlan_id: 7 + enabled: true + mode: "ce" + name: "vlan7" + state: active + mapped_vni: 100 + +rendered: + - vlan 5 + - name vlan5 + - vn-segment 100 + - vlan 6 + - name vlan6 + - state suspend diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc/tasks/main.yaml new file mode 100644 index 00000000..c9e70304 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc/tasks/main.yaml @@ -0,0 +1,12 @@ +--- +- name: Run the CLI and NX-API tests + block: + - name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + always: + - name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc/tests/common/sanity.yaml new file mode 100644 index 00000000..fb073afb --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc/tests/common/sanity.yaml @@ -0,0 +1,182 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_vpc sanity test + +- block: + - name: Set a fact for 'delay_restore_orphan_port' + ansible.builtin.set_fact: + delay_restore_orphan_port: 25 + + - name: Set a fact for 'def_delay_restore_orphan_port' + ansible.builtin.set_fact: + def_delay_restore_orphan_port: default + when: platform is not search("N35|N5K|N6K") + +- block: + - name: Disable vpc for initial vpc configuration cleanup + cisco.nxos.nxos_feature: + feature: vpc + state: disabled + + - name: Enable 'feature vpc' + cisco.nxos.nxos_feature: + feature: vpc + state: enabled + + - name: Ensure NTC VRF exists on switch + cisco.nxos.nxos_vrf: + vrf: ntc + + - name: Configure vpc + register: result + cisco.nxos.nxos_vpc: &id001 + state: present + domain: 100 + pkl_dest: 192.168.100.4 + pkl_src: 10.1.100.20 + pkl_vrf: ntc + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Configure idempotence + register: result + cisco.nxos.nxos_vpc: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Configure vpc1 + register: result + cisco.nxos.nxos_vpc: &id003 + state: present + domain: 100 + role_priority: 500 + system_priority: 2000 + peer_gw: true + delay_restore: 5 + delay_restore_interface_vlan: 15 + delay_restore_orphan_port: "{{ delay_restore_orphan_port|default(omit) }}" + + - ansible.builtin.assert: *id002 + + - name: Configure idempotence + register: result + cisco.nxos.nxos_vpc: *id003 + + - ansible.builtin.assert: *id004 + + - block: + - set_fact: def_auto_recovery=False + + - set_fact: def_auto_recovery=True + when: platform is search("N7K") + + - name: auto-recovery from default to non-default + register: result + cisco.nxos.nxos_vpc: &id005 + domain: 100 + auto_recovery: "{{ not def_auto_recovery }}" + + - assert: *id002 + + - name: Conf Idempotence auto-recovery def-to-non-def + register: result + cisco.nxos.nxos_vpc: *id005 + + - assert: *id004 + + - name: auto-recovery from non-default to default + register: result + cisco.nxos.nxos_vpc: &id006 + domain: 100 + auto_recovery: "{{ def_auto_recovery }}" + + - assert: *id002 + + - name: Conf Idempotence auto-recovery non-def-to-def + register: result + cisco.nxos.nxos_vpc: *id006 + + - assert: *id004 + when: platform is search("N35|N7K|N3K-F|N9K-F") + + - name: Configure auto-recovery reload-delay + register: result + cisco.nxos.nxos_vpc: &id007 + domain: 100 + auto_recovery_reload_delay: 242 + + - ansible.builtin.assert: *id002 + + - name: Configure idempotence auto-recovery reload-delay + register: result + cisco.nxos.nxos_vpc: *id007 + + - ansible.builtin.assert: *id004 + + - name: Configure vpc2 + register: result + cisco.nxos.nxos_vpc: &id008 + state: present + domain: 100 + role_priority: default + system_priority: default + peer_gw: true + delay_restore: default + delay_restore_interface_vlan: default + delay_restore_orphan_port: "{{ def_delay_restore_orphan_port|default(omit) }}" + + - ansible.builtin.assert: *id002 + + - name: Configure idempotence + register: result + cisco.nxos.nxos_vpc: *id008 + + - ansible.builtin.assert: *id004 + + - name: Configure vpc3 + register: result + cisco.nxos.nxos_vpc: &id009 + state: present + domain: 100 + peer_gw: false + + - ansible.builtin.assert: *id002 + + - name: Configure idempotence + register: result + cisco.nxos.nxos_vpc: *id009 + + - ansible.builtin.assert: *id004 + + - name: Remove vpc + register: result + cisco.nxos.nxos_vpc: &id010 + state: absent + domain: 100 + + - ansible.builtin.assert: *id002 + + - name: Remove idempotence + register: result + cisco.nxos.nxos_vpc: *id010 + + - ansible.builtin.assert: *id004 + always: + - name: Remove VRF + ignore_errors: true + cisco.nxos.nxos_vrf: + vrf: ntc + state: absent + + - name: Disable 'feature vpc' + ignore_errors: true + cisco.nxos.nxos_feature: + feature: vpc + state: disabled + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_vpc sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc_interface/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc_interface/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc_interface/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc_interface/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc_interface/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc_interface/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc_interface/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc_interface/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc_interface/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc_interface/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc_interface/tasks/main.yaml new file mode 100644 index 00000000..c9e70304 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc_interface/tasks/main.yaml @@ -0,0 +1,12 @@ +--- +- name: Run the CLI and NX-API tests + block: + - name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + always: + - name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc_interface/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc_interface/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc_interface/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc_interface/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc_interface/tests/common/sanity.yaml new file mode 100644 index 00000000..e74930c7 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vpc_interface/tests/common/sanity.yaml @@ -0,0 +1,138 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_vpc_interface sanity test + +- block: + - name: Enable 'feature vpc' + cisco.nxos.nxos_feature: + feature: vpc + state: enabled + + - name: Create port-channel10 + cisco.nxos.nxos_config: + commands: + - interface port-channel10 + - switchport + match: none + + - name: Create port-channel11 + cisco.nxos.nxos_config: + commands: + - interface port-channel11 + - switchport + match: none + + - name: Configure vpc + cisco.nxos.nxos_vpc: + state: present + domain: 100 + role_priority: 32667 + system_priority: 2000 + pkl_dest: 192.168.100.4 + pkl_src: 10.1.100.20 + peer_gw: true + auto_recovery: false + + - name: Configure vpc port channel + register: result + cisco.nxos.nxos_vpc_interface: &id001 + portchannel: 10 + vpc: 10 + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Configure idempotence + register: result + cisco.nxos.nxos_vpc_interface: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Configure vpc port channel + register: result + when: image_version != "7.0(3)I5(1)" + cisco.nxos.nxos_vpc_interface: &id003 + portchannel: 11 + peer_link: true + + - ansible.builtin.assert: *id002 + when: image_version != "7.0(3)I5(1)" + + - name: Configure idempotence + register: result + when: image_version != "7.0(3)I5(1)" + cisco.nxos.nxos_vpc_interface: *id003 + + - ansible.builtin.assert: *id004 + when: image_version != "7.0(3)I5(1)" + + - name: Configure vpc port channel + register: result + when: image_version != "7.0(3)I5(1)" + cisco.nxos.nxos_vpc_interface: &id005 + portchannel: 11 + peer_link: false + + - ansible.builtin.assert: *id002 + when: image_version != "7.0(3)I5(1)" + + - name: Configure idempotence + register: result + when: image_version != "7.0(3)I5(1)" + cisco.nxos.nxos_vpc_interface: *id005 + + - ansible.builtin.assert: *id004 + when: image_version != "7.0(3)I5(1)" + + - name: Remove vpc port channel + register: result + cisco.nxos.nxos_vpc_interface: &id006 + portchannel: 10 + vpc: 10 + state: absent + + - ansible.builtin.assert: *id002 + + - name: Remove idempotence + register: result + cisco.nxos.nxos_vpc_interface: *id006 + + - ansible.builtin.assert: *id004 + always: + - name: Remove vpc + ignore_errors: true + cisco.nxos.nxos_vpc: + state: absent + domain: 100 + role_priority: 32667 + system_priority: 2000 + pkl_dest: 192.168.100.4 + pkl_src: 10.1.100.20 + peer_gw: true + auto_recovery: false + + - name: Remove vpc port channel + ignore_errors: true + cisco.nxos.nxos_vpc_interface: + portchannel: 10 + vpc: 10 + state: absent + + - name: Remove port channel + ignore_errors: true + cisco.nxos.nxos_config: + commands: + - no interface port-channel10 + - no interface port-channel11 + match: none + + - name: Disable 'feature vpc' + cisco.nxos.nxos_feature: + feature: vpc + state: disabled + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_vpc_interface sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf/tests/common/intent.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf/tests/common/intent.yaml new file mode 100644 index 00000000..f95da2fb --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf/tests/common/intent.yaml @@ -0,0 +1,198 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_vrf intent & aggregate test + +- name: Set a fact for 'testint1' + ansible.builtin.set_fact: + testint1: "{{ nxos_int1 }}" + +- name: Set a fact for 'testint2' + ansible.builtin.set_fact: + testint2: "{{ nxos_int2 }}" + +- name: Setup - remove VRF from interfaces used in test(part1) + ignore_errors: true + cisco.nxos.nxos_config: + lines: + - no vrf member test1 + parents: no switchport + before: interface {{ testint1 }} + +- name: Setup - remove VRF from interfaces used in test(part2) + ignore_errors: true + cisco.nxos.nxos_config: + lines: + - no vrf member test1 + parents: no switchport + before: interface {{ testint2 }} + +- name: Setup - delete VRF test1 used in test + ignore_errors: true + cisco.nxos.nxos_config: + lines: + - no vrf context test1 + +- name: Setup - remove VRF test2 used in test + ignore_errors: true + cisco.nxos.nxos_config: + lines: + - no vrf context test2 + +- name: Aggregate definitions of vrfs + register: result + cisco.nxos.nxos_vrf: &id001 + aggregate: + - name: test1 + description: Configured by Ansible + + - name: test2 + description: Testing + admin_state: down + +- ansible.builtin.assert: + that: + - result.changed == true + - '"vrf context test1" in result.commands' + - '"description Configured by Ansible" in result.commands' + - '"no shutdown" in result.commands' + - '"vrf context test2" in result.commands' + - '"description Testing" in result.commands' + - '"shutdown" in result.commands' + +- name: Aggregate definitions of vrfs(idempotence) + register: result + cisco.nxos.nxos_vrf: *id001 + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Assign interfaces to VRF (config + intent) + register: result + cisco.nxos.nxos_vrf: &id002 + name: test1 + interfaces: + - "{{ testint1 }}" + - "{{ testint2 }}" + associated_interfaces: + - "{{ testint1 }}" + - "{{ testint2 }}" + +- ansible.builtin.assert: + that: + - result.changed == true + - result.failed == false + - '"interface {{ testint1 }}" in result.commands' + - '"vrf member test1" in result.commands' + - '"interface {{ testint2 }}" in result.commands' + - '"vrf member test1" in result.commands' + +- name: Assign interfaces to vrf(idempotence) + register: result + cisco.nxos.nxos_vrf: *id002 + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Check interfaces assigned to VRF (intent) + register: result + cisco.nxos.nxos_vrf: + name: test1 + associated_interfaces: + - "{{ testint1 }}" + - "{{ testint2 }}" + +- ansible.builtin.assert: + that: + - result.failed == false + +- name: Assign interfaces to VRF (intent fail) + register: result + ignore_errors: true + cisco.nxos.nxos_vrf: + name: test1 + associated_interfaces: + - test + +- ansible.builtin.assert: + that: + - result.failed == True + +- name: Remove interface from VRF + register: result + cisco.nxos.nxos_vrf: &id003 + name: test1 + interfaces: + - "{{ testint2 }}" + +- ansible.builtin.assert: + that: + - result.changed == true + - '"interface {{ testint1 }}" in result.commands' + - '"no vrf member test1" in result.commands' + +- name: Remove interface from vrf(idempotence) + register: result + cisco.nxos.nxos_vrf: *id003 + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Delete vrfs + register: result + cisco.nxos.nxos_vrf: &id004 + aggregate: + - name: test1 + description: Configured by Ansible + + - name: test2 + description: Testing + admin_state: down + state: absent + +- ansible.builtin.assert: + that: + - result.changed == true + - '"no vrf context test1" in result.commands' + - '"no vrf context test2" in result.commands' + +- name: Delete vrfs(idempotence) + register: result + cisco.nxos.nxos_vrf: *id004 + +- ansible.builtin.assert: + that: + - result.changed == false + +- name: Setup - remove VRF from interfaces used in test(part1) + ignore_errors: true + cisco.nxos.nxos_config: + lines: + - no vrf member test1 + parents: no switchport + before: interface {{ testint1 }} + +- name: Setup - remove VRF from interfaces used in test(part2) + ignore_errors: true + cisco.nxos.nxos_config: + lines: + - no vrf member test1 + parents: no switchport + before: interface {{ testint2 }} + +- name: Setup - delete VRF test1 used in test + ignore_errors: true + cisco.nxos.nxos_config: + lines: + - no vrf context test1 + +- name: Setup - remove VRF test2 used in test + ignore_errors: true + cisco.nxos.nxos_config: + lines: + - no vrf context test2 + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_vrf intent & aggregate test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf/tests/common/sanity.yaml new file mode 100644 index 00000000..c4ef8c1c --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf/tests/common/sanity.yaml @@ -0,0 +1,122 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_vrf sanity test + +- name: Set a fact for 'intname1' + ansible.builtin.set_fact: + intname1: "{{ nxos_int1 }}" + +- name: Set a fact for 'intname2' + ansible.builtin.set_fact: + intname2: "{{ nxos_int2 }}" + +- name: Set a fact for 'rdnd' + ansible.builtin.set_fact: + rdnd: "1:2" + when: (platform is not match("N35|N7K")) and ((imagetag != 'I2')) + +- name: Set a fact for 'rdd' + ansible.builtin.set_fact: + rdd: default + when: (platform is not match("N35|N7K")) and ((imagetag != 'I2')) + +- name: Set a fact for 'vnind' + ansible.builtin.set_fact: + vnind: "5000" + when: platform is not match("N35|N7K|N3L") + +- name: Set a fact for 'vnid' + ansible.builtin.set_fact: + vnid: default + when: platform is not match("N35|N7K|N3L") + +- name: Enable 'feature bgp' + ignore_errors: true + cisco.nxos.nxos_feature: + feature: bgp + state: enabled + +- name: "Setup: enable NV overlay EVPN" + ignore_errors: true + when: platform is match("N5K|N6K") + cisco.nxos.nxos_config: + commands: + - nv overlay evpn + +- block: + - name: Ensure NTC VRF exists on switch + register: result + cisco.nxos.nxos_vrf: &id001 + vrf: ntc + admin_state: down + description: testing + vni: "{{vnind|default(omit)}}" + rd: "{{rdnd|default(omit)}}" + interfaces: + - "{{ intname1 }}" + - "{{ intname2 }}" + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Configure idempotence + register: result + cisco.nxos.nxos_vrf: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - ansible.builtin.pause: + seconds: 30 + + - name: Remove configuration + register: result + cisco.nxos.nxos_vrf: &id003 + vrf: ntc + admin_state: up + vni: "{{vnid|default(omit)}}" + rd: "{{rdd|default(omit)}}" + interfaces: default + + - ansible.builtin.assert: *id002 + + - name: Configure idempotence + register: result + cisco.nxos.nxos_vrf: *id003 + + - ansible.builtin.assert: *id004 + + - name: Ensure NTC VRF does not exist on switch + register: result + cisco.nxos.nxos_vrf: &id005 + vrf: ntc + state: absent + + - ansible.builtin.assert: *id002 + + - ansible.builtin.pause: + seconds: 30 + + - name: Remove idempotence + register: result + cisco.nxos.nxos_vrf: *id005 + + - ansible.builtin.assert: *id004 + always: + - name: "Setup: disable NV overlay EVPN" + ignore_errors: true + when: platform is match("N5K|N6K") + cisco.nxos.nxos_config: + commands: + - no nv overlay evpn + + - name: Disable 'feature bgp' + ignore_errors: true + cisco.nxos.nxos_feature: + feature: bgp + state: disabled + + - ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_vrf sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_af/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_af/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_af/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_af/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_af/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_af/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_af/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_af/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_af/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_af/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_af/tasks/main.yaml new file mode 100644 index 00000000..c9e70304 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_af/tasks/main.yaml @@ -0,0 +1,12 @@ +--- +- name: Run the CLI and NX-API tests + block: + - name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + always: + - name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_af/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_af/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_af/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_af/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_af/tests/common/sanity.yaml new file mode 100644 index 00000000..3e276fa1 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_af/tests/common/sanity.yaml @@ -0,0 +1,146 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_vrf_af sanity test + +- name: Configure 'feature bgp' + cisco.nxos.nxos_feature: + feature: bgp + state: enabled + +- name: Configure 'feature nv overlay' + ignore_errors: true + cisco.nxos.nxos_config: + commands: feature nv overlay + +- name: Configure NV overlay EVPN + ignore_errors: true + cisco.nxos.nxos_config: + commands: nv overlay evpn + +- block: + - name: Configure VRF AF ipv4 + register: result + cisco.nxos.nxos_vrf_af: &id001 + vrf: ansible + afi: ipv4 + route_target_both_auto_evpn: true + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Configure idempotence + register: result + cisco.nxos.nxos_vrf_af: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Configure VRF AF ipv6 + register: result + cisco.nxos.nxos_vrf_af: &id003 + vrf: ansible + afi: ipv6 + route_target_both_auto_evpn: true + + - ansible.builtin.assert: *id002 + + - name: Configure idempotence + register: result + cisco.nxos.nxos_vrf_af: *id003 + + - ansible.builtin.assert: *id004 + + - name: Remove router target4 + register: result + cisco.nxos.nxos_vrf_af: &id005 + vrf: ansible + afi: ipv4 + route_target_both_auto_evpn: false + + - ansible.builtin.assert: *id002 + + - name: Configure idempotence + register: result + cisco.nxos.nxos_vrf_af: *id005 + + - ansible.builtin.assert: *id004 + + - name: Remove router target6 + register: result + cisco.nxos.nxos_vrf_af: &id006 + vrf: ansible + afi: ipv6 + route_target_both_auto_evpn: false + + - ansible.builtin.assert: *id002 + + - name: Configure idempotence + register: result + cisco.nxos.nxos_vrf_af: *id006 + + - ansible.builtin.assert: *id004 + + - name: Remove VRF AF v6 + register: result + cisco.nxos.nxos_vrf_af: &id007 + vrf: ansible + afi: ipv6 + route_target_both_auto_evpn: true + state: absent + + - ansible.builtin.assert: *id002 + + - ansible.builtin.pause: + seconds: 30 + + - name: Remove idempotence + register: result + cisco.nxos.nxos_vrf_af: *id007 + + - ansible.builtin.assert: *id004 + + - name: Remove VRF AF v4 + register: result + cisco.nxos.nxos_vrf_af: &id008 + vrf: ansible + afi: ipv4 + route_target_both_auto_evpn: true + state: absent + + - ansible.builtin.assert: *id002 + + - ansible.builtin.pause: + seconds: 30 + + - name: Remove idempotence + register: result + cisco.nxos.nxos_vrf_af: *id008 + + - ansible.builtin.assert: *id004 + when: not platform is search("N35|N3L") + always: + - name: Remove VRF + ignore_errors: true + cisco.nxos.nxos_config: + commands: no vrf context ansible + + - name: Remove NV overlay EVPN + ignore_errors: true + cisco.nxos.nxos_config: + commands: no nv overlay evpn + + - name: Remove 'feature nv overlay' + ignore_errors: true + cisco.nxos.nxos_config: + commands: no feature nv overlay + + - name: Remove 'feature bgp' + ignore_errors: true + cisco.nxos.nxos_feature: + feature: bgp + state: disabled + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_vrf_af sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_interface/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_interface/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_interface/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_interface/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_interface/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_interface/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_interface/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_interface/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_interface/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_interface/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_interface/tasks/main.yaml new file mode 100644 index 00000000..c9e70304 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_interface/tasks/main.yaml @@ -0,0 +1,12 @@ +--- +- name: Run the CLI and NX-API tests + block: + - name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + always: + - name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_interface/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_interface/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_interface/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_interface/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_interface/tests/common/sanity.yaml new file mode 100644 index 00000000..dbe8baf9 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrf_interface/tests/common/sanity.yaml @@ -0,0 +1,59 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_vrf_interface sanity test + +- name: Set a fact for 'intname' + ansible.builtin.set_fact: + intname: "{{ nxos_int1 }}" + +- block: + - name: Put interface in layer 3 + cisco.nxos.nxos_config: + commands: + - no switchport + parents: + - interface {{ intname }} + match: none + + - name: Ensure VRF NTC exists on interface + register: result + cisco.nxos.nxos_vrf_interface: &id001 + vrf: ntc + interface: "{{ intname }}" + state: present + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Configure idempotence + register: result + cisco.nxos.nxos_vrf_interface: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Ensure NTC VRF does not exist on interface + register: result + cisco.nxos.nxos_vrf_interface: &id003 + vrf: ntc + interface: "{{ intname }}" + state: absent + + - ansible.builtin.assert: *id002 + + - name: Remove idempotence + register: result + cisco.nxos.nxos_vrf_interface: *id003 + + - ansible.builtin.assert: *id004 + always: + - name: Put interface in default mode + ignore_errors: true + cisco.nxos.nxos_config: + lines: default interface {{ intname }} + match: none + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_vrf_interface sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrrp/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrrp/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrrp/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrrp/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrrp/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrrp/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrrp/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrrp/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrrp/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrrp/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrrp/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrrp/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrrp/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrrp/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrrp/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrrp/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrrp/tests/common/sanity.yaml new file mode 100644 index 00000000..4e3ba70f --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vrrp/tests/common/sanity.yaml @@ -0,0 +1,133 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_vrrp sanity test + +- block: + - name: Enable interface-vlan + cisco.nxos.nxos_feature: + feature: interface-vlan + state: enabled + + - name: Enable vrrp + cisco.nxos.nxos_feature: + feature: vrrp + state: enabled + + - name: Create int VLAN 10 + cisco.nxos.nxos_config: + commands: int vlan 10 + + - name: Ensure vrrp group 100 and vip 10.1.100.1 is on vlan10 + register: result + cisco.nxos.nxos_vrrp: &id001 + interface: vlan10 + group: 100 + vip: 10.1.100.1 + admin_state: no shutdown + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Configure idempotence + register: result + cisco.nxos.nxos_vrrp: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Ensure vrrp group 100 is default + register: result + cisco.nxos.nxos_vrrp: &id003 + interface: vlan10 + group: 100 + vip: default + admin_state: default + + - ansible.builtin.assert: *id002 + + - name: Configure idempotence + register: result + cisco.nxos.nxos_vrrp: *id003 + + - ansible.builtin.assert: *id004 + + - name: Ensure removal of the vrrp group configuration + register: result + cisco.nxos.nxos_vrrp: &id005 + interface: vlan10 + group: 100 + state: absent + + - ansible.builtin.assert: *id002 + + - ansible.builtin.pause: + seconds: 30 + + - name: Remove idempotence + register: result + cisco.nxos.nxos_vrrp: *id005 + + - ansible.builtin.assert: *id004 + + - ansible.builtin.pause: + seconds: 30 + + - name: Re-config with more params + register: result + cisco.nxos.nxos_vrrp: &id006 + interface: vlan10 + group: 100 + vip: 10.1.100.1 + preempt: false + interval: 10 + priority: 130 + authentication: AUTHKEY + + - ansible.builtin.assert: *id002 + + - name: Reconfig idempotence + register: result + cisco.nxos.nxos_vrrp: *id006 + + - ansible.builtin.assert: *id004 + + - name: Re-config with defaults + register: result + cisco.nxos.nxos_vrrp: &id007 + interface: vlan10 + group: 100 + vip: default + preempt: true + interval: default + priority: default + authentication: default + + - ansible.builtin.assert: *id002 + + - name: Reconfig idempotence + register: result + cisco.nxos.nxos_vrrp: *id007 + + - ansible.builtin.assert: *id004 + always: + - name: Remove vrrp + ignore_errors: true + cisco.nxos.nxos_vrrp: *id005 + + - name: Disable interface-vlan + ignore_errors: true + cisco.nxos.nxos_config: + commands: + - no feature interface-vlan + match: none + + - name: Disable vrrp + ignore_errors: true + cisco.nxos.nxos_feature: + feature: vrrp + state: disabled + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_vrrp sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vsan/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vsan/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vsan/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vsan/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vsan/meta/main.yml new file mode 100644 index 00000000..ed97d539 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vsan/meta/main.yml @@ -0,0 +1 @@ +--- diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vsan/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vsan/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vsan/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vsan/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vsan/tasks/main.yaml new file mode 100644 index 00000000..477fbd41 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vsan/tasks/main.yaml @@ -0,0 +1,19 @@ +--- +- name: Check platform type and skip if not MDS + register: result + cisco.nxos.nxos_command: + commands: show version | grep MDS + +- name: Set skip_test flag to false + ansible.builtin.set_fact: + skip_test: false + +- name: Set skip_test flag to true if not MDS + ansible.builtin.set_fact: + skip_test: true + when: result.stdout[0] is not search('MDS') + +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: cli + when: not skip_test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vsan/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vsan/tests/common/sanity.yaml new file mode 100644 index 00000000..fd6a1f21 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vsan/tests/common/sanity.yaml @@ -0,0 +1,73 @@ +--- +- ansible.builtin.debug: + msg: "START nxos_vsan sanity test with connection={{ ansible_connection }} " + +- ansible.builtin.debug: + msg: >- + Using vsans {{ vsan1 }}, {{ vsan2 }} for running this sanity test, + please make sure these are not used in the setup, + these will be deleted after the tests + +- block: + - name: Setup - remove VSAN if configured + ignore_errors: true + cisco.nxos.nxos_vsan: &id002 + vsan: + - id: "{{ vsan1 | int }}" + remove: true + + - id: "{{ vsan2 | int }}" + remove: true + + - name: Configure VSAN + register: result + cisco.nxos.nxos_vsan: &id001 + vsan: + - id: "{{ vsan1 | int }}" + name: vsan-SAN-A + suspend: true + interface: + - "{{intA1}}" + remove: false + + - id: "{{ vsan2 | int }}" + name: vsan-SAN-B + interface: + - "{{intB1}}" + remove: false + + - ansible.builtin.assert: + that: + - result.changed == true + + - ansible.builtin.assert: + that: + - result.commands == desired + vars: + desired: + - "terminal dont-ask" + - "vsan database" + - "vsan 922" + - "vsan 922 name vsan-SAN-A" + - "vsan 922 suspend" + - "vsan 922 interface fc1/1" + - "vsan 923" + - "vsan 923 name vsan-SAN-B" + - "no vsan 923 suspend" + - "vsan 923 interface fc1/2" + - "no terminal dont-ask" + + - name: Idempotence check + register: result + cisco.nxos.nxos_vsan: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + + - ansible.builtin.assert: + that: + - result.commands == [] + always: + - name: Remove VSAN configuration + cisco.nxos.nxos_vsan: *id002 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vsan/vars/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vsan/vars/main.yml new file mode 100644 index 00000000..41b2fdb0 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vsan/vars/main.yml @@ -0,0 +1,5 @@ +--- +vsan1: 922 +vsan2: 923 +intA1: fc1/1 # noqa var-naming +intB1: fc1/2 # noqa var-naming diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_domain/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_domain/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_domain/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_domain/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_domain/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_domain/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_domain/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_domain/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_domain/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_domain/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_domain/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_domain/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_domain/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_domain/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_domain/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_domain/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_domain/tests/common/sanity.yaml new file mode 100644 index 00000000..6c2a43f4 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_domain/tests/common/sanity.yaml @@ -0,0 +1,50 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_vtp_domain sanity test + +- name: Set a fact for 'vtp_run' + ansible.builtin.set_fact: + vtp_run: true + +- name: Set a fact for 'vtp_run' + ansible.builtin.set_fact: + vtp_run: false + when: platform is search('N3K-F|N9K-F') + +- block: + - name: Disable 'feature vtp' + ignore_errors: true + cisco.nxos.nxos_feature: + feature: vtp + state: disabled + + - name: Enable 'feature vtp' + cisco.nxos.nxos_feature: + feature: vtp + state: enabled + + - name: Configure VTP domain + register: result + cisco.nxos.nxos_vtp_domain: &id001 + domain: ntc + + - ansible.builtin.assert: + that: + - result.changed == true + + - name: Configure idempotence + register: result + cisco.nxos.nxos_vtp_domain: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + when: vtp_run + always: + - name: Disable 'feature vtp' + cisco.nxos.nxos_feature: + feature: vtp + state: disabled + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_vtp_domain sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_password/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_password/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_password/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_password/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_password/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_password/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_password/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_password/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_password/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_password/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_password/tasks/main.yaml new file mode 100644 index 00000000..c9e70304 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_password/tasks/main.yaml @@ -0,0 +1,12 @@ +--- +- name: Run the CLI and NX-API tests + block: + - name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + always: + - name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_password/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_password/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_password/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_password/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_password/tests/common/sanity.yaml new file mode 100644 index 00000000..a0f0e1f2 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_password/tests/common/sanity.yaml @@ -0,0 +1,69 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_vtp_password sanity test + +- name: Set a fact for 'vtp_run' + ansible.builtin.set_fact: + vtp_run: true + +- name: Set a fact for 'vtp_run' + ansible.builtin.set_fact: + vtp_run: false + when: platform is search('N3K-F|N9K-F') + +- block: + - name: Disable 'feature vtp' + ignore_errors: true + cisco.nxos.nxos_feature: + feature: vtp + state: disabled + + - name: Enable 'feature vtp' + cisco.nxos.nxos_feature: + feature: vtp + state: enabled + + - name: Configure VTP domain + cisco.nxos.nxos_vtp_domain: + domain: testing + + - name: Configure VTP password + register: result + cisco.nxos.nxos_vtp_password: &id001 + vtp_password: ntc + state: present + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Configure idempotence + register: result + cisco.nxos.nxos_vtp_password: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Remove VTP password + register: result + cisco.nxos.nxos_vtp_password: &id003 + vtp_password: ntc + state: absent + + - ansible.builtin.assert: *id002 + + - name: Remove idempotence + register: result + cisco.nxos.nxos_vtp_password: *id003 + + - ansible.builtin.assert: *id004 + when: vtp_run + always: + - name: Disable 'feature vtp' + cisco.nxos.nxos_feature: + feature: vtp + state: disabled + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_vtp_password sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_version/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_version/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_version/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_version/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_version/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_version/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_version/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_version/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_version/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_version/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_version/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_version/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_version/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_version/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_version/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_version/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_version/tests/common/sanity.yaml new file mode 100644 index 00000000..248c5c47 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vtp_version/tests/common/sanity.yaml @@ -0,0 +1,54 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_vtp_version sanity test + +- name: Set a fact for 'vtp_run' + ansible.builtin.set_fact: + vtp_run: true + +- name: Set a fact for 'vtp_run' + ansible.builtin.set_fact: + vtp_run: false + when: platform is search('N3K-F|N9K-F') + +- block: + - name: Disable 'feature vtp' + ignore_errors: true + cisco.nxos.nxos_feature: + feature: vtp + state: disabled + + - name: Enable 'feature vtp' + cisco.nxos.nxos_feature: + feature: vtp + state: enabled + + - name: Configure supporting VTP domain + cisco.nxos.nxos_vtp_domain: + domain: foo + + - name: Configure VTP version + register: result + cisco.nxos.nxos_vtp_version: &id001 + version: 2 + + - ansible.builtin.assert: + that: + - result.changed == true + + - name: Configure idempotence + register: result + cisco.nxos.nxos_vtp_version: *id001 + + - ansible.builtin.assert: + that: + - result.changed == false + when: vtp_run | bool + always: + - name: Disable 'feature vtp' + cisco.nxos.nxos_feature: + feature: vtp + state: disabled + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_vtp_version sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep/tasks/main.yaml new file mode 100644 index 00000000..a1da90e5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep/tasks/main.yaml @@ -0,0 +1,10 @@ +--- +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep/tasks/platform/n7k/cleanup.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep/tasks/platform/n7k/cleanup.yaml new file mode 100644 index 00000000..6de2a7ac --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep/tasks/platform/n7k/cleanup.yaml @@ -0,0 +1,22 @@ +--- +- name: Unconfigure VDC setting limit-resource module-type f3 + ignore_errors: true # noqa ignore-errors + cisco.nxos.nxos_config: + commands: + - terminal dont-ask ; vdc {{ vdcid }} ; no limit-resource module-type f3 + match: none + +- name: Previous command is asynchronous and can take a while. allow time for it to complete + ansible.builtin.pause: + seconds: 45 + +- name: Configure VDC setting allocate interface unallocated-interfaces + ignore_errors: true # noqa ignore-errors + cisco.nxos.nxos_config: + commands: + - terminal dont-ask ; vdc {{ vdcid }} ; allocate interface unallocated-interfaces + match: none + +- name: Previous command is asynchronous can take a while. allow time for it to complete + ansible.builtin.pause: + seconds: 45 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep/tasks/platform/n7k/setup.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep/tasks/platform/n7k/setup.yaml new file mode 100644 index 00000000..52a8aad8 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep/tasks/platform/n7k/setup.yaml @@ -0,0 +1,32 @@ +--- +- name: Get default VDC id + register: vdcout + cisco.nxos.nxos_command: + commands: + - show vdc current-vdc | json + +- name: Set a fact for 'vdcid' + ansible.builtin.set_fact: + vdcid: "{{ vdcout.stdout_lines[0].name }}" + +- name: Configure VDC setting limit-resource module-type f3 + ignore_errors: true # noqa ignore-errors + cisco.nxos.nxos_config: + commands: + - terminal dont-ask ; vdc {{ vdcid }} ; limit-resource module-type f3 + match: none + +- name: Previous command is asynchronous and can take a while. allow time for it to complete + ansible.builtin.pause: + seconds: 45 + +- name: Configure VDC setting allocate interface unallocated-interfaces + ignore_errors: true # noqa ignore-errors + cisco.nxos.nxos_config: + commands: + - terminal dont-ask ; vdc {{ vdcid }} ; allocate interface unallocated-interfaces + match: none + +- name: Previous command is asynchronous and can take a while. allow time for it to complete + ansible.builtin.pause: + seconds: 45 diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep/tests/common/multisite.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep/tests/common/multisite.yaml new file mode 100644 index 00000000..b2ffc5a1 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep/tests/common/multisite.yaml @@ -0,0 +1,113 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_vxlan_vtep multisite sanity test + +- name: Enable 'feature nv overlay' - multisite + cisco.nxos.nxos_config: + commands: + - feature nv overlay + match: none + +- name: Enable NV overlay EVPN - multisite + when: platform is search('N9K') + cisco.nxos.nxos_config: + lines: + - nv overlay evpn + +- name: Enable multisite border gateway - multisite + ignore_errors: true + register: multiout + cisco.nxos.nxos_config: + lines: + - evpn multisite border-gateway 10 + +- block: + - name: Configure vxlan_vtep + register: result + cisco.nxos.nxos_vxlan_vtep: &id001 + interface: nve1 + description: abcd + host_reachability: true + source_interface: Loopback0 + source_interface_hold_down_time: 30 + global_ingress_replication_bgp: true + multisite_border_gateway_interface: Loopback10 + shutdown: false + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Configure idempotence + register: result + cisco.nxos.nxos_vxlan_vtep: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Reset vxlan_vtep + register: result + cisco.nxos.nxos_vxlan_vtep: &id003 + interface: nve1 + description: default + host_reachability: false + source_interface_hold_down_time: default + source_interface: default + global_ingress_replication_bgp: false + multisite_border_gateway_interface: default + shutdown: true + + - ansible.builtin.assert: *id002 + + - name: Reset idempotence + register: result + cisco.nxos.nxos_vxlan_vtep: *id003 + + - ansible.builtin.assert: *id004 + + - name: Remove vxlan_vtep + register: result + cisco.nxos.nxos_vxlan_vtep: &id005 + interface: nve1 + description: default + host_reachability: true + source_interface: Loopback0 + source_interface_hold_down_time: 30 + shutdown: true + state: absent + + - ansible.builtin.assert: + that: + - result.changed == true + + - name: Remove idempotence + register: result + cisco.nxos.nxos_vxlan_vtep: *id005 + + - ansible.builtin.assert: + that: + - result.changed == false + + - name: Disable multisite border gateway - multisite + cisco.nxos.nxos_config: + lines: + - no evpn multisite border-gateway 10 + when: multiout is not search("Invalid command") + +- name: Disable NV overlay EVPN + when: platform is search('N9K') + ignore_errors: true + cisco.nxos.nxos_config: + commands: + - no nv overlay evpn + match: none + +- name: Disable 'feature nv overlay' + ignore_errors: true + cisco.nxos.nxos_feature: + feature: nve + state: disabled + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_vxlan_vtep sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep/tests/common/sanity.yaml new file mode 100644 index 00000000..11f53ed5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep/tests/common/sanity.yaml @@ -0,0 +1,219 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_vxlan_vtep sanity test + +- block: + - name: Set a fact for 'global_mcast_group_l2' + ansible.builtin.set_fact: + global_mcast_group_L2: 225.1.1.2 + + - name: Set a fact for 'def_global_mcast_group_l2' + ansible.builtin.set_fact: + def_global_mcast_group_L2: default + + - block: + - set_fact: global_mcast_group_L3="225.1.1.1" + + - set_fact: def_global_mcast_group_L3="default" + + - set_fact: global_ingress_replication_bgp="true" + + - set_fact: def_global_ingress_replication_bgp="false" + when: false + + - name: Tcam resource check for global_suppress_arp + connection: ansible.netcommon.network_cli + register: tcam_state + cisco.nxos.nxos_command: + commands: + - command: show hardware access-list tcam region | incl arp-ether | sed 's/.*size = *//' + output: text + + - block: + - set_fact: global_suppress_arp="true" + + - set_fact: def_global_suppress_arp="false" + when: tcam_state.stdout[0]|int > 0 + when: platform is search('N9K') and (major_version is version('9.2', 'ge')) + +- block: + - name: Apply N7K specific setup configuration + ansible.builtin.include_tasks: targets/nxos_vxlan_vtep/tasks/platform/n7k/setup.yaml + when: platform is match('N7K') + + - name: Enable 'feature nv overlay' + cisco.nxos.nxos_config: + commands: + - feature nv overlay + - nv overlay evpn + match: none + + - block: + - name: Enable feature ngmvpn + cisco.nxos.nxos_config: + commands: + - feature ngmvpn + match: none + when: global_mcast_group_L3 is defined + + - block: + - name: configure vxlan_vtep + register: result + cisco.nxos.nxos_vxlan_vtep: &id001 + interface: nve1 + description: abcd + host_reachability: true + source_interface: Loopback0 + source_interface_hold_down_time: 30 + global_ingress_replication_bgp: "{{ global_ingress_replication_bgp|default(omit) }}" + global_suppress_arp: "{{ global_suppress_arp|default(omit) }}" + global_mcast_group_L3: "{{ global_mcast_group_L3|default(omit) }}" + shutdown: false + + - assert: &id002 + that: + - result.changed == true + + - name: Conf Idempotence + register: result + cisco.nxos.nxos_vxlan_vtep: *id001 + + - assert: &id004 + that: + - result.changed == false + + - name: reset vxlan_vtep + register: result + cisco.nxos.nxos_vxlan_vtep: &id003 + interface: nve1 + description: default + host_reachability: false + source_interface_hold_down_time: default + source_interface: default + global_ingress_replication_bgp: "{{ def_global_ingress_replication_bgp|default(omit) }}" + global_suppress_arp: "{{ def_global_suppress_arp|default(omit) }}" + global_mcast_group_L3: "{{ def_global_mcast_group_L3|default(omit) }}" + shutdown: true + + - assert: *id002 + + - name: reset Idempotence + register: result + cisco.nxos.nxos_vxlan_vtep: *id003 + + - assert: *id004 + + - name: configure global mcast L2 + register: result + cisco.nxos.nxos_vxlan_vtep: &id005 + interface: nve1 + host_reachability: true + global_mcast_group_L2: "{{ global_mcast_group_L2|default(omit) }}" + + - assert: *id002 + + - name: Conf Idempotence + register: result + cisco.nxos.nxos_vxlan_vtep: *id005 + + - assert: *id004 + + - name: reset global mcast L2 + register: result + cisco.nxos.nxos_vxlan_vtep: &id006 + interface: nve1 + host_reachability: false + global_mcast_group_L2: "{{ def_global_mcast_group_L2|default(omit) }}" + + - assert: *id002 + + - name: reset Idempotence + register: result + cisco.nxos.nxos_vxlan_vtep: *id006 + + - assert: *id004 + when: (platform is search('N9K')) + + - block: + - name: configure vxlan_vtep + register: result + cisco.nxos.nxos_vxlan_vtep: &id007 + interface: nve1 + description: default + host_reachability: true + source_interface: Loopback0 + shutdown: false + + - assert: + that: + - result.changed == true + + - name: Conf Idempotence + register: result + cisco.nxos.nxos_vxlan_vtep: *id007 + + - assert: + that: + - result.changed == false + + - name: reset vxlan_vtep + register: result + cisco.nxos.nxos_vxlan_vtep: &id008 + interface: nve1 + description: default + host_reachability: false + source_interface: default + shutdown: true + + - assert: *id002 + + - name: reset Idempotence + register: result + cisco.nxos.nxos_vxlan_vtep: *id008 + + - assert: *id004 + when: (platform is search('N7K')) + + - name: Remove vxlan_vtep + register: result + cisco.nxos.nxos_vxlan_vtep: &id009 + interface: nve1 + description: default + host_reachability: true + source_interface: Loopback0 + source_interface_hold_down_time: 30 + shutdown: true + state: absent + + - ansible.builtin.assert: + that: + - result.changed == true + + - name: Remove idempotence + register: result + cisco.nxos.nxos_vxlan_vtep: *id009 + + - ansible.builtin.assert: + that: + - result.changed == false + when: (platform is search("N7K|N9K")) + always: + - name: Apply N7K specific cleanup configuration + ansible.builtin.include_tasks: targets/nxos_vxlan_vtep/tasks/platform/n7k/cleanup.yaml + when: platform is match('N7K') + + - name: Disable NV overlay EVPN + ignore_errors: true + cisco.nxos.nxos_config: + commands: + - no nv overlay evpn + match: none + + - name: Disable 'feature nv overlay' + ignore_errors: true + cisco.nxos.nxos_feature: + feature: nve + state: disabled + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_vxlan_vtep sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep_vni/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep_vni/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep_vni/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep_vni/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep_vni/meta/main.yml new file mode 100644 index 00000000..f504a6ab --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep_vni/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - prepare_nxos_tests diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep_vni/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep_vni/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep_vni/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep_vni/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep_vni/tasks/main.yaml new file mode 100644 index 00000000..c9e70304 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep_vni/tasks/main.yaml @@ -0,0 +1,12 @@ +--- +- name: Run the CLI and NX-API tests + block: + - name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + always: + - name: Include the NX-API tasks + ansible.builtin.include_tasks: nxapi.yaml + tags: + - nxapi diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep_vni/tasks/nxapi.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep_vni/tasks/nxapi.yaml new file mode 100644 index 00000000..b4ed5520 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep_vni/tasks/nxapi.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect NX-API test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + nxapi_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.httpapi) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.httpapi + connection: "{{ nxapi }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep_vni/tests/common/multisite.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep_vni/tests/common/multisite.yaml new file mode 100644 index 00000000..13ab21fd --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep_vni/tests/common/multisite.yaml @@ -0,0 +1,107 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_vxlan_vtep_vni multisite sanity test + +- name: Disable 'feature nv overlay' - multisite + ignore_errors: true + cisco.nxos.nxos_feature: + feature: nv overlay + state: disabled + +- name: Enable 'feature nv overlay' - multisite + ignore_errors: true + cisco.nxos.nxos_feature: + feature: nv overlay + state: enabled + +- name: Enable NV overlay EVPN - multisite + when: platform is search('N9K') + cisco.nxos.nxos_config: + lines: + - nv overlay evpn + +- name: Enable multisite border gateway - multisite + ignore_errors: true + register: multiout + cisco.nxos.nxos_config: + lines: + - evpn multisite border-gateway 10 + +- block: + - name: Configure vxlan_vtep - multisite + cisco.nxos.nxos_vxlan_vtep: + interface: nve1 + host_reachability: true + + - name: Configure multisite ingress replication - multisite + register: result + cisco.nxos.nxos_vxlan_vtep_vni: &id001 + interface: nve1 + vni: 8000 + multisite_ingress_replication: enable + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Idempotence check + register: result + cisco.nxos.nxos_vxlan_vtep_vni: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Remove multisite ingress replication - multisite + register: result + cisco.nxos.nxos_vxlan_vtep_vni: &id003 + interface: nve1 + vni: 8000 + multisite_ingress_replication: disable + + - ansible.builtin.assert: *id002 + + - name: Idempotence check + register: result + cisco.nxos.nxos_vxlan_vtep_vni: *id003 + + - ansible.builtin.assert: *id004 + + - name: Configure optimized multisite ingress replication - multisite + register: result + cisco.nxos.nxos_vxlan_vtep_vni: &id005 + interface: nve1 + vni: 8000 + multisite_ingress_replication: optimized + + - ansible.builtin.assert: *id002 + + - name: Idempotence check + register: result + cisco.nxos.nxos_vxlan_vtep_vni: *id005 + + - ansible.builtin.assert: *id004 + + - name: Disable multisite border gateway - multisite + cisco.nxos.nxos_config: + lines: + - no evpn multisite border-gateway 10 + when: multiout is not search("Invalid command") + +- name: Disable 'feature nv overlay' - multisite + ignore_errors: true + cisco.nxos.nxos_feature: + feature: nv overlay + state: disabled + +- ansible.builtin.pause: + seconds: 5 + +- name: Remove NV overlay EVPN - multisite + when: platform is search('N9K') + cisco.nxos.nxos_config: + lines: + - no nv overlay evpn + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_vxlan_vtep_vni multisite sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep_vni/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep_vni/tests/common/sanity.yaml new file mode 100644 index 00000000..ac478b9a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_vxlan_vtep_vni/tests/common/sanity.yaml @@ -0,0 +1,250 @@ +--- +- ansible.builtin.debug: + msg: START connection={{ ansible_connection }} nxos_vxlan_vtep_vni sanity test + +- block: + - name: Apply N7K specific setup configuration + ansible.builtin.include_tasks: targets/nxos_vxlan_vtep/tasks/platform/n7k/setup.yaml + when: platform is match('N7K') + + - name: Enable 'feature nv overlay' + cisco.nxos.nxos_config: + commands: + - feature nv overlay + match: none + + - name: Configure vxlan_vtep + cisco.nxos.nxos_vxlan_vtep: + interface: nve1 + host_reachability: true + + - name: Configure vxlan_vtep_vni assoc-vrf + register: result + cisco.nxos.nxos_vxlan_vtep_vni: &id001 + interface: nve1 + vni: 6000 + assoc_vrf: true + + - ansible.builtin.assert: &id002 + that: + - result.changed == true + + - name: Configure 1 idempotence + register: result + cisco.nxos.nxos_vxlan_vtep_vni: *id001 + + - ansible.builtin.assert: &id004 + that: + - result.changed == false + + - name: Remove vxlan_vtep_vni + cisco.nxos.nxos_vxlan_vtep_vni: + interface: nve1 + vni: 6000 + assoc_vrf: true + state: absent + + - name: Configure vxlan_vtep_vni + register: result + cisco.nxos.nxos_vxlan_vtep_vni: + interface: nve1 + vni: 8000 + + - ansible.builtin.assert: *id002 + + - name: Configure vxlan_vtep_vni mcast + register: result + cisco.nxos.nxos_vxlan_vtep_vni: &id003 + interface: nve1 + vni: 8000 + multicast_group: 224.1.1.1 + + - ansible.builtin.assert: *id002 + + - name: Configure 3 idempotence + register: result + cisco.nxos.nxos_vxlan_vtep_vni: *id003 + + - ansible.builtin.assert: *id004 + + - name: Configure vxlan_vtep_vni default mcast + register: result + cisco.nxos.nxos_vxlan_vtep_vni: &id005 + interface: nve1 + vni: 8000 + multicast_group: default + + - ansible.builtin.assert: *id002 + + - name: Configure 4 idempotence + register: result + cisco.nxos.nxos_vxlan_vtep_vni: *id005 + + - ansible.builtin.assert: *id004 + + - name: Remove configuration + cisco.nxos.nxos_vxlan_vtep_vni: &id013 + interface: nve1 + vni: 8000 + state: absent + + - name: Configure vxlan_vtep + cisco.nxos.nxos_vxlan_vtep: + interface: nve1 + host_reachability: false + + - block: + - name: configure vxlan_vtep_vni + register: result + cisco.nxos.nxos_vxlan_vtep_vni: + interface: nve1 + vni: 8000 + + - assert: *id002 + + - name: configure vxlan_vtep_vni ingress static + register: result + cisco.nxos.nxos_vxlan_vtep_vni: &id006 + interface: nve1 + vni: 8000 + ingress_replication: static + + - assert: *id002 + + - name: check configure vxlan_vtep_vni ingress static idempotence check + register: result + cisco.nxos.nxos_vxlan_vtep_vni: *id006 + + - assert: *id004 + + - name: Remove and reconfigure vxlan_vtep + cisco.nxos.nxos_vxlan_vtep: &id009 + interface: nve1 + state: absent + + - name: Configure vxlan_vtep with host reachability bgp + cisco.nxos.nxos_vxlan_vtep: + interface: nve1 + host_reachability: true + + - name: configure vxlan_vtep_vni + cisco.nxos.nxos_vxlan_vtep_vni: &id010 + interface: nve1 + vni: 8000 + + - name: configure vxlan_vtep_vni ingress bgp + register: result + cisco.nxos.nxos_vxlan_vtep_vni: &id007 + interface: nve1 + vni: 8000 + ingress_replication: bgp + + - assert: *id002 + + - name: Conf 7 Idempotence + register: result + cisco.nxos.nxos_vxlan_vtep_vni: *id007 + + - assert: *id004 + + - name: remove ingress_repl + register: result + cisco.nxos.nxos_vxlan_vtep_vni: &id008 + interface: nve1 + vni: 8000 + ingress_replication: default + + - assert: *id002 + + - name: Conf 8 Idempotence + register: result + cisco.nxos.nxos_vxlan_vtep_vni: *id008 + + - assert: *id004 + + - name: Remove and reconfigure vxlan_vtep + cisco.nxos.nxos_vxlan_vtep: *id009 + + - name: Configure vxlan_vtep with host reachability static + cisco.nxos.nxos_vxlan_vtep: + interface: nve1 + host_reachability: false + + - name: configure vxlan_vtep_vni + cisco.nxos.nxos_vxlan_vtep_vni: *id010 + + - name: configure vxlan_vtep_vni peer-list + register: result + cisco.nxos.nxos_vxlan_vtep_vni: &id011 + interface: nve1 + vni: 8000 + peer_list: + - 192.0.2.1 + - 192.0.2.2 + - 192.0.2.3 + - 192.0.2.4 + ingress_replication: static + + - assert: *id002 + + - name: Conf 9 Idempotence + register: result + cisco.nxos.nxos_vxlan_vtep_vni: *id011 + + - assert: *id004 + + - name: configure vxlan_vtep_vni default peer-list + register: result + cisco.nxos.nxos_vxlan_vtep_vni: &id012 + interface: nve1 + vni: 8000 + peer_list: default + ingress_replication: static + + - assert: *id002 + + - name: Conf 10 Idempotence + register: result + cisco.nxos.nxos_vxlan_vtep_vni: *id012 + + - assert: *id004 + + - name: Conf 9 again + register: result + cisco.nxos.nxos_vxlan_vtep_vni: *id011 + + - assert: *id002 + + - name: remove vxlan_vtep_vni + register: result + cisco.nxos.nxos_vxlan_vtep_vni: *id013 + + - assert: *id002 + + - name: remove Idempotence + register: result + cisco.nxos.nxos_vxlan_vtep_vni: *id013 + + - assert: *id004 + when: (platform is search('N9K')) + when: (platform is search("N7K|N9K")) + always: + - name: Apply N7K specific cleanup configuration + ansible.builtin.include_tasks: targets/nxos_vxlan_vtep/tasks/platform/n7k/cleanup.yaml + when: platform is match('N7K') + + - name: Remove vxlan_vtep + ignore_errors: true + cisco.nxos.nxos_vxlan_vtep: + interface: nve1 + shutdown: true + state: absent + + - name: Disable 'feature nv overlay' + ignore_errors: true + cisco.nxos.nxos_feature: + feature: nve + state: disabled + +- ansible.builtin.debug: + msg: END connection={{ ansible_connection }} nxos_vxlan_vtep_vni sanity test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_zone_zoneset/defaults/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_zone_zoneset/defaults/main.yaml new file mode 100644 index 00000000..5f709c5a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_zone_zoneset/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_zone_zoneset/meta/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_zone_zoneset/meta/main.yml new file mode 100644 index 00000000..ed97d539 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_zone_zoneset/meta/main.yml @@ -0,0 +1 @@ +--- diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_zone_zoneset/tasks/cli.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_zone_zoneset/tasks/cli.yaml new file mode 100644 index 00000000..f6096901 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_zone_zoneset/tasks/cli.yaml @@ -0,0 +1,32 @@ +--- +- name: Collect common test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: Collect CLI test cases + ansible.builtin.find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yaml" + connection: local + register: cli_cases + +- name: Set a fact for 'test_cases' + ansible.builtin.set_fact: + test_cases: + files: "{{ test_cases.files + cli_cases.files }}" + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + +- name: Run test cases (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: "{{ test_case_to_run }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + vars: + ansible_connection: ansible.netcommon.network_cli + connection: "{{ cli }}" diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_zone_zoneset/tasks/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_zone_zoneset/tasks/main.yaml new file mode 100644 index 00000000..477fbd41 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_zone_zoneset/tasks/main.yaml @@ -0,0 +1,19 @@ +--- +- name: Check platform type and skip if not MDS + register: result + cisco.nxos.nxos_command: + commands: show version | grep MDS + +- name: Set skip_test flag to false + ansible.builtin.set_fact: + skip_test: false + +- name: Set skip_test flag to true if not MDS + ansible.builtin.set_fact: + skip_test: true + when: result.stdout[0] is not search('MDS') + +- name: Include the CLI tasks + ansible.builtin.include_tasks: cli.yaml + tags: cli + when: not skip_test diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_zone_zoneset/tests/common/sanity.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_zone_zoneset/tests/common/sanity.yaml new file mode 100644 index 00000000..a0b5948c --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_zone_zoneset/tests/common/sanity.yaml @@ -0,0 +1,227 @@ +--- +- ansible.builtin.debug: + msg: "START nxos_zone_zoneset sanity test with connection={{ ansible_connection }} " + +- ansible.builtin.debug: + msg: >- + Using vsans {{ vsan1 }}, {{ vsan2 }} for running this sanity test, + please make sure these are not used in the setup, + these will be deleted after the tests + +- always: + - name: Remove VSAN configuration + cisco.nxos.nxos_vsan: + vsan: + - id: "{{ vsan1 | int }}" + remove: true + + - id: "{{ vsan2 | int }}" + remove: true + block: + - name: Setup - remove VSAN if configured + ignore_errors: true + cisco.nxos.nxos_vsan: + vsan: + - id: "{{ vsan1 | int }}" + remove: true + + - id: "{{ vsan2 | int }}" + remove: true + + - name: Configure VSAN + cisco.nxos.nxos_vsan: + vsan: + - id: "{{ vsan1 | int }}" + + - id: "{{ vsan2 | int }}" + + - name: Configure zone and zoneset + register: result + cisco.nxos.nxos_zone_zoneset: &id001 + zone_zoneset_details: + - mode: enhanced + vsan: "{{ vsan1 | int }}" + zone: + - members: + - pwwn: "11:11:11:11:11:11:11:11" + + - device_alias: test123 + + - pwwn: "61:61:62:62:12:12:12:12" + remove: true + name: zoneA + + - members: + - pwwn: "10:11:11:11:11:11:11:11" + + - pwwn: "62:62:62:62:21:21:21:21" + name: zoneB + + - name: zoneC + remove: true + zoneset: + - action: activate + members: + - name: zoneA + + - name: zoneB + + - name: zoneC + remove: true + name: zsetname1 + + - action: deactivate + name: zsetTestExtra + remove: true + + - mode: basic + smart_zoning: true + vsan: "{{ vsan2 | int }}" + zone: + - members: + - devtype: both + pwwn: "11:11:11:11:11:11:11:11" + + - pwwn: "62:62:62:62:12:12:12:12" + + - devtype: both + pwwn: "92:62:62:62:12:12:1a:1a" + remove: true + name: zone21A + + - members: + - pwwn: "10:11:11:11:11:11:11:11" + + - pwwn: "62:62:62:62:21:21:21:21" + + - device_alias: somedummyname + + - device_alias: anydummyname + remove: true + name: zone21B + zoneset: + - action: activate + members: + - name: zone21A + + - name: zone21B + name: zsetname21 + + - ansible.builtin.assert: + that: + - result.changed == true + + - ansible.builtin.assert: + that: + - result.commands == desired + vars: + desired: + - "terminal dont-ask" + - "zone mode enhanced vsan 922" + - "zone name zoneA vsan 922" + - "member pwwn 11:11:11:11:11:11:11:11" + - "member device-alias test123" + - "zone name zoneB vsan 922" + - "member pwwn 10:11:11:11:11:11:11:11" + - "member pwwn 62:62:62:62:21:21:21:21" + - "zoneset name zsetname1 vsan 922" + - "member zoneA" + - "member zoneB" + - "zoneset activate name zsetname1 vsan 922" + - "zone commit vsan 922" + - "zone smart-zoning enable vsan 923" + - "zone name zone21A vsan 923" + - "member pwwn 11:11:11:11:11:11:11:11 both" + - "member pwwn 62:62:62:62:12:12:12:12" + - "zone name zone21B vsan 923" + - "member pwwn 10:11:11:11:11:11:11:11" + - "member pwwn 62:62:62:62:21:21:21:21" + - "member device-alias somedummyname" + - "zoneset name zsetname21 vsan 923" + - "member zone21A" + - "member zone21B" + - "zoneset activate name zsetname21 vsan 923" + - "no terminal dont-ask" + + - name: Idempotence check + register: result + cisco.nxos.nxos_zone_zoneset: *id001 + + - name: Display idempotence check result + ansible.builtin.debug: + var: result + + - ansible.builtin.assert: + that: + - result.commands == [] + + - ansible.builtin.assert: + that: + - result.changed == false + + - name: Delete zone and zoneset that was configured + register: result + cisco.nxos.nxos_zone_zoneset: &id002 + zone_zoneset_details: + - mode: enhanced + vsan: "{{ vsan1 | int }}" + zone: + - name: zoneA + remove: true + + - name: zoneB + remove: true + + - name: zoneC + remove: true + zoneset: + - name: zsetname1 + remove: true + + - action: deactivate + name: zsetTestExtra + remove: true + + - mode: basic + smart_zoning: true + vsan: "{{ vsan2 | int }}" + zone: + - name: zone21A + remove: true + + - name: zone21B + remove: true + zoneset: + - name: zsetname21 + remove: true + + - ansible.builtin.assert: + that: + - result.changed == true + + - ansible.builtin.assert: + that: + - result.commands == desired + vars: + desired: + - "terminal dont-ask" + - "no zone name zoneA vsan 922" + - "no zone name zoneB vsan 922" + - "no zoneset name zsetname1 vsan 922" + - "zone commit vsan 922" + - "no zone name zone21A vsan 923" + - "no zone name zone21B vsan 923" + - "no zoneset name zsetname21 vsan 923" + - "no terminal dont-ask" + + - name: Idempotence check for zone/zoneset removal + register: result + cisco.nxos.nxos_zone_zoneset: *id002 + + - ansible.builtin.assert: + that: + - result.commands == [] + + - ansible.builtin.assert: + that: + - result.changed == false diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/nxos_zone_zoneset/vars/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_zone_zoneset/vars/main.yml new file mode 100644 index 00000000..41b2fdb0 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/nxos_zone_zoneset/vars/main.yml @@ -0,0 +1,5 @@ +--- +vsan1: 922 +vsan2: 923 +intA1: fc1/1 # noqa var-naming +intB1: fc1/2 # noqa var-naming diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/prepare_nxos_tests/meta/main.yaml b/ansible_collections/cisco/nxos/tests/integration/targets/prepare_nxos_tests/meta/main.yaml new file mode 100644 index 00000000..61d3ffe4 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/prepare_nxos_tests/meta/main.yaml @@ -0,0 +1,2 @@ +--- +allow_duplicates: true diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/prepare_nxos_tests/tasks/main.yml b/ansible_collections/cisco/nxos/tests/integration/targets/prepare_nxos_tests/tasks/main.yml new file mode 100644 index 00000000..78729cdd --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/prepare_nxos_tests/tasks/main.yml @@ -0,0 +1,27 @@ +--- +- name: Set inventory vars here temporarily + ansible.builtin.set_fact: + chassis_type: "C9300v" + cli: + transport: "cli" + authorize: true + fretta: "" + imagemr: "6" + imagetag: "9.3" + image_version: "9.3(6)" + ipv6_supported: true + major_version: "9.0" + nxapi: + port: "80" + transport: "nxapi" + use_ssl: false + nxos_int1: "Ethernet1/1" + nxos_int2: "Ethernet1/2" + nxos_int3: "Ethernet1/3" + platform: "N9K" + prepare_nxos_tests_task: false + titanium: false + +- name: Run the prepare steps if requested + ansible.builtin.include_tasks: prepare.yml + when: prepare_nxos_tests_task | default(False) | bool diff --git a/ansible_collections/cisco/nxos/tests/integration/targets/prepare_nxos_tests/tasks/prepare.yml b/ansible_collections/cisco/nxos/tests/integration/targets/prepare_nxos_tests/tasks/prepare.yml new file mode 100644 index 00000000..52d38597 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/integration/targets/prepare_nxos_tests/tasks/prepare.yml @@ -0,0 +1,170 @@ +--- +- name: Enable feature privilege + connection: ansible.netcommon.network_cli + ignore_errors: true # noqa ignore-errors + cisco.nxos.nxos_config: + lines: + - feature privilege + +- name: Enable feature NX-API + connection: ansible.netcommon.network_cli + cisco.nxos.nxos_nxapi: + state: present + +- name: Enable lldp + connection: ansible.netcommon.network_cli + ignore_errors: true # noqa ignore-errors + cisco.nxos.nxos_config: + lines: + - feature lldp + +- name: Collect interface list + connection: ansible.netcommon.network_cli + register: intout + cisco.nxos.nxos_command: + commands: + - show interface brief | json + +- name: Set a fact for 'intdataraw' + ansible.builtin.set_fact: + intdataraw: "{{ intout.stdout_lines[0]['TABLE_interface']['ROW_interface'] }}" + +- name: Set a fact for 'nxos_int1' + ansible.builtin.set_fact: + nxos_int1: "{{ intdataraw[1].interface }}" + +- name: Set a fact for 'nxos_int2' + ansible.builtin.set_fact: + nxos_int2: "{{ intdataraw[2].interface }}" + +- name: Set a fact for 'nxos_int3' + ansible.builtin.set_fact: + nxos_int3: "{{ intdataraw[3].interface }}" + +- name: Gather image version info + connection: ansible.netcommon.network_cli + register: nxos_version_output + cisco.nxos.nxos_command: + commands: + - show version | json + +- name: Set a fact for 'image_version' + ansible.builtin.set_fact: + image_version: "{{ nxos_version_output.stdout[0]['kickstart_ver_str'] }}" + +- name: Gather platform info + connection: ansible.netcommon.network_cli + register: nxos_inventory_output + cisco.nxos.nxos_command: + commands: + - show inventory | json + +- name: Set a fact for 'platform' + ansible.builtin.set_fact: + platform: "{{ nxos_inventory_output.stdout_lines[0]['TABLE_inv']['ROW_inv'][0]['productid'].split('-')[0] }}" + +- name: Set a fact for 'chassis_type' + ansible.builtin.set_fact: + chassis_type: "{{ nxos_inventory_output.stdout_lines[0]['TABLE_inv']['ROW_inv'][0]['productid'].split('-')[1] }}" + +- name: Set a fact for 'fretta' + ansible.builtin.set_fact: + fretta: "{% for row in nxos_inventory_output.stdout_lines[0]['TABLE_inv']['ROW_inv'] if '-R' in row['productid'] %}true{% endfor %}" + when: platform is match("N9K|N3K") + +- name: Set a fact for 'platform' + ansible.builtin.set_fact: + platform: N3K-F + when: (platform is match("N3K")) and (fretta is search("true")) + +- name: Set a fact for 'platform' + ansible.builtin.set_fact: + platform: N9K-F + when: (platform is match("N9K")) and (fretta is search("true")) + +- name: Set a fact for 'titanium' + ansible.builtin.set_fact: + titanium: "false" + +- name: Set a fact for 'titanium' + ansible.builtin.set_fact: + titanium: "{% for row in nxos_inventory_output.stdout_lines[0]['TABLE_inv']['ROW_inv'] if 'NX-OSv' in row['desc']%}true{% endfor %}" + when: platform is match("N7K") + +- name: Set a fact for 'platform' + ansible.builtin.set_fact: + platform: N35 + when: (chassis_type is search("C35")) + +- name: Set a fact for 'platform' + ansible.builtin.set_fact: + platform: N35NG + when: (chassis_type is search("C35")) and image_version is search("7.0\(3\)I7") + +- name: Set a fact for 'platform' + ansible.builtin.set_fact: + platform: N3L + when: (chassis_type is search("C3048")) + +- name: Set a fact for 'imagetag' + ansible.builtin.set_fact: + imagetag: "" + +- name: Set a fact for 'imagemr' + ansible.builtin.set_fact: + imagemr: "" + +- name: Set a fact for 'major_version' + ansible.builtin.set_fact: + major_version: "{{ image_version[0:3] }}" + +- name: Set a fact for 'imagetag' + ansible.builtin.set_fact: + imagetag: "{{ image_version[0:3] }}" + when: image_version is search("\d\.\d\(\d\)") + +- name: Set a fact for 'imagetag' + ansible.builtin.set_fact: + imagetag: "{{ image_version[6:8] }}" + when: image_version is search("\d\.\d\(\d\)\S\S\(\d\)") + +- name: Set a fact for 'imagetag' + ansible.builtin.set_fact: + imagetag: "{{ image_version[6:10] }}" + when: image_version is search("\d\.\d\(\d\)\S\S\S\S\(\d\)") + +- name: Set a fact for 'imagemr' + ansible.builtin.set_fact: + imagemr: "{{ image_version[4:5] }}" + when: image_version is search("\d\.\d\(\d\)") + +- name: Set a fact for 'imagemr' + ansible.builtin.set_fact: + imagemr: "{{ image_version[9:10] }}" + when: image_version is search("\d\.\d\(\d\)\S\S\(\d\)") + +- name: Set a fact for 'imagemr' + ansible.builtin.set_fact: + imagemr: "{{ image_version[11:12] }}" + when: image_version is search("\d\.\d\(\d\)\S\S\S\S\(\d\)") + +- name: Debug output the image version + ansible.builtin.debug: + msg: IMAGE VERSION {{ image_version }} + +- name: Debug output the image tag + ansible.builtin.debug: + msg: IMAGE TAG {{ imagetag }} + +- name: Debug output the image maintenance release + ansible.builtin.debug: + msg: IMAGE MR {{ imagemr }} + +- name: Set a fact for 'ipv6_supported' + ansible.builtin.set_fact: + ipv6_supported: "true" + +- name: Set a fact for 'ipv6_supported' + ansible.builtin.set_fact: + ipv6_supported: "false" + when: platform is match("N35") diff --git a/ansible_collections/cisco/nxos/tests/sanity/ignore-2.10.txt b/ansible_collections/cisco/nxos/tests/sanity/ignore-2.10.txt new file mode 100644 index 00000000..4f8c291e --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/sanity/ignore-2.10.txt @@ -0,0 +1,34 @@ +plugins/action/nxos.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` +plugins/module_utils/network/nxos/config/bgp_global/bgp_global.py compile-2.6!skip +plugins/module_utils/network/nxos/config/ospf_interfaces/ospf_interfaces.py compile-2.6!skip +plugins/module_utils/network/nxos/config/ospfv2/ospfv2.py compile-2.6!skip +plugins/module_utils/network/nxos/config/ospfv3/ospfv3.py compile-2.6!skip +plugins/module_utils/network/nxos/config/bgp_address_family/bgp_address_family.py compile-2.6!skip +plugins/modules/nxos_bgp_address_family.py compile-2.6!skip +plugins/module_utils/network/nxos/config/bgp_neighbor_address_family/bgp_neighbor_address_family.py compile-2.6!skip +plugins/modules/nxos_bgp_neighbor_address_family.py compile-2.6!skip +plugins/module_utils/network/nxos/config/bgp_global/bgp_global.py import-2.6!skip +plugins/module_utils/network/nxos/config/ospf_interfaces/ospf_interfaces.py import-2.6!skip +plugins/module_utils/network/nxos/config/ospfv2/ospfv2.py import-2.6!skip +plugins/module_utils/network/nxos/config/ospfv3/ospfv3.py import-2.6!skip +plugins/modules/nxos_bgp_global.py import-2.6!skip +plugins/modules/nxos_ospf_interfaces.py import-2.6!skip +plugins/modules/nxos_ospfv2.py import-2.6!skip +plugins/modules/nxos_ospfv3.py import-2.6!skip +plugins/modules/nxos_route_maps.py import-2.6!skip +plugins/module_utils/network/nxos/config/route_maps/route_maps.py import-2.6!skip +plugins/module_utils/network/nxos/config/route_maps/route_maps.py compile-2.6!skip +plugins/module_utils/network/nxos/config/snmp_server/snmp_server.py import-2.6!skip +plugins/module_utils/network/nxos/config/snmp_server/snmp_server.py compile-2.6!skip +plugins/module_utils/network/nxos/config/bgp_address_family/bgp_address_family.py import-2.6!skip +plugins/modules/nxos_bgp_address_family.py import-2.6!skip +plugins/module_utils/network/nxos/config/bgp_neighbor_address_family/bgp_neighbor_address_family.py import-2.6!skip +plugins/modules/nxos_bgp_neighbor_address_family.py import-2.6!skip +plugins/modules/nxos_prefix_lists.py import-2.6!skip +plugins/module_utils/network/nxos/config/prefix_lists/prefix_lists.py import-2.6!skip +plugins/module_utils/network/nxos/config/prefix_lists/prefix_lists.py compile-2.6!skip +plugins/modules/nxos_logging_global.py import-2.6!skip +plugins/module_utils/network/nxos/config/logging_global/logging_global.py import-2.6!skip +plugins/module_utils/network/nxos/config/logging_global/logging_global.py compile-2.6!skip +plugins/module_utils/network/nxos/utils/utils.py import-2.6!skip +plugins/module_utils/network/nxos/utils/utils.py compile-2.6!skip diff --git a/ansible_collections/cisco/nxos/tests/sanity/ignore-2.11.txt b/ansible_collections/cisco/nxos/tests/sanity/ignore-2.11.txt new file mode 100644 index 00000000..4f8c291e --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/sanity/ignore-2.11.txt @@ -0,0 +1,34 @@ +plugins/action/nxos.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` +plugins/module_utils/network/nxos/config/bgp_global/bgp_global.py compile-2.6!skip +plugins/module_utils/network/nxos/config/ospf_interfaces/ospf_interfaces.py compile-2.6!skip +plugins/module_utils/network/nxos/config/ospfv2/ospfv2.py compile-2.6!skip +plugins/module_utils/network/nxos/config/ospfv3/ospfv3.py compile-2.6!skip +plugins/module_utils/network/nxos/config/bgp_address_family/bgp_address_family.py compile-2.6!skip +plugins/modules/nxos_bgp_address_family.py compile-2.6!skip +plugins/module_utils/network/nxos/config/bgp_neighbor_address_family/bgp_neighbor_address_family.py compile-2.6!skip +plugins/modules/nxos_bgp_neighbor_address_family.py compile-2.6!skip +plugins/module_utils/network/nxos/config/bgp_global/bgp_global.py import-2.6!skip +plugins/module_utils/network/nxos/config/ospf_interfaces/ospf_interfaces.py import-2.6!skip +plugins/module_utils/network/nxos/config/ospfv2/ospfv2.py import-2.6!skip +plugins/module_utils/network/nxos/config/ospfv3/ospfv3.py import-2.6!skip +plugins/modules/nxos_bgp_global.py import-2.6!skip +plugins/modules/nxos_ospf_interfaces.py import-2.6!skip +plugins/modules/nxos_ospfv2.py import-2.6!skip +plugins/modules/nxos_ospfv3.py import-2.6!skip +plugins/modules/nxos_route_maps.py import-2.6!skip +plugins/module_utils/network/nxos/config/route_maps/route_maps.py import-2.6!skip +plugins/module_utils/network/nxos/config/route_maps/route_maps.py compile-2.6!skip +plugins/module_utils/network/nxos/config/snmp_server/snmp_server.py import-2.6!skip +plugins/module_utils/network/nxos/config/snmp_server/snmp_server.py compile-2.6!skip +plugins/module_utils/network/nxos/config/bgp_address_family/bgp_address_family.py import-2.6!skip +plugins/modules/nxos_bgp_address_family.py import-2.6!skip +plugins/module_utils/network/nxos/config/bgp_neighbor_address_family/bgp_neighbor_address_family.py import-2.6!skip +plugins/modules/nxos_bgp_neighbor_address_family.py import-2.6!skip +plugins/modules/nxos_prefix_lists.py import-2.6!skip +plugins/module_utils/network/nxos/config/prefix_lists/prefix_lists.py import-2.6!skip +plugins/module_utils/network/nxos/config/prefix_lists/prefix_lists.py compile-2.6!skip +plugins/modules/nxos_logging_global.py import-2.6!skip +plugins/module_utils/network/nxos/config/logging_global/logging_global.py import-2.6!skip +plugins/module_utils/network/nxos/config/logging_global/logging_global.py compile-2.6!skip +plugins/module_utils/network/nxos/utils/utils.py import-2.6!skip +plugins/module_utils/network/nxos/utils/utils.py compile-2.6!skip diff --git a/ansible_collections/cisco/nxos/tests/sanity/ignore-2.12.txt b/ansible_collections/cisco/nxos/tests/sanity/ignore-2.12.txt new file mode 100644 index 00000000..33c91076 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/sanity/ignore-2.12.txt @@ -0,0 +1,38 @@ +plugins/action/nxos.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` +plugins/module_utils/network/nxos/config/bgp_global/bgp_global.py compile-2.6!skip +plugins/module_utils/network/nxos/config/ospf_interfaces/ospf_interfaces.py compile-2.6!skip +plugins/module_utils/network/nxos/config/ospfv2/ospfv2.py compile-2.6!skip +plugins/module_utils/network/nxos/config/ospfv3/ospfv3.py compile-2.6!skip +plugins/module_utils/network/nxos/config/bgp_address_family/bgp_address_family.py compile-2.6!skip +plugins/modules/nxos_bgp_address_family.py compile-2.6!skip +plugins/module_utils/network/nxos/config/bgp_neighbor_address_family/bgp_neighbor_address_family.py compile-2.6!skip +plugins/modules/nxos_bgp_neighbor_address_family.py compile-2.6!skip +plugins/module_utils/network/nxos/config/bgp_global/bgp_global.py import-2.6!skip +plugins/module_utils/network/nxos/config/ospf_interfaces/ospf_interfaces.py import-2.6!skip +plugins/module_utils/network/nxos/config/ospfv2/ospfv2.py import-2.6!skip +plugins/module_utils/network/nxos/config/ospfv3/ospfv3.py import-2.6!skip +plugins/modules/nxos_bgp_global.py import-2.6!skip +plugins/modules/nxos_ospf_interfaces.py import-2.6!skip +plugins/modules/nxos_ospfv2.py import-2.6!skip +plugins/modules/nxos_ospfv3.py import-2.6!skip +plugins/modules/nxos_route_maps.py import-2.6!skip +plugins/module_utils/network/nxos/config/route_maps/route_maps.py import-2.6!skip +plugins/module_utils/network/nxos/config/route_maps/route_maps.py compile-2.6!skip +plugins/module_utils/network/nxos/config/snmp_server/snmp_server.py import-2.6!skip +plugins/module_utils/network/nxos/config/snmp_server/snmp_server.py compile-2.6!skip +plugins/module_utils/network/nxos/config/bgp_address_family/bgp_address_family.py import-2.6!skip +plugins/modules/nxos_bgp_address_family.py import-2.6!skip +plugins/module_utils/network/nxos/config/bgp_neighbor_address_family/bgp_neighbor_address_family.py import-2.6!skip +plugins/modules/nxos_bgp_neighbor_address_family.py import-2.6!skip +plugins/modules/nxos_prefix_lists.py import-2.6!skip +plugins/module_utils/network/nxos/config/prefix_lists/prefix_lists.py import-2.6!skip +plugins/module_utils/network/nxos/config/prefix_lists/prefix_lists.py compile-2.6!skip +plugins/modules/nxos_logging_global.py import-2.6!skip +plugins/module_utils/network/nxos/config/logging_global/logging_global.py import-2.6!skip +plugins/module_utils/network/nxos/config/logging_global/logging_global.py compile-2.6!skip +plugins/module_utils/network/nxos/config/ntp_global/ntp_global.py import-2.6!skip +plugins/module_utils/network/nxos/config/ntp_global/ntp_global.py compile-2.6!skip +plugins/module_utils/network/nxos/utils/utils.py import-2.6!skip +plugins/module_utils/network/nxos/utils/utils.py compile-2.6!skip +plugins/cliconf/nxos.py pylint:arguments-renamed +tests/unit/mock/loader.py pylint:arguments-renamed diff --git a/ansible_collections/cisco/nxos/tests/sanity/ignore-2.13.txt b/ansible_collections/cisco/nxos/tests/sanity/ignore-2.13.txt new file mode 100644 index 00000000..c2ac0a10 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/sanity/ignore-2.13.txt @@ -0,0 +1,3 @@ +plugins/action/nxos.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` +plugins/cliconf/nxos.py pylint:arguments-renamed +tests/unit/mock/loader.py pylint:arguments-renamed diff --git a/ansible_collections/cisco/nxos/tests/sanity/ignore-2.14.txt b/ansible_collections/cisco/nxos/tests/sanity/ignore-2.14.txt new file mode 100644 index 00000000..c2ac0a10 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/sanity/ignore-2.14.txt @@ -0,0 +1,3 @@ +plugins/action/nxos.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` +plugins/cliconf/nxos.py pylint:arguments-renamed +tests/unit/mock/loader.py pylint:arguments-renamed diff --git a/ansible_collections/cisco/nxos/tests/sanity/ignore-2.15.txt b/ansible_collections/cisco/nxos/tests/sanity/ignore-2.15.txt new file mode 100644 index 00000000..c2ac0a10 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/sanity/ignore-2.15.txt @@ -0,0 +1,3 @@ +plugins/action/nxos.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` +plugins/cliconf/nxos.py pylint:arguments-renamed +tests/unit/mock/loader.py pylint:arguments-renamed diff --git a/ansible_collections/cisco/nxos/tests/sanity/ignore-2.9.txt b/ansible_collections/cisco/nxos/tests/sanity/ignore-2.9.txt new file mode 100644 index 00000000..245bf89f --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/sanity/ignore-2.9.txt @@ -0,0 +1,63 @@ +plugins/modules/nxos_logging.py validate-modules:deprecation-mismatch # 2.9 expects METADATA +plugins/modules/nxos_logging.py validate-modules:invalid-documentation # removed_at_date not +plugins/action/nxos.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` +plugins/modules/nxos_bgp.py validate-modules:deprecation-mismatch # 2.9 expects METADATA +plugins/modules/nxos_bgp.py validate-modules:invalid-documentation # removed_at_date not supported in `deprecated` dict +plugins/modules/nxos_bgp_neighbor.py validate-modules:deprecation-mismatch # 2.9 expects METADATA +plugins/modules/nxos_bgp_neighbor.py validate-modules:invalid-documentation # removed_at_date not supported in `deprecated` dict +plugins/modules/nxos_bgp_af.py validate-modules:deprecation-mismatch # 2.9 expects METADATA +plugins/modules/nxos_bgp_af.py validate-modules:invalid-documentation # removed_at_date not supported in `deprecated` dict +plugins/modules/nxos_bgp_neighbor_af.py validate-modules:deprecation-mismatch # 2.9 expects METADATA +plugins/modules/nxos_bgp_neighbor_af.py validate-modules:invalid-documentation # removed_at_date not supported in `deprecated` dict +plugins/modules/nxos_ntp.py validate-modules:deprecation-mismatch # 2.9 expects METADATA +plugins/modules/nxos_ntp.py validate-modules:invalid-documentation # removed_at_date not supported in `deprecated` dict +plugins/modules/nxos_ntp_auth.py validate-modules:deprecation-mismatch # 2.9 expects METADATA +plugins/modules/nxos_ntp_auth.py validate-modules:invalid-documentation # removed_at_date not supported in `deprecated` dict +plugins/modules/nxos_ntp_options.py validate-modules:deprecation-mismatch # 2.9 expects METADATA +plugins/modules/nxos_ntp_options.py validate-modules:invalid-documentation # removed_at_date not supported in `deprecated` dict +plugins/modules/nxos_snmp_community.py validate-modules:deprecation-mismatch # 2.9 expects METADATA +plugins/modules/nxos_snmp_community.py validate-modules:invalid-documentation # removed_at_date not supported in `deprecated` dict +plugins/modules/nxos_snmp_contact.py validate-modules:deprecation-mismatch # 2.9 expects METADATA +plugins/modules/nxos_snmp_contact.py validate-modules:invalid-documentation # removed_at_date not supported in `deprecated` dict +plugins/modules/nxos_snmp_host.py validate-modules:deprecation-mismatch # 2.9 expects METADATA +plugins/modules/nxos_snmp_host.py validate-modules:invalid-documentation # removed_at_date not supported in `deprecated` dict +plugins/modules/nxos_snmp_location.py validate-modules:deprecation-mismatch # 2.9 expects METADATA +plugins/modules/nxos_snmp_location.py validate-modules:invalid-documentation # removed_at_date not supported in `deprecated` dict +plugins/modules/nxos_snmp_traps.py validate-modules:deprecation-mismatch # 2.9 expects METADATA +plugins/modules/nxos_snmp_traps.py validate-modules:invalid-documentation # removed_at_date not supported in `deprecated` dict +plugins/modules/nxos_snmp_user.py validate-modules:deprecation-mismatch # 2.9 expects METADATA +plugins/modules/nxos_snmp_user.py validate-modules:invalid-documentation # removed_at_date not supported in `deprecated` dict +plugins/module_utils/network/nxos/config/bgp_global/bgp_global.py compile-2.6!skip +plugins/module_utils/network/nxos/config/ospf_interfaces/ospf_interfaces.py compile-2.6!skip +plugins/module_utils/network/nxos/config/ospfv2/ospfv2.py compile-2.6!skip +plugins/module_utils/network/nxos/config/ospfv3/ospfv3.py compile-2.6!skip +plugins/module_utils/network/nxos/config/bgp_address_family/bgp_address_family.py compile-2.6!skip +plugins/modules/nxos_bgp_address_family.py compile-2.6!skip +plugins/module_utils/network/nxos/config/bgp_neighbor_address_family/bgp_neighbor_address_family.py compile-2.6!skip +plugins/modules/nxos_bgp_neighbor_address_family.py compile-2.6!skip +plugins/module_utils/network/nxos/config/bgp_global/bgp_global.py import-2.6!skip +plugins/module_utils/network/nxos/config/ospf_interfaces/ospf_interfaces.py import-2.6!skip +plugins/module_utils/network/nxos/config/ospfv2/ospfv2.py import-2.6!skip +plugins/module_utils/network/nxos/config/ospfv3/ospfv3.py import-2.6!skip +plugins/modules/nxos_bgp_global.py import-2.6!skip +plugins/modules/nxos_ospf_interfaces.py import-2.6!skip +plugins/modules/nxos_ospfv2.py import-2.6!skip +plugins/modules/nxos_ospfv3.py import-2.6!skip +plugins/modules/nxos_route_maps.py import-2.6!skip +plugins/module_utils/network/nxos/config/route_maps/route_maps.py import-2.6!skip +plugins/module_utils/network/nxos/config/route_maps/route_maps.py compile-2.6!skip +plugins/module_utils/network/nxos/config/bgp_address_family/bgp_address_family.py import-2.6!skip +plugins/modules/nxos_bgp_address_family.py import-2.6!skip +plugins/module_utils/network/nxos/config/bgp_neighbor_address_family/bgp_neighbor_address_family.py import-2.6!skip +plugins/modules/nxos_bgp_neighbor_address_family.py import-2.6!skip +plugins/modules/nxos_prefix_lists.py import-2.6!skip +plugins/module_utils/network/nxos/config/prefix_lists/prefix_lists.py import-2.6!skip +plugins/module_utils/network/nxos/config/prefix_lists/prefix_lists.py compile-2.6!skip +plugins/modules/nxos_logging_global.py import-2.6!skip +plugins/module_utils/network/nxos/config/logging_global/logging_global.py import-2.6!skip +plugins/module_utils/network/nxos/config/logging_global/logging_global.py compile-2.6!skip +plugins/modules/nxos_snmp_server.py import-2.6!skip +plugins/module_utils/network/nxos/config/snmp_server/snmp_server.py import-2.6!skip +plugins/module_utils/network/nxos/config/snmp_server/snmp_server.py compile-2.6!skip +plugins/module_utils/network/nxos/utils/utils.py import-2.6!skip +plugins/module_utils/network/nxos/utils/utils.py compile-2.6!skip diff --git a/ansible_collections/cisco/nxos/tests/unit/__init__.py b/ansible_collections/cisco/nxos/tests/unit/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/compat/__init__.py b/ansible_collections/cisco/nxos/tests/unit/compat/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/compat/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/compat/mock.py b/ansible_collections/cisco/nxos/tests/unit/compat/mock.py new file mode 100644 index 00000000..50583cd6 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/compat/mock.py @@ -0,0 +1,127 @@ +# (c) 2014, Toshio Kuratomi <tkuratomi@ansible.com> +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +""" +Compat module for Python3.x's unittest.mock module +""" +import sys + + +# Python 2.7 + +# Note: Could use the pypi mock library on python3.x as well as python2.x. It +# is the same as the python3 stdlib mock library + +try: + # Allow wildcard import because we really do want to import all of mock's + # symbols into this compat shim + # pylint: disable=wildcard-import,unused-wildcard-import + from unittest.mock import * +except ImportError: + # Python 2 + # pylint: disable=wildcard-import,unused-wildcard-import + try: + from mock import * + except ImportError: + print("You need the mock library installed on python2.x to run tests") + + +# Prior to 3.4.4, mock_open cannot handle binary read_data +if sys.version_info >= (3,) and sys.version_info < (3, 4, 4): + file_spec = None + + def _iterate_read_data(read_data): + # Helper for mock_open: + # Retrieve lines from read_data via a generator so that separate calls to + # readline, read, and readlines are properly interleaved + sep = b"\n" if isinstance(read_data, bytes) else "\n" + data_as_list = [l + sep for l in read_data.split(sep)] + + if data_as_list[-1] == sep: + # If the last line ended in a newline, the list comprehension will have an + # extra entry that's just a newline. Remove this. + data_as_list = data_as_list[:-1] + else: + # If there wasn't an extra newline by itself, then the file being + # emulated doesn't have a newline to end the last line remove the + # newline that our naive format() added + data_as_list[-1] = data_as_list[-1][:-1] + + for line in data_as_list: + yield line + + def mock_open(mock=None, read_data=""): + """ + A helper function to create a mock to replace the use of `open`. It works + for `open` called directly or used as a context manager. + + The `mock` argument is the mock object to configure. If `None` (the + default) then a `MagicMock` will be created for you, with the API limited + to methods or attributes available on standard file handles. + + `read_data` is a string for the `read` methoddline`, and `readlines` of the + file handle to return. This is an empty string by default. + """ + + def _readlines_side_effect(*args, **kwargs): + if handle.readlines.return_value is not None: + return handle.readlines.return_value + return list(_data) + + def _read_side_effect(*args, **kwargs): + if handle.read.return_value is not None: + return handle.read.return_value + return type(read_data)().join(_data) + + def _readline_side_effect(): + if handle.readline.return_value is not None: + while True: + yield handle.readline.return_value + for line in _data: + yield line + + global file_spec + if file_spec is None: + import _io + + file_spec = list(set(dir(_io.TextIOWrapper)).union(set(dir(_io.BytesIO)))) + + if mock is None: + mock = MagicMock(name="open", spec=open) + + handle = MagicMock(spec=file_spec) + handle.__enter__.return_value = handle + + _data = _iterate_read_data(read_data) + + handle.write.return_value = None + handle.read.return_value = None + handle.readline.return_value = None + handle.readlines.return_value = None + + handle.read.side_effect = _read_side_effect + handle.readline.side_effect = _readline_side_effect() + handle.readlines.side_effect = _readlines_side_effect + + mock.return_value = handle + return mock diff --git a/ansible_collections/cisco/nxos/tests/unit/compat/unittest.py b/ansible_collections/cisco/nxos/tests/unit/compat/unittest.py new file mode 100644 index 00000000..df4266ec --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/compat/unittest.py @@ -0,0 +1,41 @@ +# (c) 2014, Toshio Kuratomi <tkuratomi@ansible.com> +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +""" +Compat module for Python2.7's unittest module +""" + +import sys + + +# Allow wildcard import because we really do want to import all of +# unittests's symbols into this compat shim +# pylint: disable=wildcard-import,unused-wildcard-import +if sys.version_info < (2, 7): + try: + # Need unittest2 on python2.6 + from unittest2 import * + except ImportError: + print("You need unittest2 installed on python2.6.x to run tests") +else: + from unittest import * diff --git a/ansible_collections/cisco/nxos/tests/unit/mock/__init__.py b/ansible_collections/cisco/nxos/tests/unit/mock/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/mock/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/mock/loader.py b/ansible_collections/cisco/nxos/tests/unit/mock/loader.py new file mode 100644 index 00000000..2b5eb36a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/mock/loader.py @@ -0,0 +1,117 @@ +# (c) 2012-2014, Michael DeHaan <michael.dehaan@gmail.com> +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +import os + +from ansible.errors import AnsibleParserError +from ansible.module_utils._text import to_bytes, to_text +from ansible.parsing.dataloader import DataLoader + + +class DictDataLoader(DataLoader): + def __init__(self, file_mapping=None): + file_mapping = {} if file_mapping is None else file_mapping + assert type(file_mapping) == dict + + super(DictDataLoader, self).__init__() + + self._file_mapping = file_mapping + self._build_known_directories() + self._vault_secrets = None + + def load_from_file(self, path, cache=True, unsafe=False): + path = to_text(path) + if path in self._file_mapping: + return self.load(self._file_mapping[path], path) + return None + + # TODO: the real _get_file_contents returns a bytestring, so we actually convert the + # unicode/text it's created with to utf-8 + def _get_file_contents(self, path): + path = to_text(path) + if path in self._file_mapping: + return (to_bytes(self._file_mapping[path]), False) + else: + raise AnsibleParserError("file not found: %s" % path) + + def path_exists(self, path): + path = to_text(path) + return path in self._file_mapping or path in self._known_directories + + def is_file(self, path): + path = to_text(path) + return path in self._file_mapping + + def is_directory(self, path): + path = to_text(path) + return path in self._known_directories + + def list_directory(self, path): + ret = [] + path = to_text(path) + for x in list(self._file_mapping.keys()) + self._known_directories: + if x.startswith(path): + if os.path.dirname(x) == path: + ret.append(os.path.basename(x)) + return ret + + def is_executable(self, path): + # FIXME: figure out a way to make paths return true for this + return False + + def _add_known_directory(self, directory): + if directory not in self._known_directories: + self._known_directories.append(directory) + + def _build_known_directories(self): + self._known_directories = [] + for path in self._file_mapping: + dirname = os.path.dirname(path) + while dirname not in ("/", ""): + self._add_known_directory(dirname) + dirname = os.path.dirname(dirname) + + def push(self, path, content): + rebuild_dirs = False + if path not in self._file_mapping: + rebuild_dirs = True + + self._file_mapping[path] = content + + if rebuild_dirs: + self._build_known_directories() + + def pop(self, path): + if path in self._file_mapping: + del self._file_mapping[path] + self._build_known_directories() + + def clear(self): + self._file_mapping = dict() + self._known_directories = [] + + def get_basedir(self): + return os.getcwd() + + def set_vault_secrets(self, vault_secrets): + self._vault_secrets = vault_secrets diff --git a/ansible_collections/cisco/nxos/tests/unit/mock/path.py b/ansible_collections/cisco/nxos/tests/unit/mock/path.py new file mode 100644 index 00000000..d15430fd --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/mock/path.py @@ -0,0 +1,10 @@ +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type +from ansible.utils.path import unfrackpath + +from ansible_collections.cisco.nxos.tests.unit.compat.mock import MagicMock + + +mock_unfrackpath_noop = MagicMock(spec_set=unfrackpath, side_effect=lambda x, *args, **kwargs: x) diff --git a/ansible_collections/cisco/nxos/tests/unit/mock/procenv.py b/ansible_collections/cisco/nxos/tests/unit/mock/procenv.py new file mode 100644 index 00000000..e14ad0ec --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/mock/procenv.py @@ -0,0 +1,97 @@ +# (c) 2016, Matt Davis <mdavis@ansible.com> +# (c) 2016, Toshio Kuratomi <tkuratomi@ansible.com> +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +import json +import sys + +from contextlib import contextmanager +from io import BytesIO, StringIO + +from ansible.module_utils._text import to_bytes +from ansible.module_utils.six import PY3 + +from ansible_collections.cisco.nxos.tests.unit.compat import unittest + + +@contextmanager +def swap_stdin_and_argv(stdin_data="", argv_data=tuple()): + """ + context manager that temporarily masks the test runner's values for stdin and argv + """ + real_stdin = sys.stdin + real_argv = sys.argv + + if PY3: + fake_stream = StringIO(stdin_data) + fake_stream.buffer = BytesIO(to_bytes(stdin_data)) + else: + fake_stream = BytesIO(to_bytes(stdin_data)) + + try: + sys.stdin = fake_stream + sys.argv = argv_data + + yield + finally: + sys.stdin = real_stdin + sys.argv = real_argv + + +@contextmanager +def swap_stdout(): + """ + context manager that temporarily replaces stdout for tests that need to verify output + """ + old_stdout = sys.stdout + + if PY3: + fake_stream = StringIO() + else: + fake_stream = BytesIO() + + try: + sys.stdout = fake_stream + + yield fake_stream + finally: + sys.stdout = old_stdout + + +class ModuleTestCase(unittest.TestCase): + def setUp(self, module_args=None): + if module_args is None: + module_args = { + "_ansible_remote_tmp": "/tmp", + "_ansible_keep_remote_files": False, + } + + args = json.dumps(dict(ANSIBLE_MODULE_ARGS=module_args)) + + # unittest doesn't have a clean place to use a context manager, so we have to enter/exit manually + self.stdin_swap = swap_stdin_and_argv(stdin_data=args) + self.stdin_swap.__enter__() + + def tearDown(self): + # unittest doesn't have a clean place to use a context manager, so we have to enter/exit manually + self.stdin_swap.__exit__(None, None, None) diff --git a/ansible_collections/cisco/nxos/tests/unit/mock/vault_helper.py b/ansible_collections/cisco/nxos/tests/unit/mock/vault_helper.py new file mode 100644 index 00000000..6006ba96 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/mock/vault_helper.py @@ -0,0 +1,40 @@ +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from ansible.module_utils._text import to_bytes +from ansible.parsing.vault import VaultSecret + + +class TextVaultSecret(VaultSecret): + """A secret piece of text. ie, a password. Tracks text encoding. + + The text encoding of the text may not be the default text encoding so + we keep track of the encoding so we encode it to the same bytes.""" + + def __init__(self, text, encoding=None, errors=None, _bytes=None): + super(TextVaultSecret, self).__init__() + self.text = text + self.encoding = encoding or "utf-8" + self._bytes = _bytes + self.errors = errors or "strict" + + @property + def bytes(self): + """The text encoded with encoding, unless we specifically set _bytes.""" + return self._bytes or to_bytes(self.text, encoding=self.encoding, errors=self.errors) diff --git a/ansible_collections/cisco/nxos/tests/unit/mock/yaml_helper.py b/ansible_collections/cisco/nxos/tests/unit/mock/yaml_helper.py new file mode 100644 index 00000000..2e857592 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/mock/yaml_helper.py @@ -0,0 +1,157 @@ +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type +import io + +import yaml + +from ansible.module_utils.six import PY3 +from ansible.parsing.yaml.dumper import AnsibleDumper +from ansible.parsing.yaml.loader import AnsibleLoader + + +class YamlTestUtils(object): + """Mixin class to combine with a unittest.TestCase subclass.""" + + def _loader(self, stream): + """Vault related tests will want to override this. + + Vault cases should setup a AnsibleLoader that has the vault password.""" + return AnsibleLoader(stream) + + def _dump_stream(self, obj, stream, dumper=None): + """Dump to a py2-unicode or py3-string stream.""" + if PY3: + return yaml.dump(obj, stream, Dumper=dumper) + else: + return yaml.dump(obj, stream, Dumper=dumper, encoding=None) + + def _dump_string(self, obj, dumper=None): + """Dump to a py2-unicode or py3-string""" + if PY3: + return yaml.dump(obj, Dumper=dumper) + else: + return yaml.dump(obj, Dumper=dumper, encoding=None) + + def _dump_load_cycle(self, obj): + # Each pass though a dump or load revs the 'generation' + # obj to yaml string + string_from_object_dump = self._dump_string(obj, dumper=AnsibleDumper) + + # wrap a stream/file like StringIO around that yaml + stream_from_object_dump = io.StringIO(string_from_object_dump) + loader = self._loader(stream_from_object_dump) + # load the yaml stream to create a new instance of the object (gen 2) + obj_2 = loader.get_data() + + # dump the gen 2 objects directory to strings + string_from_object_dump_2 = self._dump_string(obj_2, dumper=AnsibleDumper) + + # The gen 1 and gen 2 yaml strings + self.assertEqual(string_from_object_dump, string_from_object_dump_2) + # the gen 1 (orig) and gen 2 py object + self.assertEqual(obj, obj_2) + + # again! gen 3... load strings into py objects + stream_3 = io.StringIO(string_from_object_dump_2) + loader_3 = self._loader(stream_3) + obj_3 = loader_3.get_data() + + string_from_object_dump_3 = self._dump_string(obj_3, dumper=AnsibleDumper) + + self.assertEqual(obj, obj_3) + # should be transitive, but... + self.assertEqual(obj_2, obj_3) + self.assertEqual(string_from_object_dump, string_from_object_dump_3) + + def _old_dump_load_cycle(self, obj): + """Dump the passed in object to yaml, load it back up, dump again, compare.""" + stream = io.StringIO() + + yaml_string = self._dump_string(obj, dumper=AnsibleDumper) + self._dump_stream(obj, stream, dumper=AnsibleDumper) + + yaml_string_from_stream = stream.getvalue() + + # reset stream + stream.seek(0) + + loader = self._loader(stream) + # loader = AnsibleLoader(stream, vault_password=self.vault_password) + obj_from_stream = loader.get_data() + + stream_from_string = io.StringIO(yaml_string) + loader2 = self._loader(stream_from_string) + # loader2 = AnsibleLoader(stream_from_string, vault_password=self.vault_password) + obj_from_string = loader2.get_data() + + stream_obj_from_stream = io.StringIO() + stream_obj_from_string = io.StringIO() + + if PY3: + yaml.dump(obj_from_stream, stream_obj_from_stream, Dumper=AnsibleDumper) + yaml.dump(obj_from_stream, stream_obj_from_string, Dumper=AnsibleDumper) + else: + yaml.dump( + obj_from_stream, + stream_obj_from_stream, + Dumper=AnsibleDumper, + encoding=None, + ) + yaml.dump( + obj_from_stream, + stream_obj_from_string, + Dumper=AnsibleDumper, + encoding=None, + ) + + yaml_string_stream_obj_from_stream = stream_obj_from_stream.getvalue() + yaml_string_stream_obj_from_string = stream_obj_from_string.getvalue() + + stream_obj_from_stream.seek(0) + stream_obj_from_string.seek(0) + + if PY3: + yaml_string_obj_from_stream = yaml.dump(obj_from_stream, Dumper=AnsibleDumper) + yaml_string_obj_from_string = yaml.dump(obj_from_string, Dumper=AnsibleDumper) + else: + yaml_string_obj_from_stream = yaml.dump( + obj_from_stream, + Dumper=AnsibleDumper, + encoding=None, + ) + yaml_string_obj_from_string = yaml.dump( + obj_from_string, + Dumper=AnsibleDumper, + encoding=None, + ) + + assert yaml_string == yaml_string_obj_from_stream + assert yaml_string == yaml_string_obj_from_stream == yaml_string_obj_from_string + assert ( + yaml_string + == yaml_string_obj_from_stream + == yaml_string_obj_from_string + == yaml_string_stream_obj_from_stream + == yaml_string_stream_obj_from_string + ) + assert obj == obj_from_stream + assert obj == obj_from_string + assert obj == yaml_string_obj_from_stream + assert obj == yaml_string_obj_from_string + assert ( + obj + == obj_from_stream + == obj_from_string + == yaml_string_obj_from_stream + == yaml_string_obj_from_string + ) + return { + "obj": obj, + "yaml_string": yaml_string, + "yaml_string_from_stream": yaml_string_from_stream, + "obj_from_stream": obj_from_stream, + "obj_from_string": obj_from_string, + "yaml_string_obj_from_string": yaml_string_obj_from_string, + } diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/conftest.py b/ansible_collections/cisco/nxos/tests/unit/modules/conftest.py new file mode 100644 index 00000000..41465c30 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/conftest.py @@ -0,0 +1,32 @@ +# Copyright (c) 2017 Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +import json + +import pytest + +from ansible.module_utils._text import to_bytes +from ansible.module_utils.common._collections_compat import MutableMapping +from ansible.module_utils.six import string_types + + +@pytest.fixture +def patch_ansible_module(request, mocker): + if isinstance(request.param, string_types): + args = request.param + elif isinstance(request.param, MutableMapping): + if "ANSIBLE_MODULE_ARGS" not in request.param: + request.param = {"ANSIBLE_MODULE_ARGS": request.param} + if "_ansible_remote_tmp" not in request.param["ANSIBLE_MODULE_ARGS"]: + request.param["ANSIBLE_MODULE_ARGS"]["_ansible_remote_tmp"] = "/tmp" + if "_ansible_keep_remote_files" not in request.param["ANSIBLE_MODULE_ARGS"]: + request.param["ANSIBLE_MODULE_ARGS"]["_ansible_keep_remote_files"] = False + args = json.dumps(request.param) + else: + raise Exception("Malformed data to the patch_ansible_module pytest fixture") + + mocker.patch("ansible.module_utils.basic._ANSIBLE_ARGS", to_bytes(args)) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/_nxos_ip_interface.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/_nxos_ip_interface.cfg new file mode 100644 index 00000000..e68520bf --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/_nxos_ip_interface.cfg @@ -0,0 +1,30 @@ +IP Interface Status for VRF "default"(1) +Ethernet2/4, Interface status: protocol-up/link-up/admin-up, iod: 39, + IP address: 192.0.2.1, IP subnet: 1.1.1.0/8 route-preference: 0, tag: 0 + IP broadcast address: 255.255.255.255 + IP multicast groups locally joined: none + IP MTU: 1500 bytes (using link MTU) + IP primary address route-preference: 0, tag: 0 + IP proxy ARP : disabled + IP Local Proxy ARP : disabled + IP multicast routing: disabled + IP icmp redirects: enabled + IP directed-broadcast: disabled + IP Forwarding: disabled + IP icmp unreachables (except port): disabled + IP icmp port-unreachable: enabled + IP unicast reverse path forwarding: none + IP load sharing: none + IP interface statistics last reset: never + IP interface software stats: (sent/received/forwarded/originated/consumed) + Unicast packets : 0/0/0/0/0 + Unicast bytes : 0/0/0/0/0 + Multicast packets : 0/0/0/0/0 + Multicast bytes : 0/0/0/0/0 + Broadcast packets : 0/0/0/0/0 + Broadcast bytes : 0/0/0/0/0 + Labeled packets : 0/0/0/0/0 + Labeled bytes : 0/0/0/0/0 + WCCP Redirect outbound: disabled + WCCP Redirect inbound: disabled + WCCP Redirect exclude: disabled diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/cliconf/mds/show_inventory b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/cliconf/mds/show_inventory new file mode 100644 index 00000000..3f8c22b1 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/cliconf/mds/show_inventory @@ -0,0 +1,53 @@ +NAME: "Chassis", DESCR: "MDS 9710 (10 Slot) Chassis" +PID: DS-C9710 , VID: V01 , SN: JAF1724ADSD + +NAME: "Slot 1", DESCR: "4/8/16/32 Gbps Advanced FC Module" +PID: DS-X9648-1536K9 , VID: V01 , SN: JAE204207TT + +NAME: "Slot 2", DESCR: "1/10/40G IPS,2/4/8/10/16G FC Module" +PID: DS-X9334-K9 , VID: V00 , SN: JAE200806S9 + +NAME: "Slot 3", DESCR: "2/4/8/10/16 Gbps Advanced FC Module" +PID: DS-X9448-768K9 , VID: V01 , SN: JAE180605X5 + +NAME: "Slot 4", DESCR: "2/4/8/10/16 Gbps Advanced FC Module" +PID: DS-X9448-768K9 , VID: V01 , SN: JAE180605XZ + +NAME: "Slot 5", DESCR: "Supervisor Module-3" +PID: DS-X97-SF1-K9 , VID: V01 , SN: JAE172007TK + +NAME: "Slot 6", DESCR: "Supervisor Module-3" +PID: DS-X97-SF1-K9 , VID: V01 , SN: JAE17200573 + +NAME: "Slot 7", DESCR: "4/8/16/32 Gbps Advanced FC Module" +PID: DS-X9648-1536K9 , VID: V01 , SN: JAE203901ZM + +NAME: "Slot 8", DESCR: "1/10/40G IPS,2/4/8/10/16G FC Module" +PID: DS-X9334-K9 , VID: V02 , SN: JAE240306KZ + +NAME: "Slot 11", DESCR: "Fabric card module" +PID: DS-X9710-FAB1 , VID: V01 , SN: JAE172008WA + +NAME: "Slot 12", DESCR: "Fabric card module" +PID: DS-X9710-FAB1 , VID: V01 , SN: JAE172006B7 + +NAME: "Slot 13", DESCR: "Fabric card module" +PID: DS-X9710-FAB1 , VID: V01 , SN: JAE1720069V + +NAME: "Slot 33", DESCR: "MDS 9710 (10 Slot) Chassis Power Supply" +PID: DS-CAC97-3KW , VID: V01 , SN: DTM172005SG + +NAME: "Slot 34", DESCR: "MDS 9710 (10 Slot) Chassis Power Supply" +PID: DS-CAC97-3KW , VID: V01 , SN: DTM172005SH + +NAME: "Slot 35", DESCR: "MDS 9710 (10 Slot) Chassis Power Supply" +PID: DS-CAC97-3KW , VID: V01 , SN: DTM172005JK + +NAME: "Slot 41", DESCR: "MDS 9710 (10 Slot) Chassis Fan Module" +PID: DS-C9710-FAN , VID: V01 , SN: JAF1724ALHP + +NAME: "Slot 42", DESCR: "MDS 9710 (10 Slot) Chassis Fan Module" +PID: DS-C9710-FAN , VID: V01 , SN: JAF1721ALCB + +NAME: "Slot 43", DESCR: "MDS 9710 (10 Slot) Chassis Fan Module" +PID: DS-C9710-FAN , VID: V01 , SN: JAF1721AKRL diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/cliconf/mds/show_version b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/cliconf/mds/show_version new file mode 100644 index 00000000..c14b76b5 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/cliconf/mds/show_version @@ -0,0 +1,40 @@ +Cisco Nexus Operating System (NX-OS) Software +TAC support: http://www.cisco.com/tac +Documents: http://www.cisco.com/en/US/products/ps9372/tsd_products_support_serie +s_home.html +Copyright (c) 2002-2020, Cisco Systems, Inc. All rights reserved. +The copyrights to certain works contained herein are owned by +other third parties and are used and distributed under license. +Some parts of this software are covered under the GNU Public +License. A copy of the license is available at +http://www.gnu.org/licenses/gpl.html. + +Software + BIOS: version 2.1.18 + loader: version N/A + kickstart: version 8.4(2b) + system: version 8.4(2b) + BIOS compile time: 04/06/20 + kickstart image file is: bootflash:///m9100-s5ek9-kickstart-mz.8.4.2b.bin + kickstart compile time: 9/30/2020 12:00:00 [10/06/2020 13:37:39] + system image file is: bootflash:///m9100-s5ek9-mz.8.4.2b.bin + system compile time: 9/30/2020 12:00:00 [10/06/2020 15:30:06] + + +Hardware + cisco MDS 9148S 16G 48 FC (1 Slot) Chassis ("2/4/8/16 Gbps FC/Supervisor") + Motorola, e500v2 with 4088624 kB of memory. + Processor Board ID JAF1751BGPS + + Device name: sw109-Mini + bootflash: 4001760 kB + +Kernel uptime is 42 day(s), 23 hour(s), 31 minute(s), 29 second(s) + +Last reset at 870592 usecs after Tue Oct 13 17:01:33 2020 + Reason: Reset Requested by CLI command reload + System version: 8.4(2b) + Service: + +plugin + Core Plugin diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/cliconf/nxos/show_inventory b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/cliconf/nxos/show_inventory new file mode 100644 index 00000000..128e9410 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/cliconf/nxos/show_inventory @@ -0,0 +1,8 @@ +NAME: "Chassis", DESCR: "Nexus9000 C9300v Chassis" +PID: N9K-C9300v , VID: , SN: 9UTMKABK3C4 + +NAME: "Slot 1", DESCR: "Nexus 9000v 64 port Ethernet Module" +PID: N9K-X9364v , VID: , SN: 9VUZB48Q0AF + +NAME: "Slot 27", DESCR: "Supervisor Module" +PID: N9K-vSUP , VID: , SN: 9J9LUC1LLV5 diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/cliconf/nxos/show_version b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/cliconf/nxos/show_version new file mode 100644 index 00000000..109c6cd7 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/cliconf/nxos/show_version @@ -0,0 +1,38 @@ +Cisco Nexus Operating System (NX-OS) Software +TAC support: http://www.cisco.com/tac +Documents: http://www.cisco.com/en/US/products/ps9372/tsd_products_support_series_home.html +Copyright (c) 2002-2019, Cisco Systems, Inc. All rights reserved. +The copyrights to certain works contained herein are owned by +other third parties and are used and distributed under license. +Some parts of this software are covered under the GNU Public +License. A copy of the license is available at +http://www.gnu.org/licenses/gpl.html. + +Nexus 9000v is a demo version of the Nexus Operating System + +Software + BIOS: version + NXOS: version 9.3(3) + BIOS compile time: + NXOS image file is: bootflash:///nxos.9.3.3.bin + NXOS compile time: 12/22/2019 2:00:00 [12/22/2019 14:00:37] + + +Hardware + cisco Nexus9000 C9300v Chassis + Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz with 6087432 kB of memory. + Processor Board ID 9J9LUC1LLV5 + + Device name: nxos-9kv-933 + bootflash: 4287040 kB +Kernel uptime is 2 day(s), 5 hour(s), 5 minute(s), 41 second(s) + +Last reset + Reason: Unknown + System version: + Service: + +plugin + Core Plugin, Ethernet Plugin + +Active Package(s): diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_acl/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_acl/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_acl/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_acl/show_ip_access-list.txt b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_acl/show_ip_access-list.txt new file mode 100644 index 00000000..d480ae8b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_acl/show_ip_access-list.txt @@ -0,0 +1,227 @@ +{ + "TABLE_ip_ipv6_mac": { + "ROW_ip_ipv6_mac": [ + { + "op_ip_ipv6_mac": "ip", + "acl_name": "copp-system-p-acl-bgp", + "TABLE_seqno": { + "ROW_seqno": [ + { + "seqno": 10, + "permitdeny": "permit", + "proto_str": "tcp", + "src_any": "any", + "src_port_op": "gt", + "src_port1_num": "1024", + "dest_any": "any", + "dest_port_op": "eq", + "dest_port1_str": "bgp", + "dest_port1_num": "179" + }, + { + "seqno": 20, + "permitdeny": "permit", + "proto_str": "tcp", + "src_any": "any", + "src_port_op": "eq", + "src_port1_str": "bgp", + "src_port1_num": "179", + "dest_any": "any", + "dest_port_op": "gt", + "dest_port1_num": "1024" + } + ] + } + }, + { + "op_ip_ipv6_mac": "ip", + "acl_name": "copp-system-p-acl-cts", + "TABLE_seqno": { + "ROW_seqno": [ + { + "seqno": 10, + "permitdeny": "permit", + "proto_str": "tcp", + "src_any": "any", + "dest_any": "any", + "dest_port_op": "eq", + "dest_port1_num": "64999" + }, + { + "seqno": 20, + "permitdeny": "permit", + "proto_str": "tcp", + "src_any": "any", + "src_port_op": "eq", + "src_port1_num": "64999", + "dest_any": "any" + } + ] + } + }, + { + "op_ip_ipv6_mac": "ip", + "acl_name": "copp-system-p-acl-dhcp", + "TABLE_seqno": { + "ROW_seqno": [ + { + "seqno": 10, + "permitdeny": "permit", + "proto_str": "udp", + "src_any": "any", + "src_port_op": "eq", + "src_port1_str": "bootpc", + "src_port1_num": "68", + "dest_any": "any" + }, + { + "seqno": 20, + "permitdeny": "permit", + "proto_str": "udp", + "src_any": "any", + "src_port_op": "neq", + "src_port1_str": "bootps", + "src_port1_num": "67", + "dest_any": "any", + "dest_port_op": "eq", + "dest_port1_str": "bootps", + "dest_port1_num": "67" + } + ] + } + }, + { + "op_ip_ipv6_mac": "ip", + "acl_name": "copp-system-p-acl-dhcp-relay-response", + "TABLE_seqno": { + "ROW_seqno": [ + { + "seqno": 10, + "permitdeny": "permit", + "proto_str": "udp", + "src_any": "any", + "src_port_op": "eq", + "src_port1_str": "bootps", + "src_port1_num": "67", + "dest_any": "any" + }, + { + "seqno": 20, + "permitdeny": "permit", + "proto_str": "udp", + "src_any": "any", + "dest_any": "any", + "dest_port_op": "eq", + "dest_port1_str": "bootpc", + "dest_port1_num": "68" + } + ] + } + }, + { + "op_ip_ipv6_mac": "ip", + "acl_name": "copp-system-p-acl-eigrp", + "TABLE_seqno": { + "ROW_seqno": { + "seqno": 10, + "permitdeny": "permit", + "proto_str": "eigrp", + "src_any": "any", + "dest_any": "any" + } + } + }, + { + "op_ip_ipv6_mac": "ip", + "acl_name": "copp-system-p-acl-ftp", + "TABLE_seqno": { + "ROW_seqno": [ + { + "seqno": 10, + "permitdeny": "permit", + "proto_str": "tcp", + "src_any": "any", + "dest_any": "any", + "dest_port_op": "eq", + "dest_port1_str": "ftp-data", + "dest_port1_num": "20" + }, + { + "seqno": 20, + "permitdeny": "permit", + "proto_str": "tcp", + "src_any": "any", + "dest_any": "any", + "dest_port_op": "eq", + "dest_port1_str": "ftp", + "dest_port1_num": "21" + }, + { + "seqno": 30, + "permitdeny": "permit", + "proto_str": "tcp", + "src_any": "any", + "src_port_op": "eq", + "src_port1_str": "ftp-data", + "src_port1_num": "20", + "dest_any": "any" + }, + { + "seqno": 40, + "permitdeny": "permit", + "proto_str": "tcp", + "src_any": "any", + "src_port_op": "eq", + "src_port1_str": "ftp", + "src_port1_num": "21", + "dest_any": "any" + } + ] + } + }, + { + "op_ip_ipv6_mac": "ip", + "acl_name": "copp-system-p-acl-glbp", + "TABLE_seqno": { + "ROW_seqno": { + "seqno": 10, + "permitdeny": "permit", + "proto_str": "udp", + "src_any": "any", + "src_port_op": "eq", + "src_port1_num": "3222", + "dest_ip_prefix": "224.0.0.0/24", + "dest_port_op": "eq", + "dest_port1_num": "3222" + } + } + }, + { + "op_ip_ipv6_mac": "ip", + "acl_name": "copp-system-p-acl-hsrp", + "TABLE_seqno": { + "ROW_seqno": [ + { + "seqno": 10, + "permitdeny": "permit", + "proto_str": "udp", + "src_any": "any", + "dest_ip_prefix": "224.0.0.2/32", + "dest_port_op": "eq", + "dest_port1_num": "1985" + }, + { + "seqno": 20, + "permitdeny": "permit", + "proto_str": "udp", + "src_any": "any", + "dest_ip_prefix": "224.0.0.102/32", + "dest_port_op": "eq", + "dest_port1_num": "1985" + } + ] + } + } + ] + } +} diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_acl_interface/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_acl_interface/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_acl_interface/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_acl_interface/show_running-config_aclmgr.txt b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_acl_interface/show_running-config_aclmgr.txt new file mode 100644 index 00000000..ccf92c99 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_acl_interface/show_running-config_aclmgr.txt @@ -0,0 +1,4 @@ +ip access-list ANSIBLE_OUT + 10 permit tcp 192.0.2.1/24 any +interface Ethernet1/41 + ip access-group copp-system-p-acl-bgp out diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_acl_interfaces/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_acl_interfaces/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_acl_interfaces/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_acl_interfaces/nxos_acl_interfaces.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_acl_interfaces/nxos_acl_interfaces.cfg new file mode 100644 index 00000000..f22110d4 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_acl_interfaces/nxos_acl_interfaces.cfg @@ -0,0 +1,2 @@ +interface Ethernet1/2 + ip access-group ACL1v4 out diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_bfd_global/N7K.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_bfd_global/N7K.cfg new file mode 100644 index 00000000..efe96268 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_bfd_global/N7K.cfg @@ -0,0 +1,16 @@ +feature bfd + +bfd echo-interface loopback2 +bfd echo-rx-interval 56 +bfd interval 51 min_rx 52 multiplier 4 +bfd slow-timer 2001 +bfd startup-timer 6 +bfd ipv4 echo-rx-interval 54 +bfd ipv4 interval 54 min_rx 54 multiplier 4 +bfd ipv4 slow-timer 2004 +bfd ipv6 echo-rx-interval 56 +bfd ipv6 interval 56 min_rx 56 multiplier 6 +bfd ipv6 slow-timer 2006 +bfd fabricpath slow-timer 2008 +bfd fabricpath interval 58 min_rx 58 multiplier 8 +bfd fabricpath vlan 2 diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_bfd_global/N9K.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_bfd_global/N9K.cfg new file mode 100644 index 00000000..ab1d2d4a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_bfd_global/N9K.cfg @@ -0,0 +1,13 @@ +feature bfd + +bfd echo-interface loopback2 +bfd echo-rx-interval 56 +bfd interval 51 min_rx 52 multiplier 4 +bfd slow-timer 2001 +bfd startup-timer 6 +bfd ipv4 echo-rx-interval 54 +bfd ipv4 interval 54 min_rx 54 multiplier 4 +bfd ipv4 slow-timer 2004 +bfd ipv6 echo-rx-interval 56 +bfd ipv6 interval 56 min_rx 56 multiplier 6 +bfd ipv6 slow-timer 2006 diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_bfd_global/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_bfd_global/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_bfd_global/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_bgp/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_bgp/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_bgp/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_bgp/config.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_bgp/config.cfg new file mode 100644 index 00000000..f0797ee4 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_bgp/config.cfg @@ -0,0 +1,26 @@ +feature bgp + +router bgp 65535 + router-id 192.168.1.1 + event-history cli size medium + event-history detail + vrf test2 + address-family ipv4 unicast + timers bgp 1 10 + neighbor 1.1.1.1 + neighbor 1.1.1.2 + bfd + neighbor 3.3.3.4 + remove-private-as all + neighbor 3.3.3.5 + address-family ipv4 unicast + maximum-prefix 30 30 + neighbor 5.5.5.5 + peer-type fabric-border-leaf + neighbor 6.6.6.6 + peer-type fabric-external + address-family l2vpn evpn + retain route-target route-map xyz + neighbor 7.7.7.7 + address-family l2vpn evpn + rewrite-evpn-rt-asn diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_bgp/config_32_bits_as.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_bgp/config_32_bits_as.cfg new file mode 100644 index 00000000..03db9936 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_bgp/config_32_bits_as.cfg @@ -0,0 +1,6 @@ +feature bgp + +router bgp 65535.65535 + router-id 192.168.1.1 + vrf test + address-family ipv4 unicast diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_command/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_command/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_command/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_command/show_version.txt b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_command/show_version.txt new file mode 100644 index 00000000..08ba1ad3 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_command/show_version.txt @@ -0,0 +1,66 @@ +Cisco NX-OS Software +Copyright (c) 2002-2016, Cisco Systems, Inc. All rights reserved. +NX-OSv software ("NX-OSv Software") and related documentation, +files or other reference materials ("Documentation") are +the proprietary property and confidential information of Cisco +Systems, Inc. ("Cisco") and are protected, without limitation, +pursuant to United States and International copyright and trademark +laws in the applicable jurisdiction which provide civil and criminal +penalties for copying or distribution without Cisco's authorization. + +Any use or disclosure, in whole or in part, of the NX-OSv Software +or Documentation to any third party for any purposes is expressly +prohibited except as otherwise authorized by Cisco in writing. +The copyrights to certain works contained herein are owned by other +third parties and are used and distributed under license. Some parts +of this software may be covered under the GNU Public License or the +GNU Lesser General Public License. A copy of each such license is +available at +http://www.gnu.org/licenses/gpl.html and +http://www.gnu.org/licenses/lgpl.html +*************************************************************************** +* NX-OSv is strictly limited to use for evaluation, demonstration and * +* NX-OS education. NX-OSv is provided as-is and is not supported by * +* Cisco's Technical Advisory Center. Any use or disclosure, in whole or * +* in part of the NX-OSv Software or Documentation to any third party for * +* any purposes is expressly prohibited except as otherwise authorized by * +* Cisco in writing. * +*************************************************************************** +nxos01# show version +Cisco Nexus Operating System (NX-OS) Software +TAC support: http://www.cisco.com/tac +Documents: http://www.cisco.com/en/US/products/ps9372/tsd_products_support_series_home.html +Copyright (c) 2002-2016, Cisco Systems, Inc. All rights reserved. +The copyrights to certain works contained herein are owned by +other third parties and are used and distributed under license. +Some parts of this software are covered under the GNU Public +License. A copy of the license is available at +http://www.gnu.org/licenses/gpl.html. + +NX-OSv is a demo version of the Nexus Operating System + +Software + loader: version N/A + kickstart: version 7.3(0)D1(1) + system: version 7.3(0)D1(1) + kickstart image file is: bootflash:///titanium-d1-kickstart.7.3.0.D1.1.bin + kickstart compile time: 1/11/2016 16:00:00 [02/11/2016 10:30:12] + system image file is: bootflash:///titanium-d1.7.3.0.D1.1.bin + system compile time: 1/11/2016 16:00:00 [02/11/2016 13:08:11] + + +Hardware + cisco NX-OSv Chassis ("NX-OSv Supervisor Module") + QEMU Virtual CPU version 2.0 with 3064860 kB of memory. + Processor Board ID TM3E35B910B + + Device name: nxos01 + bootflash: 3184776 kB + +Kernel uptime is 7 day(s), 17 hour(s), 0 minute(s), 23 second(s) + + +plugin + Core Plugin, Ethernet Plugin + +Active Package(s) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_config/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_config/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_config/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_config/candidate.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_config/candidate.cfg new file mode 100644 index 00000000..b11bc93e --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_config/candidate.cfg @@ -0,0 +1,7 @@ +hostname switch01 +! +interface Ethernet1 + description test interface + no shutdown +! +ip routing diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_config/config.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_config/config.cfg new file mode 100644 index 00000000..6a471371 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_config/config.cfg @@ -0,0 +1,26 @@ +! +hostname localhost +ip domain-name eng.ansible.com +! +vrf definition mgmt +! +vrf definition test +! +interface Management1 + ip address 192.168.1.1/24 +! +interface Ethernet1 + shutdown +! +interface Ethernet2 + shutdown +! +interface Ethernet3 + shutdown +! +interface Ethernet4 + shutdown +! +interface Ethernet5 + shutdown +! diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_devicealias/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_devicealias/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_devicealias/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_devicealias/shdadatabse.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_devicealias/shdadatabse.cfg new file mode 100644 index 00000000..8eb233a6 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_devicealias/shdadatabse.cfg @@ -0,0 +1,4 @@ +device-alias name test1_add pwwn 56:02:22:11:22:88:11:67 +device-alias name test2_add pwwn 65:22:22:11:22:22:11:0d +device-alias name tieHost-1 pwwn 10:00:00:00:89:a1:01:01 +device-alias name tieHost-2 pwwn 10:00:00:00:89:a1:01:02 diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_devicealias/shdastatus.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_devicealias/shdastatus.cfg new file mode 100644 index 00000000..8086451d --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_devicealias/shdastatus.cfg @@ -0,0 +1,3 @@ +Fabric Distribution : Enabled +Database:- Device Aliases 3831 Mode: Enhanced + Checksum: 0xdc7b6c6c124abd8fe28cf6a1ab293c diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_devicealias/shdastatus_mansi.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_devicealias/shdastatus_mansi.cfg new file mode 100644 index 00000000..442e2d37 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_devicealias/shdastatus_mansi.cfg @@ -0,0 +1,3 @@ +Fabric Distribution : Disabled +Database:- Device Aliases 3831 Mode: Basic + Checksum: 0xdc7b6c6c124abd8fe28cf6a1ab293c diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_devicealias/shdastatuslock.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_devicealias/shdastatuslock.cfg new file mode 100644 index 00000000..7e70c3b9 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_devicealias/shdastatuslock.cfg @@ -0,0 +1,5 @@ +Fabric Distribution : Enabled +Database:- Device Aliases 3831 Mode: Enhanced + Checksum: 0xdc7b6c6c124abd8fe28cf6a1ab293c +Locked By:- User "CLI/SNMPv3:admin" SWWN 20:00:54:7f:ee:1b:13:f0 +Pending Database:- Device Aliases 3831 Mode: Enhanced diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_evpn_global/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_evpn_global/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_evpn_global/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_evpn_global/configured.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_evpn_global/configured.cfg new file mode 100644 index 00000000..8246cef1 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_evpn_global/configured.cfg @@ -0,0 +1,2 @@ +hostname switch01 +nv overlay evpn diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_evpn_global/unconfigured.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_evpn_global/unconfigured.cfg new file mode 100644 index 00000000..c555eaaf --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_evpn_global/unconfigured.cfg @@ -0,0 +1 @@ +hostname switch01 diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_evpn_vni_config.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_evpn_vni_config.cfg new file mode 100644 index 00000000..b1c8352f --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_evpn_vni_config.cfg @@ -0,0 +1,8 @@ +nv overlay evpn +feature nv overlay + +evpn + vni 6000 l2 + rd auto + route-target import auto + route-target export auto diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_feature/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_feature/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_feature/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_feature/show_feature.txt b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_feature/show_feature.txt new file mode 100644 index 00000000..e27c595c --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_feature/show_feature.txt @@ -0,0 +1,4 @@ +Feature Name Instance State +-------------------- -------- ----- +nve 1 disabled +ospf 1 enabled diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_feature/show_feature_mds.txt b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_feature/show_feature_mds.txt new file mode 100644 index 00000000..fee0225c --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_feature/show_feature_mds.txt @@ -0,0 +1,36 @@ +Feature Name Instance State +-------------------- -------- ----- +analytics 1 enabled +bulkstat 1 disabled +cimserver 1 disabled +cluster 1 disabled +dpvm 1 disabled +elo 1 disabled +evmed 1 disabled +extended_credit 1 disabled +fabric-access 1 disabled +fabric-binding 1 disabled +fcsp 1 disabled +fpm 1 disabled +fport-channel-trunk 1 enabled +http-server 1 enabled +isapi 1 enabled +ivr 1 disabled +ldap 1 disabled +license-smart 1 enabled +npiv 1 enabled +port-security 1 disabled +port_track 1 enabled +privilege 1 disabled +qos-manager 1 disabled +scheduler 1 enabled +scpServer 1 enabled +sdv 1 disabled +sfm 1 disabled +sftpServer 1 disabled +sshServer 1 enabled +tacacs 1 enabled +telemetry 1 enabled +telnetServer 1 enabled +tpc 1 disabled +vmis 1 disabled diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_interface/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_interface/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_interface/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_interface/show_interface b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_interface/show_interface new file mode 100644 index 00000000..35e74eb8 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_interface/show_interface @@ -0,0 +1,129 @@ +{ + "TABLE_interface": { + "ROW_interface": [ + { + "interface": "Ethernet2/1", + "state": "up", + "admin_state": "up", + "share_state": "Dedicated", + "eth_hw_desc": "Ethernet", + "eth_hw_addr": "fa16.3e50.6647", + "eth_bia_addr": "fa16.3e50.6619", + "desc": "Test aggregation on first interface", + "eth_mtu": "1500", + "eth_bw": 1000000, + "eth_dly": 10, + "eth_reliability": "255", + "eth_txload": "1", + "eth_rxload": "1", + "medium": "broadcast", + "eth_mode": "routed", + "eth_duplex": "full", + "eth_speed": "1000 Mb/s", + "eth_beacon": "off", + "eth_autoneg": "off", + "eth_in_flowctrl": "off", + "eth_out_flowctrl": "off", + "eth_mdix": "off", + "eth_swt_monitor": "off", + "eth_ethertype": "0x8100", + "eth_eee_state": "n/a", + "eth_link_flapped": "4d15h", + "eth_clear_counters": "never", + "eth_reset_cntr": 87, + "eth_load_interval1_rx": 0, + "eth_inrate1_bits": 0, + "eth_inrate1_pkts": 0, + "eth_load_interval1_tx": 0, + "eth_outrate1_bits": 0, + "eth_outrate1_pkts": 0, + "eth_inrate1_summary_bits": "0 bps", + "eth_inrate1_summary_pkts": "0 pps", + "eth_outrate1_summary_bits": "0 bps", + "eth_outrate1_summary_pkts": "0 pps", + "eth_load_interval2_rx": 0, + "eth_inrate2_bits": 0, + "eth_inrate2_pkts": 0, + "eth_load_interval2_tx": 0, + "eth_outrate2_bits": 0, + "eth_outrate2_pkts": 0, + "eth_inrate2_summary_bits": "0 bps", + "eth_inrate2_summary_pkts": "0 pps", + "eth_outrate2_summary_bits": "0 bps", + "eth_outrate2_summary_pkts": "0 pps", + "eth_inucast": 0, + "eth_inmcast": 0, + "eth_inbcast": 0, + "eth_inpkts": 0, + "eth_inbytes": 0, + "eth_jumbo_inpkts": 0, + "eth_storm_supp": 0, + "eth_runts": 0, + "eth_giants": 0, + "eth_crc": 0, + "eth_nobuf": 0, + "eth_inerr": 0, + "eth_frame": 0, + "eth_overrun": 0, + "eth_underrun": 0, + "eth_ignored": 0, + "eth_watchdog": 0, + "eth_bad_eth": 0, + "eth_bad_proto": 0, + "eth_in_ifdown_drops": 0, + "eth_dribble": 0, + "eth_indiscard": 0, + "eth_inpause": 0, + "eth_outucast": 0, + "eth_outmcast": 0, + "eth_outbcast": 0, + "eth_outpkts": 0, + "eth_outbytes": 0, + "eth_jumbo_outpkts": 0, + "eth_outerr": 0, + "eth_coll": 0, + "eth_deferred": 0, + "eth_latecoll": 0, + "eth_lostcarrier": 0, + "eth_nocarrier": 0, + "eth_babbles": 0, + "eth_outdiscard": 0, + "eth_outpause": 0 + }, + { + "interface": "loopback0", + "state": "up", + "admin_state": "up", + "eth_hw_desc": "Loopback", + "desc": "Loopback", + "eth_ip_addr": "192.168.255.1", + "eth_ip_mask": 32, + "eth_ip_prefix": "192.168.255.1", + "eth_mtu": "1500", + "eth_bw": 8000000, + "eth_dly": 5000, + "eth_reliability": "255", + "eth_txload": "1", + "eth_rxload": "1", + "medium": "broadcast", + "eth_mode": "routed", + "eth_mdix": "off", + "loop_in_pkts": 1451854, + "loop_in_bytes": 75138128, + "loop_in_mcast": 0, + "loop_in_compressed": 0, + "loop_in_errors": 0, + "loop_in_frame": 0, + "loop_in_overrun": 0, + "loop_in_fifo": 0, + "loop_out_pkts": 0, + "loop_out_bytes": 0, + "loop_out_underruns": 0, + "loop_out_errors": 0, + "loop_out_collisions": 0, + "loop_out_fifo": 0, + "loop_out_carriers": 0 + } + ] + } +} diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_interface/show_interface_Ethernet2_1 b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_interface/show_interface_Ethernet2_1 new file mode 100644 index 00000000..f478350f --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_interface/show_interface_Ethernet2_1 @@ -0,0 +1,96 @@ +{ + "TABLE_interface": { + "ROW_interface": { + "interface": "Ethernet2/1", + "state": "up", + "admin_state": "up", + "share_state": "Dedicated", + "eth_hw_desc": "Ethernet", + "eth_hw_addr": "fa16.3e00.0001", + "eth_bia_addr": "fa16.3e27.f279", + "desc": "to nxos03", + "eth_ip_addr": "10.0.0.45", + "eth_ip_mask": 30, + "eth_ip_prefix": "10.0.0.44", + "eth_mtu": "1500", + "eth_bw": 1000000, + "eth_dly": 10, + "eth_reliability": "255", + "eth_txload": "1", + "eth_rxload": "1", + "medium": "broadcast", + "eth_mode": "routed", + "eth_duplex": "full", + "eth_speed": "1000 Mb/s", + "eth_beacon": "off", + "eth_autoneg": "off", + "eth_in_flowctrl": "off", + "eth_out_flowctrl": "off", + "eth_mdix": "off", + "eth_swt_monitor": "off", + "eth_ethertype": "0x8100", + "eth_eee_state": "n/a", + "eth_link_flapped": "14week(s) 0day(s)", + "eth_clear_counters": "never", + "eth_reset_cntr": 1, + "eth_load_interval1_rx": 0, + "eth_inrate1_bits": 0, + "eth_inrate1_pkts": 0, + "eth_load_interval1_tx": 0, + "eth_outrate1_bits": 0, + "eth_outrate1_pkts": 0, + "eth_inrate1_summary_bits": "0 bps", + "eth_inrate1_summary_pkts": "0 pps", + "eth_outrate1_summary_bits": "0 bps", + "eth_outrate1_summary_pkts": "0 pps", + "eth_load_interval2_rx": 0, + "eth_inrate2_bits": 0, + "eth_inrate2_pkts": 0, + "eth_load_interval2_tx": 0, + "eth_outrate2_bits": 0, + "eth_outrate2_pkts": 0, + "eth_inrate2_summary_bits": "0 bps", + "eth_inrate2_summary_pkts": "0 pps", + "eth_outrate2_summary_bits": "0 bps", + "eth_outrate2_summary_pkts": "0 pps", + "eth_inucast": 0, + "eth_inmcast": 0, + "eth_inbcast": 0, + "eth_inpkts": 0, + "eth_inbytes": 0, + "eth_jumbo_inpkts": 0, + "eth_storm_supp": 0, + "eth_runts": 0, + "eth_giants": 0, + "eth_crc": 0, + "eth_nobuf": 0, + "eth_inerr": 0, + "eth_frame": 0, + "eth_overrun": 0, + "eth_underrun": 0, + "eth_ignored": 0, + "eth_watchdog": 0, + "eth_bad_eth": 0, + "eth_bad_proto": 0, + "eth_in_ifdown_drops": 0, + "eth_dribble": 0, + "eth_indiscard": 0, + "eth_inpause": 0, + "eth_outucast": 0, + "eth_outmcast": 0, + "eth_outbcast": 0, + "eth_outpkts": 0, + "eth_outbytes": 0, + "eth_jumbo_outpkts": 0, + "eth_outerr": 0, + "eth_coll": 0, + "eth_deferred": 0, + "eth_latecoll": 0, + "eth_lostcarrier": 0, + "eth_nocarrier": 0, + "eth_babbles": 0, + "eth_outdiscard": 0, + "eth_outpause": 0 + } + } +} diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_interface/show_interface_loopback0 b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_interface/show_interface_loopback0 new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_interface/show_interface_loopback0 diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_interface/show_run_interface_Ethernet2_1 b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_interface/show_run_interface_Ethernet2_1 new file mode 100644 index 00000000..e60c3b4c --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_interface/show_run_interface_Ethernet2_1 @@ -0,0 +1,8 @@ +interface Ethernet1/5 + description to csr02 + no switchport + speed 1000 + mtu 1500 + mac-address fa16.3e00.000b + ip address 172.31.0.66/30 + no shutdown diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_interface/show_run_interface_loopback0 b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_interface/show_run_interface_loopback0 new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_interface/show_run_interface_loopback0 diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_interface_ospf/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_interface_ospf/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_interface_ospf/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_interface_ospf/config.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_interface_ospf/config.cfg new file mode 100644 index 00000000..2061d4d7 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_interface_ospf/config.cfg @@ -0,0 +1,17 @@ +interface Ethernet1/33 +interface Ethernet1/33.101 + ip router ospf 1 area 0.0.0.1 +interface Ethernet1/34 + ip router ospf 1 area 0.0.0.1 + ip ospf passive-interface +interface Ethernet1/35 + ip router ospf 1 area 0.0.0.1 + no ip ospf passive-interface + +interface Ethernet1/36 + ip router ospf 1 area 0.0.0.1 + ip ospf bfd + +interface Ethernet1/37 + ip router ospf 1 area 0.0.0.1 + ip ospf bfd disable diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_l3_interface/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_l3_interface/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_l3_interface/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_l3_interface/ethernet_noshut b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_l3_interface/ethernet_noshut new file mode 100644 index 00000000..b0407edc --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_l3_interface/ethernet_noshut @@ -0,0 +1,3 @@ +interface Ethernet1/1 + description Configured by Ansible + no shutdown diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_l3_interface/ethernet_noshut_ipv4_ipv6 b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_l3_interface/ethernet_noshut_ipv4_ipv6 new file mode 100644 index 00000000..3e4f1978 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_l3_interface/ethernet_noshut_ipv4_ipv6 @@ -0,0 +1,5 @@ +interface Ethernet1/1 + description Configured by Ansible + ip address 192.168.0.1/24 + ipv6 address 2001:db8::1/124 + no shutdown diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_l3_interface/ethernet_noshut_multiple_ipv6 b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_l3_interface/ethernet_noshut_multiple_ipv6 new file mode 100644 index 00000000..9013b134 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_l3_interface/ethernet_noshut_multiple_ipv6 @@ -0,0 +1,7 @@ +interface Ethernet1/1 + description Configured by Ansible + ip address 192.168.0.1/24 + ipv6 address 2001:db8:1::1/124 + ipv6 address 2001:db8:2::1/124 + ipv6 address 2001:db8::1/124 + no shutdown diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_nxapi/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_nxapi/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_nxapi/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_nxapi/n3k/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_nxapi/n3k/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_nxapi/n3k/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_nxapi/n3k/show_run_all b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_nxapi/n3k/show_run_all new file mode 100644 index 00000000..da0dfaa7 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_nxapi/n3k/show_run_all @@ -0,0 +1,2 @@ +feature nxapi +nxapi http port 80 diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_nxapi/n7k/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_nxapi/n7k/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_nxapi/n7k/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_nxapi/n7k/show_run_all b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_nxapi/n7k/show_run_all new file mode 100644 index 00000000..e977fae6 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_nxapi/n7k/show_run_all @@ -0,0 +1,4 @@ +feature nxapi +nxapi http port 80 +no nxapi https +no nxapi sandbox diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_overlay_global_config.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_overlay_global_config.cfg new file mode 100644 index 00000000..45a6ff99 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_overlay_global_config.cfg @@ -0,0 +1 @@ +fabric forwarding anycast-gateway-mac 000B.000B.000B diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_pim/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_pim/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_pim/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_pim/config.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_pim/config.cfg new file mode 100644 index 00000000..9771622d --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_pim/config.cfg @@ -0,0 +1,2 @@ +ip pim bfd +ip pim ssm range 127.0.0.0/31 diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_pim_interface/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_pim_interface/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_pim_interface/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_pim_interface/config.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_pim_interface/config.cfg new file mode 100644 index 00000000..2120e607 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_pim_interface/config.cfg @@ -0,0 +1,11 @@ +!Command: show running-config interface Ethernet2/1 +!Time: Mon Aug 21 17:22:02 2017 + +version 7.3(0)D1(1) + +interface Ethernet2/1 + description Configured by Ansible - Layer3 + no switchport + mac-address fa16.3e00.0006 + ip address 10.0.0.69/30 + no shutdown diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_pim_interface/sh_run_interface_eth2_1_all b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_pim_interface/sh_run_interface_eth2_1_all new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_pim_interface/sh_run_interface_eth2_1_all diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_pim_interface/show_interface_eth2_1 b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_pim_interface/show_interface_eth2_1 new file mode 100644 index 00000000..f478350f --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_pim_interface/show_interface_eth2_1 @@ -0,0 +1,96 @@ +{ + "TABLE_interface": { + "ROW_interface": { + "interface": "Ethernet2/1", + "state": "up", + "admin_state": "up", + "share_state": "Dedicated", + "eth_hw_desc": "Ethernet", + "eth_hw_addr": "fa16.3e00.0001", + "eth_bia_addr": "fa16.3e27.f279", + "desc": "to nxos03", + "eth_ip_addr": "10.0.0.45", + "eth_ip_mask": 30, + "eth_ip_prefix": "10.0.0.44", + "eth_mtu": "1500", + "eth_bw": 1000000, + "eth_dly": 10, + "eth_reliability": "255", + "eth_txload": "1", + "eth_rxload": "1", + "medium": "broadcast", + "eth_mode": "routed", + "eth_duplex": "full", + "eth_speed": "1000 Mb/s", + "eth_beacon": "off", + "eth_autoneg": "off", + "eth_in_flowctrl": "off", + "eth_out_flowctrl": "off", + "eth_mdix": "off", + "eth_swt_monitor": "off", + "eth_ethertype": "0x8100", + "eth_eee_state": "n/a", + "eth_link_flapped": "14week(s) 0day(s)", + "eth_clear_counters": "never", + "eth_reset_cntr": 1, + "eth_load_interval1_rx": 0, + "eth_inrate1_bits": 0, + "eth_inrate1_pkts": 0, + "eth_load_interval1_tx": 0, + "eth_outrate1_bits": 0, + "eth_outrate1_pkts": 0, + "eth_inrate1_summary_bits": "0 bps", + "eth_inrate1_summary_pkts": "0 pps", + "eth_outrate1_summary_bits": "0 bps", + "eth_outrate1_summary_pkts": "0 pps", + "eth_load_interval2_rx": 0, + "eth_inrate2_bits": 0, + "eth_inrate2_pkts": 0, + "eth_load_interval2_tx": 0, + "eth_outrate2_bits": 0, + "eth_outrate2_pkts": 0, + "eth_inrate2_summary_bits": "0 bps", + "eth_inrate2_summary_pkts": "0 pps", + "eth_outrate2_summary_bits": "0 bps", + "eth_outrate2_summary_pkts": "0 pps", + "eth_inucast": 0, + "eth_inmcast": 0, + "eth_inbcast": 0, + "eth_inpkts": 0, + "eth_inbytes": 0, + "eth_jumbo_inpkts": 0, + "eth_storm_supp": 0, + "eth_runts": 0, + "eth_giants": 0, + "eth_crc": 0, + "eth_nobuf": 0, + "eth_inerr": 0, + "eth_frame": 0, + "eth_overrun": 0, + "eth_underrun": 0, + "eth_ignored": 0, + "eth_watchdog": 0, + "eth_bad_eth": 0, + "eth_bad_proto": 0, + "eth_in_ifdown_drops": 0, + "eth_dribble": 0, + "eth_indiscard": 0, + "eth_inpause": 0, + "eth_outucast": 0, + "eth_outmcast": 0, + "eth_outbcast": 0, + "eth_outpkts": 0, + "eth_outbytes": 0, + "eth_jumbo_outpkts": 0, + "eth_outerr": 0, + "eth_coll": 0, + "eth_deferred": 0, + "eth_latecoll": 0, + "eth_lostcarrier": 0, + "eth_nocarrier": 0, + "eth_babbles": 0, + "eth_outdiscard": 0, + "eth_outpause": 0 + } + } +} diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_pim_interface/show_ip_pim_interface_eth2_1 b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_pim_interface/show_ip_pim_interface_eth2_1 new file mode 100644 index 00000000..e013423b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_pim_interface/show_ip_pim_interface_eth2_1 @@ -0,0 +1,68 @@ +{ + "TABLE_vrf": { + "ROW_vrf": { + "vrf-name": "default", + "TABLE_iod": { + "ROW_iod": { + "if-name": "Ethernet2/1", + "if-status": "protocol-up/link-up/admin-up", + "if-addr-summary": "IP address: 10.0.0.45, IP subnet: 10.0.0.44/30", + "pim-dr-address": "10.0.0.45", + "dr-priority": 2, + "nbr-cnt": 0, + "hello-interval-sec": 35, + "hello-timer": "PT3S", + "holdtime-sec": 105, + "if-conf-dr-priority": 1, + "if-conf-delay": 3, + "is-border": "true", + "genid": "38c4b959", + "isauth-config": "false", + "nbr-policy-name": "none configured", + "jp-interval": 1, + "jp-next-send": 1, + "pim-bfd-enabled": "no", + "is-passive": "false", + "is-pim-vpc-svi": "no", + "is-auto-enabled": "no", + "last-cleared": "PT0S", + "hello-sent": 23, + "hello-rcvd": 0, + "hello-early-sent": 0, + "jp-sent": 0, + "jp-rcvd": 0, + "assert-sent": 0, + "assert-rcvd": 0, + "graft-sent": 0, + "graft-rcvd": 0, + "graft-ack-sent": 0, + "graft-ack-rcvd": 0, + "df-offer-sent": 0, + "df-offer-rcvd": 0, + "df-winner-sent": 0, + "df-winner-rcvd": 0, + "df-backoff-sent": 0, + "df-backoff-rcvd": 0, + "pass-sent": 0, + "pass-rcvd": 0, + "cksum-errors": 0, + "invalid-errors": 0, + "invalid-df-errors": 0, + "auth-failed": 0, + "pak-len-errors": 0, + "ver-errors": 0, + "pkts-self": 0, + "pkts-non-nbr": 0, + "pkts-on-passive": 0, + "jp-rcvd-on-rpf": 0, + "jp-rcvd-no-rp": 0, + "jp-rcvd-wrong-rp": 0, + "jp-rcvd-for-ssm": 0, + "jp-rcvd-for-bidir": 0, + "jp-in-policy-filter": 0, + "jp-out-policy-filter": 0 + } + } + } + } +} diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_pim_rp_address/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_pim_rp_address/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_pim_rp_address/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_pim_rp_address/config.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_pim_rp_address/config.cfg new file mode 100644 index 00000000..ca9730ec --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_pim_rp_address/config.cfg @@ -0,0 +1 @@ +ip pim rp-address 1.2.3.4 diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_static_route.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_static_route.cfg new file mode 100644 index 00000000..8b1a6fe8 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_static_route.cfg @@ -0,0 +1,3 @@ +ip route 10.10.30.0/24 1.2.4.8 +vrf context test + ip route 10.8.0.0/14 15.16.17.18 diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_switchport/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_switchport/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_switchport/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_switchport/show_interface_ethernet b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_switchport/show_interface_ethernet new file mode 100644 index 00000000..ac8d7d60 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_switchport/show_interface_ethernet @@ -0,0 +1,97 @@ +{ + "TABLE_interface": { + "ROW_interface": { + "interface": "Ethernet2/1", + "state": "up", + "admin_state": "up", + "share_state": "Dedicated", + "eth_hw_desc": "Ethernet", + "eth_hw_addr": "fa16.3e00.0001", + "eth_bia_addr": "fa16.3e27.f279", + "desc": "to nxos03", + "eth_ip_addr": "10.0.0.45", + "eth_ip_mask": 30, + "eth_ip_prefix": "10.0.0.44", + "eth_mtu": "1500", + "eth_bw": 1000000, + "eth_dly": 10, + "eth_reliability": "255", + "eth_txload": "1", + "eth_rxload": "1", + "medium": "broadcast", + "eth_mode": "access", + "eth_bundle": 0, + "eth_duplex": "full", + "eth_speed": "1000 Mb/s", + "eth_beacon": "off", + "eth_autoneg": "off", + "eth_in_flowctrl": "off", + "eth_out_flowctrl": "off", + "eth_mdix": "off", + "eth_swt_monitor": "off", + "eth_ethertype": "0x8100", + "eth_eee_state": "n/a", + "eth_link_flapped": "13week(s) 0day(s)", + "eth_clear_counters": "never", + "eth_reset_cntr": 1, + "eth_load_interval1_rx": 0, + "eth_inrate1_bits": 0, + "eth_inrate1_pkts": 0, + "eth_load_interval1_tx": 0, + "eth_outrate1_bits": 0, + "eth_outrate1_pkts": 0, + "eth_inrate1_summary_bits": "0 bps", + "eth_inrate1_summary_pkts": "0 pps", + "eth_outrate1_summary_bits": "0 bps", + "eth_outrate1_summary_pkts": "0 pps", + "eth_load_interval2_rx": 0, + "eth_inrate2_bits": 0, + "eth_inrate2_pkts": 0, + "eth_load_interval2_tx": 0, + "eth_outrate2_bits": 0, + "eth_outrate2_pkts": 0, + "eth_inrate2_summary_bits": "0 bps", + "eth_inrate2_summary_pkts": "0 pps", + "eth_outrate2_summary_bits": "0 bps", + "eth_outrate2_summary_pkts": "0 pps", + "eth_inucast": 0, + "eth_inmcast": 0, + "eth_inbcast": 0, + "eth_inpkts": 0, + "eth_inbytes": 0, + "eth_jumbo_inpkts": 0, + "eth_storm_supp": 0, + "eth_runts": 0, + "eth_giants": 0, + "eth_crc": 0, + "eth_nobuf": 0, + "eth_inerr": 0, + "eth_frame": 0, + "eth_overrun": 0, + "eth_underrun": 0, + "eth_ignored": 0, + "eth_watchdog": 0, + "eth_bad_eth": 0, + "eth_bad_proto": 0, + "eth_in_ifdown_drops": 0, + "eth_dribble": 0, + "eth_indiscard": 0, + "eth_inpause": 0, + "eth_outucast": 0, + "eth_outmcast": 0, + "eth_outbcast": 0, + "eth_outpkts": 0, + "eth_outbytes": 0, + "eth_jumbo_outpkts": 0, + "eth_outerr": 0, + "eth_coll": 0, + "eth_deferred": 0, + "eth_latecoll": 0, + "eth_lostcarrier": 0, + "eth_nocarrier": 0, + "eth_babbles": 0, + "eth_outdiscard": 0, + "eth_outpause": 0 + } + } +} diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_switchport/show_interface_ethernet_switchport b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_switchport/show_interface_ethernet_switchport new file mode 100644 index 00000000..4163442c --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_switchport/show_interface_ethernet_switchport @@ -0,0 +1,14 @@ +{ + "TABLE_interface": { + "ROW_interface": { + "interface": "Ethernet2/1", + "oper_mode": "access", + "switchport": "Enabled", + "access_vlan": 2, + "access_vlan_name": "VLAN2", + "native_vlan": 10, + "native_vlan_name": "VLAN10", + "trunk_vlans": "1-50" + } + } +} diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_switchport/show_vlan b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_switchport/show_vlan new file mode 100644 index 00000000..80e5ac87 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_switchport/show_vlan @@ -0,0 +1,18 @@ +{ + "TABLE_vlanbrief": { + "ROW_vlanbrief": { + "vlanshowbr-vlanid": 1, + "vlanshowbr-vlanid-utf": 1, + "vlanshowbr-vlanname": "VLAN1", + "vlanshowbr-vlanstate": "active", + "vlanshowbr-shutstate": "noshutdown" + } + }, + "TABLE_mtuinfo": { + "ROW_mtuinfo": { + "vlanshowinfo-vlanid": 1, + "vlanshowinfo-media-type": "enet", + "vlanshowinfo-vlanmode": "ce-vlan" + } + } +} diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_system/config.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_system/config.cfg new file mode 100644 index 00000000..2f0d259c --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_system/config.cfg @@ -0,0 +1,15 @@ +hostname nxos01 +system jumbomtu 1500 +! +no ip domain-lookup +ip domain-name ansible.com +ip domain-list ansible.com +ip domain-list redhat.com +ip name-server 8.8.8.8 172.26.1.1 +! +vrf context management + ip domain-name eng.ansible.com + ip domain-list ansible.com + ip domain-list redhat.com + ip name-server 172.26.1.1 8.8.8.8 + ip route 172.26.0.0/16 172.26.4.1 diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_system/vrf_only/config.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_system/vrf_only/config.cfg new file mode 100644 index 00000000..0e9b2196 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_system/vrf_only/config.cfg @@ -0,0 +1,4 @@ +vrf context test + ip domain-name abc.com +vrf context test2 + ip domain-name xyz.com diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_telemetry/N9K.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_telemetry/N9K.cfg new file mode 100644 index 00000000..697c2c18 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_telemetry/N9K.cfg @@ -0,0 +1,43 @@ +feature telemetry + +telemetry + certificate /bootflash/server.key localhost + destination-profile + use-vrf management + use-compression gzip + source-interface loopback55 + destination-group 2 + ip address 192.168.0.1 port 50001 protocol gRPC encoding GPB + ip address 192.168.0.2 port 60001 protocol gRPC encoding GPB + destination-group 10 + ip address 192.168.0.1 port 50001 protocol gRPC encoding GPB + ip address 192.168.0.2 port 60001 protocol gRPC encoding GPB + sensor-group 2 + data-source DME + path boo depth 0 + path sys/ospf depth 0 query-condition qc filter-condition fc + path interfaces depth 0 + path sys/bgp + path sys/bgp/inst depth 0 query-condition foo filter-condition foo + path sys/bgp/inst/dom-default/peer-[10.10.10.11]/ent-[10.10.10.11] + path sys/bgp/inst/dom-default/peer-[20.20.20.11]/ent-[20.20.20.11] + path too depth 0 filter-condition foo + sensor-group 55 + sensor-group 56 + data-source DME + path environment + path interface + path resources + path vxlan + subscription 3 + subscription 4 + dst-grp 2 + snsr-grp 2 sample-interval 1000 + subscription 5 + dst-grp 2 + snsr-grp 2 sample-interval 1000 + subscription 6 + dst-grp 10 + subscription 7 + dst-grp 10 + snsr-grp 2 sample-interval 1000 diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_telemetry/N9K_SGs.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_telemetry/N9K_SGs.cfg new file mode 100644 index 00000000..1729ad81 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_telemetry/N9K_SGs.cfg @@ -0,0 +1,19 @@ +feature telemetry + +telemetry + sensor-group 1 + path sys/ch depth 4 + path sys/procsys depth 1 + sensor-group 2 + data-source NX-API + path "show bgp l2vpn evpn summary" + path "show isis adjacency" + path "show mac address-table count" depth 2 + path "show bgp sessions" + sensor-group 3 + data-source NX-API + path "show interface ethernet1/1-52" + sensor-group 4 + path sys/bd depth 2 + path sys/eps/epId-1/nws depth 2 + path sys/eps/epId-1/peers depth 2 diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_telemetry/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_telemetry/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_telemetry/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vlan/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vlan/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vlan/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vlan/agg_show_vlan_brief.txt b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vlan/agg_show_vlan_brief.txt new file mode 100644 index 00000000..4ba12553 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vlan/agg_show_vlan_brief.txt @@ -0,0 +1,27 @@ +{ + "TABLE_vlanbriefxbrief": { + "ROW_vlanbriefxbrief": [ + { + "vlanshowbr-vlanid": 1, + "vlanshowbr-vlanid-utf": 1, + "vlanshowbr-vlanname": "default", + "vlanshowbr-vlanstate": "active", + "vlanshowbr-shutstate": "noshutdown" + }, + { + "vlanshowbr-vlanid": 4, + "vlanshowbr-vlanid-utf": 4, + "vlanshowbr-vlanname": "_4_", + "vlanshowbr-vlanstate": "active", + "vlanshowbr-shutstate": "noshutdown" + }, + { + "vlanshowbr-vlanid": 5, + "vlanshowbr-vlanid-utf": 5, + "vlanshowbr-vlanname": "_5_", + "vlanshowbr-vlanstate": "active", + "vlanshowbr-shutstate": "noshutdown" + } + ] + } +} diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vlan/config.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vlan/config.cfg new file mode 100644 index 00000000..905d309f --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vlan/config.cfg @@ -0,0 +1,4 @@ +vlan 1 + mode ce + state active + no shutdown diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vlan/show_vlan_brief.txt b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vlan/show_vlan_brief.txt new file mode 100644 index 00000000..25c08d80 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vlan/show_vlan_brief.txt @@ -0,0 +1,11 @@ +{ + "TABLE_vlanbriefxbrief": { + "ROW_vlanbriefxbrief": { + "vlanshowbr-vlanid": 16777216, + "vlanshowbr-vlanid-utf": 1, + "vlanshowbr-vlanname": "default", + "vlanshowbr-vlanstate": "active", + "vlanshowbr-shutstate": "noshutdown" + } + } +} diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vlans/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vlans/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vlans/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vlans/show_running-config b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vlans/show_running-config new file mode 100644 index 00000000..51e64c99 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vlans/show_running-config @@ -0,0 +1,13 @@ +vlan 1,3-5,8 +vlan 3 + name test-vlan3 +vlan 5 + shutdown + name test-changeme + mode fabricpath + state suspend + vn-segment 942 +vlan 8 + shutdown + name test-changeme-not + state suspend diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vlans/show_running-config_no_facts b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vlans/show_running-config_no_facts new file mode 100644 index 00000000..ef66a7ff --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vlans/show_running-config_no_facts @@ -0,0 +1 @@ +! no data diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vlans/show_vlan b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vlans/show_vlan new file mode 100644 index 00000000..9d53309f --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vlans/show_vlan @@ -0,0 +1,45 @@ +{ + "TABLE_vlanbrief": { + "ROW_vlanbrief": [ + { "vlanshowbr-vlanid": "1", "vlanshowbr-vlanid-utf": "1", + "vlanshowbr-vlanname": "default", + "vlanshowbr-vlanstate": "active", + "vlanshowbr-shutstate": "noshutdown" + }, + { "vlanshowbr-vlanid": "3", "vlanshowbr-vlanid-utf": "3", + "vlanshowbr-vlanname": "test-vlan3", + "vlanshowbr-vlanstate": "active", + "vlanshowbr-shutstate": "noshutdown" + }, + { "vlanshowbr-vlanid": "4", "vlanshowbr-vlanid-utf": "4", + "vlanshowbr-vlanname": "VLAN0004", + "vlanshowbr-vlanstate": "active", + "vlanshowbr-shutstate": "noshutdown" + }, + { "vlanshowbr-vlanid": "5", "vlanshowbr-vlanid-utf": "5", + "vlanshowbr-vlanname": "test-changeme", + "vlanshowbr-vlanstate": "suspend", + "vlanshowbr-shutstate": "shutdown" + }, + { "vlanshowbr-vlanid": "8", "vlanshowbr-vlanid-utf": "8", + "vlanshowbr-vlanname": "test-changeme-not", + "vlanshowbr-vlanstate": "suspend", + "vlanshowbr-shutstate": "shutdown" + } + ] + }, + "TABLE_mtuinfo": { + "ROW_mtuinfo": [ + { "vlanshowinfo-vlanid": "1", "vlanshowinfo-media-type": "enet", + "vlanshowinfo-vlanmode": "ce-vlan" }, + { "vlanshowinfo-vlanid": "3", "vlanshowinfo-media-type": "enet", + "vlanshowinfo-vlanmode": "ce-vlan" }, + { "vlanshowinfo-vlanid": "4", "vlanshowinfo-media-type": "enet", + "vlanshowinfo-vlanmode": "ce-vlan" }, + { "vlanshowinfo-vlanid": "5", "vlanshowinfo-media-type": "enet", + "vlanshowinfo-vlanmode": "fabricpath-vlan" }, + { "vlanshowinfo-vlanid": "8", "vlanshowinfo-media-type": "enet", + "vlanshowinfo-vlanmode": "ce-vlan" } + ] + } +} diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vlans/show_vlan_no_facts b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vlans/show_vlan_no_facts new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vlans/show_vlan_no_facts @@ -0,0 +1 @@ +{} diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vpc/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vpc/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vpc/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vpc/show_vpc b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vpc/show_vpc new file mode 100644 index 00000000..7d2c2eae --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vpc/show_vpc @@ -0,0 +1,20 @@ +{ + "vpc-domain-id": "not configured", + "vpc-peer-status": "peer-not-configured", + "vpc-peer-status-reason": "SUCCESS", + "vpc-peer-keepalive-status": "disabled", + "vpc-peer-consistency": "inconsistent", + "vpc-peer-consistency-status": "SYSERR_MCECM_MCT_DOES_NOT_EXISTS", + "vpc-per-vlan-peer-consistency": "inconsistent", + "vpc-type-2-consistency": "inconsistent", + "vpc-type-2-consistency-status": "SYSERR_MCECM_MCT_DOES_NOT_EXISTS", + "vpc-role": "none-established", + "num-of-vpcs": "0", + "peer-gateway": "disabled", + "dual-active-excluded-vlans": "-", + "vpc-graceful-consistency-check-status": "enabled", + "vpc-auto-recovery-status": "Enabled (timeout = 240 seconds)", + "operational-l3-peer": "disabled", + "vpc-isolation-status": "disabled-user", + "vpc-check-consist-note": "disabled" +} diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vpc/show_vrf_all b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vpc/show_vrf_all new file mode 100644 index 00000000..838190fb --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vpc/show_vrf_all @@ -0,0 +1,30 @@ +{ + "TABLE_vrf": { + "ROW_vrf": [ + { + "vrf_name": "coke", + "vrf_id": 4, + "vrf_state": "Up", + "vrf_reason": "--" + }, + { + "vrf_name": "default", + "vrf_id": 1, + "vrf_state": "Up", + "vrf_reason": "--" + }, + { + "vrf_name": "management", + "vrf_id": 2, + "vrf_state": "Up", + "vrf_reason": "--" + }, + { + "vrf_name": "test-vrf", + "vrf_id": 3, + "vrf_state": "Up", + "vrf_reason": "--" + } + ] + } +} diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vpc/vrf_test_show_hardware b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vpc/vrf_test_show_hardware new file mode 100644 index 00000000..612a6b3d --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vpc/vrf_test_show_hardware @@ -0,0 +1,3 @@ +{ + "kickstart_ver_str": "7.0(3)I5(3)" +} diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vpc/vrf_test_show_inventory b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vpc/vrf_test_show_inventory new file mode 100644 index 00000000..c1a149dd --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vpc/vrf_test_show_inventory @@ -0,0 +1,13 @@ +{ + "TABLE_inv": { + "ROW_inv": [ + { + "name": "Chassis", + "desc": "Nexus9000 C9504 (4 Slot) Chassis", + "productid": "N9K-C9504", + "vendorid": "V01", + "serialnum": "BR-549" + } + ] + } +} diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vpc/vrf_test_show_vpc b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vpc/vrf_test_show_vpc new file mode 100644 index 00000000..f86daa6b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vpc/vrf_test_show_vpc @@ -0,0 +1,3 @@ +{ + "vpc-domain-id": "100" +} diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vpc/vrf_test_show_vrf_all b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vpc/vrf_test_show_vrf_all new file mode 100644 index 00000000..3f56f8ad --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vpc/vrf_test_show_vrf_all @@ -0,0 +1,36 @@ +{ + "TABLE_vrf": { + "ROW_vrf": [ + { + "vrf_name": "my_vrf", + "vrf_id": 4, + "vrf_state": "Up", + "vrf_reason": "--" + }, + { + "vrf_name": "default", + "vrf_id": 1, + "vrf_state": "Up", + "vrf_reason": "--" + }, + { + "vrf_name": "management", + "vrf_id": 2, + "vrf_state": "Up", + "vrf_reason": "--" + }, + { + "vrf_name": "test-vrf", + "vrf_id": 3, + "vrf_state": "Up", + "vrf_reason": "--" + }, + { + "vrf_name": "obviously-different-vrf", + "vrf_id": 4, + "vrf_state": "Up", + "vrf_reason": "--" + } + ] + } +} diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vpc/vrf_test_vpc_config b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vpc/vrf_test_vpc_config new file mode 100644 index 00000000..e7258296 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vpc/vrf_test_vpc_config @@ -0,0 +1,2 @@ +vpc domain 100 + peer-keepalive destination 192.168.1.1 source 10.1.1.1 vrf my_vrf diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vpc_interface/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vpc_interface/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vpc_interface/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vpc_interface/show_port-channel_summary b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vpc_interface/show_port-channel_summary new file mode 100644 index 00000000..d62bea66 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vpc_interface/show_port-channel_summary @@ -0,0 +1,22 @@ +{ + "TABLE_channel": { + "ROW_channel": [ + { + "group": "10", + "port-channel": "port-channel10", + "layer": "R", + "status": "D", + "type": "Eth", + "prtcl": "NONE" + }, + { + "group": "20", + "port-channel": "port-channel20", + "layer": "R", + "status": "D", + "type": "Eth", + "prtcl": "NONE" + } + ] + } +} diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vpc_interface/show_vpc_brief b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vpc_interface/show_vpc_brief new file mode 100644 index 00000000..2206eca0 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vpc_interface/show_vpc_brief @@ -0,0 +1,14 @@ +{ + "TABLE_vpc": { + "ROW_vpc": [ + { + "vpc-id": 100, + "vpc-ifindex": "Po10", + "vpc-port-state": "Up", + "vpc-thru-peerlink": 19, + "vpc-consistency": "consistent", + "vpc-consistency-status": "SUCCESS" + } + ] + } +} diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vrf/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vrf/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vrf/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vrf/show_run_all b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vrf/show_run_all new file mode 100644 index 00000000..06fe9f91 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vrf/show_run_all @@ -0,0 +1,4 @@ +vrf context coke +vrf context management + ip route 172.26.0.0/16 172.26.4.1 +vrf context test-vrf diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vrf/show_vrf_default b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vrf/show_vrf_default new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vrf/show_vrf_default diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vrf/show_vrf_default_interface b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vrf/show_vrf_default_interface new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vrf/show_vrf_default_interface diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vrf/show_vrf_management b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vrf/show_vrf_management new file mode 100644 index 00000000..a57f7ca2 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vrf/show_vrf_management @@ -0,0 +1,10 @@ +{ + "TABLE_vrf": { + "ROW_vrf": { + "vrf_name": "management", + "vrf_id": 2, + "vrf_state": "Up", + "vrf_reason": "--" + } + } +} diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vrf/show_vrf_management_interface b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vrf/show_vrf_management_interface new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vrf/show_vrf_management_interface diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vrf/show_vrf_ntc b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vrf/show_vrf_ntc new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vrf/show_vrf_ntc diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vrf/show_vrf_ntc_interface b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vrf/show_vrf_ntc_interface new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vrf/show_vrf_ntc_interface diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vrf_af/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vrf_af/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vrf_af/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vrf_af/config.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vrf_af/config.cfg new file mode 100644 index 00000000..c607479a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vrf_af/config.cfg @@ -0,0 +1,22 @@ +vrf context vrf1 + address-family ipv4 unicast + +vrf context vrf11 + address-family ipv4 unicast + route-target both auto evpn + +vrf context vrf21 + address-family ipv4 unicast + route-target import 65000:1000 + route-target import 65001:1000 + route-target import 65002:1000 + route-target export 65000:1000 + route-target export 65001:1000 + route-target export 65002:1000 + +vrf context vrf31 + address-family ipv4 unicast + route-target import 65000:1000 + route-target export 65001:1000 + route-target import 65002:1000 + route-target export 65003:1000 diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vsan/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vsan/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vsan/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vsan/shvsan.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vsan/shvsan.cfg new file mode 100644 index 00000000..67e3f512 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vsan/shvsan.cfg @@ -0,0 +1,33 @@ +vsan 1 information + name:VSAN0001 state:active + interoperability mode:default + loadbalancing:src-id/dst-id/oxid + operational state:up + +vsan 10 information + name:VsanAll state:suspended + interoperability mode:default + loadbalancing:src-id/dst-id/oxid + operational state:down + +vsan 221 information + name:VSAN0221 state:active + interoperability mode:default + loadbalancing:src-id/dst-id/oxid + operational state:up + +vsan 922 information + name:vsan-SAN-A state:active + interoperability mode:default + loadbalancing:src-id/dst-id/oxid + operational state:down + +vsan 923 information + name:vsan-SAN-B state:active + interoperability mode:default + loadbalancing:src-id/dst-id/oxid + operational state:up + +vsan 4079:evfp_isolated_vsan + +vsan 4094:isolated_vsan diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vsan/shvsanmem.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vsan/shvsanmem.cfg new file mode 100644 index 00000000..2a0cffa1 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vsan/shvsanmem.cfg @@ -0,0 +1,28 @@ +vsan 1 interfaces: + fc1/4 fc1/5 fc1/6 fc1/7 + fc1/8 fc1/9 fc1/10 fc1/12 + fc1/13 fc1/14 fc1/15 fc1/16 + fc1/17 fc1/18 fc1/19 fc1/20 + fc1/22 fc1/23 fc1/24 fc1/25 + fc1/26 fc1/27 fc1/28 fc1/29 + fc1/30 fc1/31 fc1/32 fc1/33 + fc1/34 fc1/35 fc1/36 fc1/37 + fc1/38 fc1/39 fc1/40 + +vsan 10 interfaces: + + +vsan 221 interfaces: + + +vsan 922 interfaces: + fc1/1 fc1/2 fc1/3 port-channel55 + +vsan 923 interfaces: + fc1/11 fc1/21 port-channel56 + +vsan 4079(evfp_isolated_vsan) interfaces: + + +vsan 4094(isolated_vsan) interfaces: + port-channel145 diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vxlan_vtep/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vxlan_vtep/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vxlan_vtep/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vxlan_vtep/config.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vxlan_vtep/config.cfg new file mode 100644 index 00000000..acc2da73 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vxlan_vtep/config.cfg @@ -0,0 +1,3 @@ +interface nve1 + member vni 6000 + multisite border-gateway interface loopback1 diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vxlan_vtep_vni/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vxlan_vtep_vni/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vxlan_vtep_vni/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vxlan_vtep_vni/config.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vxlan_vtep_vni/config.cfg new file mode 100644 index 00000000..2532ecf9 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_vxlan_vtep_vni/config.cfg @@ -0,0 +1,3 @@ +interface nve1 + member vni 6000 + multisite ingress-replication optimized diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/show_zone_status_vsan.out b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/show_zone_status_vsan.out new file mode 100644 index 00000000..e5b260d9 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/show_zone_status_vsan.out @@ -0,0 +1,21 @@ +VSAN: 50 default-zone: deny distribute: full Interop: default + mode: basic merge-control: allow + session: none + hard-zoning: enabled broadcast: unsupported + smart-zoning: disabled + rscn-format: fabric-address + activation overwrite control: disabled +Default zone: + qos: none broadcast: unsupported ronly: unsupported +Full Zoning Database : + DB size: 31812 bytes + Zonesets:1 Zones:134 Aliases: 106 +Active Zoning Database : + DB size: 10808 bytes + Name: z50_csphfab1_zoneset Zonesets:1 Zones:134 +Current Total Zone DB Usage: 42620 / 4000000 bytes (1 % used) +Pending (Session) DB size: + Full DB Copy size: n/a + Active DB Copy size: n/a +SFC size: 42620 / 4000000 bytes (1 % used) +Status: Activation completed at 22:19:08 PDT Apr 13 2020 diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/show_zone_vsan.out b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/show_zone_vsan.out new file mode 100644 index 00000000..8be7a71f --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/show_zone_vsan.out @@ -0,0 +1,946 @@ +zone name z50_azusant_f0_unity8174_spa1 vsan 50 + pwwn c0:50:76:09:5b:20:00:64 [azusant_f0] + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + +zone name z50_azplcbsx000652_san01-azsncbsx01_0ac vsan 50 + fcalias name azplcbsx000652_san01 vsan 50 + pwwn 21:00:f4:e9:d4:57:6e:66 [azplcbsx000652_san01] + + fcalias name azsncbsx01_c01_0a vsan 50 + pwwn 20:12:00:a0:98:fa:42:6e [azsncbsx01_c01_0a] + + fcalias name azsncbsx01_c01_0c vsan 50 + pwwn 20:32:00:a0:98:fa:42:6e [azsncbsx01_c01_0c] + + fcalias name azsncbsx01_c02_0a vsan 50 + pwwn 20:13:00:a0:98:fa:42:6e [azsncbsx01_c02_0a] + + fcalias name azsncbsx01_c02_0c vsan 50 + pwwn 20:33:00:a0:98:fa:42:6e [azsncbsx01_c02_0c] + +zone name z50_azplcbsx000653_san01-azsncbsx01_0ac vsan 50 + fcalias name azplcbsx000653_san01 vsan 50 + pwwn 21:00:f4:e9:d4:54:a7:c8 [azplcbsx000653_san01] + + fcalias name azsncbsx01_c01_0a vsan 50 + pwwn 20:12:00:a0:98:fa:42:6e [azsncbsx01_c01_0a] + + fcalias name azsncbsx01_c01_0c vsan 50 + pwwn 20:32:00:a0:98:fa:42:6e [azsncbsx01_c01_0c] + + fcalias name azsncbsx01_c02_0a vsan 50 + pwwn 20:13:00:a0:98:fa:42:6e [azsncbsx01_c02_0a] + + fcalias name azsncbsx01_c02_0c vsan 50 + pwwn 20:33:00:a0:98:fa:42:6e [azsncbsx01_c02_0c] + +zone name z50_azplwebodb01_f0_unity1773_spa3_spb2 vsan 50 + fcalias name azseunty8174_SPA3 vsan 50 + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + + fcalias name azseunty8174_SPB2 vsan 50 + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + fcalias name azplwebdb01_f0 vsan 50 + pwwn 21:00:00:24:ff:0c:58:37 [azplwebodb01_f0] + +zone name z50_azpwvnasql1_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpwvnasql1_f0 vsan 50 + pwwn 21:00:00:24:ff:0d:26:68 [azpwvnasql1_f0] + +zone name z50_azplcbsx000652_san01-azsncbsx02_0ac vsan 50 + fcalias name azplcbsx000652_san01 vsan 50 + pwwn 21:00:f4:e9:d4:57:6e:66 [azplcbsx000652_san01] + + fcalias name azsncbsx02_c01_0a vsan 50 + pwwn 20:12:00:a0:98:42:fa:8c + + fcalias name azsncbsx02_c01_0c vsan 50 + pwwn 20:32:00:a0:98:fa:42:8c [azsncbsx02_c01_0c] + + fcalias name azsncbsx02_c02_0a vsan 50 + pwwn 20:13:00:a0:98:fa:42:8c [azsncbsx02_c02_0a] + + fcalias name azsncbsx02_c02_0c vsan 50 + pwwn 20:33:00:a0:98:fa:42:8c [azsncbsx02_c02_0c] + +zone name z50_azplcbsx000653_san01-azsncbsx02_0ac vsan 50 + fcalias name azplcbsx000653_san01 vsan 50 + pwwn 21:00:f4:e9:d4:54:a7:c8 [azplcbsx000653_san01] + + fcalias name azsncbsx02_c01_0a vsan 50 + pwwn 20:12:00:a0:98:42:fa:8c + + fcalias name azsncbsx02_c01_0c vsan 50 + pwwn 20:32:00:a0:98:fa:42:8c [azsncbsx02_c01_0c] + + fcalias name azsncbsx02_c02_0a vsan 50 + pwwn 20:13:00:a0:98:fa:42:8c [azsncbsx02_c02_0a] + + fcalias name azsncbsx02_c02_0c vsan 50 + pwwn 20:33:00:a0:98:fa:42:8c [azsncbsx02_c02_0c] + +zone name z50_azpwovd01_A001_8174_spa_iom_1_fc1 vsan 50 + pwwn 20:ff:00:25:b5:a2:a0:01 [azpwovd01_f0] + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + +zone name z50_azplocat02_f0_unity8174_spa3_spb2 vsan 50 + fcalias name azseunty8174_SPA3 vsan 50 + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + + fcalias name azseunty8174_SPB2 vsan 50 + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + fcalias name azplocat02_f0 vsan 50 + pwwn 21:00:00:24:ff:01:18:5f [azplocat02_f0] + +zone name z50_azpe123_A03B_8174_spa_iom_1_fc1 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:3b [azpe123_f0] + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + +zone name z50_azpe001_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpe001_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:1d [azpe001_f0] + +zone name z50_azpe123_A03B_8174_spb_iom_1_fc2 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:3b [azpe123_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + +zone name z50_azuqaunx_f1_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azuqaunx_01_f0 vsan 50 + pwwn c0:50:76:09:5b:20:00:0e [azuqaunx-01_f0] + pwwn c0:50:76:09:5b:20:00:0f + +zone name z50_azplcbsx000309_san01-azsncbsx01_0ac vsan 50 + fcalias name azsncbsx01_c01_0a vsan 50 + pwwn 20:12:00:a0:98:fa:42:6e [azsncbsx01_c01_0a] + + fcalias name azsncbsx01_c01_0c vsan 50 + pwwn 20:32:00:a0:98:fa:42:6e [azsncbsx01_c01_0c] + + fcalias name azsncbsx01_c02_0a vsan 50 + pwwn 20:13:00:a0:98:fa:42:6e [azsncbsx01_c02_0a] + + fcalias name azsncbsx01_c02_0c vsan 50 + pwwn 20:33:00:a0:98:fa:42:6e [azsncbsx01_c02_0c] + + fcalias name azplcbsx000309_san01 vsan 50 + pwwn 21:00:f4:e9:d4:55:f3:e6 [azplcbsx000309_san01] + +zone name z50_azpe002_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpe002_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:1e [azpe002_f0] + +zone name z50_azpe122_A03A_8174_spb_iom_1_fc0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:3a [azpe122_f0] + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + +zone name z50_azpe122_A03A_8174_spa_iom_1_fc3 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:3a [azpe122_f0] + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + +zone name z50_azulaba_f0_unity8174_spa1 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azulaba_f0 vsan 50 + pwwn c0:50:76:09:5b:20:00:30 + pwwn c0:50:76:09:5b:20:00:31 + +zone name z50_azulaba_f2_unity8174_spb0 vsan 50 + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azulaba_f2 vsan 50 + pwwn c0:50:76:09:5b:20:00:34 [azulaba_f2] + pwwn c0:50:76:09:5b:20:00:35 + +zone name z50_azlonbasep1_f0_unity8174_spa3_spb2 vsan 50 + fcalias name azseunty8174_SPA3 vsan 50 + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + + fcalias name azseunty8174_SPB2 vsan 50 + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + fcalias name azlonbasep1_f0 vsan 50 + pwwn 21:00:00:24:ff:01:78:b0 [azlonbasep1_f0] + +zone name z50_azplcbsx000309_san01-azsncbsx02_0ac vsan 50 + fcalias name azsncbsx02_c01_0a vsan 50 + pwwn 20:12:00:a0:98:42:fa:8c + + fcalias name azsncbsx02_c01_0c vsan 50 + pwwn 20:32:00:a0:98:fa:42:8c [azsncbsx02_c01_0c] + + fcalias name azsncbsx02_c02_0a vsan 50 + pwwn 20:13:00:a0:98:fa:42:8c [azsncbsx02_c02_0a] + + fcalias name azsncbsx02_c02_0c vsan 50 + pwwn 20:33:00:a0:98:fa:42:8c [azsncbsx02_c02_0c] + + fcalias name azplcbsx000309_san01 vsan 50 + pwwn 21:00:f4:e9:d4:55:f3:e6 [azplcbsx000309_san01] + +zone name z50_azplcslrpa1_f0_unity1773 vsan 50 + fcalias name azseunty8174_SPA3 vsan 50 + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + + fcalias name azseunty8174_SPB2 vsan 50 + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azplcslrpa1-1_f0 vsan 50 + pwwn 50:01:24:80:0b:50:46:03 [azplcslrpa1-1_f0] + + fcalias name azplcslrpa1-2_f0 vsan 50 + pwwn 50:01:24:80:00:a0:46:03 [azplcslrpa1-2_f0] + + fcalias name azplcslrpa1-4_f0 vsan 50 + pwwn 50:01:24:80:09:c0:66:03 [azplcslrpa1-4_f0] + + fcalias name azplcslrpa1-3_f0 vsan 50 + pwwn 50:01:24:80:0f:d0:46:03 [azplcslrpa1-3_f0] + +zone name z50_azpe120_A038_8174_spa_iom_1_fc1 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:38 [azpe120_f0] + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + +zone name z50_azpe120_A038_8174_spb_iom_1_fc2 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:38 [azpe120_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + +zone name z50_azpe121_A039_8174_spb_iom_1_fc0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:39 [azpe121_f0] + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + +zone name z50_azplcbsx000310_san01-azsncbsx01_0ac vsan 50 + fcalias name azsncbsx01_c01_0a vsan 50 + pwwn 20:12:00:a0:98:fa:42:6e [azsncbsx01_c01_0a] + + fcalias name azsncbsx01_c01_0c vsan 50 + pwwn 20:32:00:a0:98:fa:42:6e [azsncbsx01_c01_0c] + + fcalias name azsncbsx01_c02_0a vsan 50 + pwwn 20:13:00:a0:98:fa:42:6e [azsncbsx01_c02_0a] + + fcalias name azsncbsx01_c02_0c vsan 50 + pwwn 20:33:00:a0:98:fa:42:6e [azsncbsx01_c02_0c] + + fcalias name azplcbsx000310_san01 vsan 50 + pwwn 21:00:f4:e9:d4:55:f4:4a [azplcbsx000310_san01] + +zone name z50_azplcbsx000310_san01-azsncbsx02_0ac vsan 50 + fcalias name azsncbsx02_c01_0a vsan 50 + pwwn 20:12:00:a0:98:42:fa:8c + + fcalias name azsncbsx02_c01_0c vsan 50 + pwwn 20:32:00:a0:98:fa:42:8c [azsncbsx02_c01_0c] + + fcalias name azsncbsx02_c02_0a vsan 50 + pwwn 20:13:00:a0:98:fa:42:8c [azsncbsx02_c02_0a] + + fcalias name azsncbsx02_c02_0c vsan 50 + pwwn 20:33:00:a0:98:fa:42:8c [azsncbsx02_c02_0c] + + fcalias name azplcbsx000310_san01 vsan 50 + pwwn 21:00:f4:e9:d4:55:f4:4a [azplcbsx000310_san01] + +zone name z50_azpe121_A039_8174_spa_iom_1_fc3 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:39 [azpe121_f0] + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + +zone name z50_azpesxctx48_A036_8174_spa_iom_1_fc1 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:36 [azpesxctx48_f0] + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + +zone name z50_azpesxctx48_A036_8174_spb_iom_1_fc2 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:36 [azpesxctx48_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + +zone name z50_azpesxctx50_A033_8174_spa_iom_1_fc1 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:33 [azpesxctx50_f0] + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + +zone name z50_azuqaunx_f0_unity8174_spa1 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + +zone name z50_azuqaunx_f2_unity8174_spb0 vsan 50 + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + +zone name z50_azpesxctx50_A033_8174_spb_iom_1_fc2 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:33 [azpesxctx50_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + +zone name z50_azpesxctx46_A034_8174_spb_iom_1_fc0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:34 [azpesxctx46_f0] + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + +zone name z50_azpesxctx46_A034_8174_spa_iom_1_fc3 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:34 [azpesxctx46_f0] + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + +zone name z50_azpesxctx47_A035_8174_spa_iom_1_fc1 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:35 [azpesxctx47_f0] + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + +zone name z50_azplepicbu01_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azplepicbu01_f0 vsan 50 + pwwn 20:ff:00:25:b5:a3:a0:02 [azplepicbu01_f0] + +zone name z50_azxe01p_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azxe01p_f0 vsan 50 + pwwn 21:00:00:24:ff:03:0f:ae [azxe01p_f0] + +zone name z50_azxe02p_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azxe02p_f0 vsan 50 + pwwn 21:00:00:24:ff:03:10:69 [azxe02p_f0] + +zone name z50_azpesxclin01_f0_unity8174_spa3_spb2 vsan 50 + fcalias name azseunty8174_SPA3 vsan 50 + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + + fcalias name azseunty8174_SPB2 vsan 50 + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + fcalias name azpesxclin01_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:02 [azpesxclin01_f0] + +zone name z50_azpesxclin02_f0_unity8174_spa3_spb2 vsan 50 + fcalias name azseunty8174_SPA3 vsan 50 + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + + fcalias name azseunty8174_SPB2 vsan 50 + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + fcalias name azpesxclin02_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:03 [azpesxclin02_f0] + +zone name z50_azpesxclin03_f0_unity8174_spa3_spb2 vsan 50 + fcalias name azseunty8174_SPA3 vsan 50 + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + + fcalias name azseunty8174_SPB2 vsan 50 + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + fcalias name azpesxclin03_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:01 [azpesxclin03_f0] + +zone name z50_azpesxctx01_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx01_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:04 [azpesxctx01_f0] + +zone name z50_azpesxctx02_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx02_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:05 [azpesxctx02_f0] + +zone name z50_azpesxctx03_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx03_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:06 [azpesxctx03_f0] + +zone name z50_azpesxctx04_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx04_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:07 [azpesxctx04_f0] + +zone name z50_azpesxctx05_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx05_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:08 [azpesxctx05_f0] + +zone name z50_azpesxctx06_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx06_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:09 [azpesxctx06_f0] + +zone name z50_azpesxctx07_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx07_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:0a [azpesxctx07_f0] + +zone name z50_azpesxctx08_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx08_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:0b [azpesxctx08_f0] + +zone name z50_azpesxctx09_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx09_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:0c [azpesxctx09_f0] + +zone name z50_azpesxctx10_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx10_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:0d [azpesxctx10_f0] + +zone name z50_azpesxctx11_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx11_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:0e [azpesxctx11_f0] + +zone name z50_azpesxctx12_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx12_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:0f [azpesxctx12_f0] + +zone name z50_azpesxctx13_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx13_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:10 [azpesxctx13_f0] + +zone name z50_azpesxctx14_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx14_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:11 [azpesxctx14_f0] + +zone name z50_azpesxctx15_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx15_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:12 [azpesxctx15_f0] + +zone name z50_azpesxctx16_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx16_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:13 [azpesxctx16_f0] + +zone name z50_azpesxctx17_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx17_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:14 [azpesxctx17_f0] + +zone name z50_azpesxctx18_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx18_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:15 [azpesxctx18_f0] + +zone name z50_azpesxctx19_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx19_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:16 [azpesxctx19_f0] + +zone name z50_azpesxctx20_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx20_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:17 [azpesxctx20_f0] + +zone name z50_azpesxctx21_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx21_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:18 [azpesxctx21_f0] + +zone name z50_azpesxctx22_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx22_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:19 [azpesxctx22_f0] + +zone name z50_azpesxctx23_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx23_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:1b [azpesxctx23_f0] + +zone name z50_azpesxctx24_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx24_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:1a [azpesxctx24_f0] + +zone name z50_azpesxctx25_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx25_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:1c [azpesxctx25_f0] + +zone name z50_azpesxpci01-x_f0_unity8174_spa3_spb2 vsan 50 + fcalias name azseunty8174_SPA3 vsan 50 + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + + fcalias name azseunty8174_SPB2 vsan 50 + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + fcalias name azpesxpci01-x_f0 vsan 50 + pwwn 21:00:00:24:ff:10:02:00 [azpesxpci01-x_f0] + +zone name z50_azxe01p_0FAE_8174_spb_iom_1_fc2 vsan 50 + pwwn 21:00:00:24:ff:03:0f:ae [azxe01p_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + +zone name z50_azxe02p_1069_8174_spb_iom_1_fc2 vsan 50 + pwwn 21:00:00:24:ff:03:10:69 [azxe02p_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + +zone name z50_azpe001_A01D_8174_spa_iom_1_fc3 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:1d [azpe001_f0] + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + +zone name z50_azpe002_A01E_8174_spb_iom_1_fc2 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:1e [azpe002_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + +zone name z50_azpesxctx47_A035_8174_spb_iom_1_fc2 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:35 [azpesxctx47_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + +zone name z50_azpesxctx49_A037_8174_spb_iom_1_fc0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:37 [azpesxctx49_f0] + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + +zone name z50_azpesxctx49_A037_8174_spa_iom_1_fc3 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:37 [azpesxctx49_f0] + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + +zone name z50_azpesxctx26_A027_8174_spa_iom_1_fc1 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:27 [azpesxctx26_f0] + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + +zone name z50_azpesxctx26_A027_8174_spb_iom_1_fc2 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:27 [azpesxctx26_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + +zone name z50_azpesxctx28_A02B_8174_spb_iom_1_fc0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:2b [azpesxctx28_f0] + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + +zone name z50_azpesxctx28_A02B_8174_spa_iom_1_fc3 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:2b [azpesxctx28_f0] + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + +zone name z50_azpesxctx31_A021_8174_spa_iom_1_fc1 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:21 [azpesxctx31_f0] + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + +zone name z50_azpesxctx31_A021_8174_spb_iom_1_fc2 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:21 [azpesxctx31_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + +zone name z50_azpesxctx32_A023_8174_spb_iom_1_fc0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:23 [azpesxctx32_f0] + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + +zone name z50_azpesxctx32_A023_8174_spa_iom_1_fc3 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:23 [azpesxctx32_f0] + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + +zone name z50_azpesxctx29_A02D_8174_spa_iom_1_fc1 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:2d [azpesxctx29_f0] + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + +zone name z50_azpesxctx29_A02D_8174_spb_iom_1_fc2 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:2d [azpesxctx29_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + +zone name z50_azpesxctx33_A024_8174_spb_iom_1_fc0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:24 [azpesxctx33_f0] + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + +zone name z50_azpesxctx33_A024_8174_spa_iom_1_fc3 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:24 [azpesxctx33_f0] + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + +zone name z50_azpesxctx30_A01F_8174_spa_iom_1_fc1 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:1f [azpesxctx30_f0] + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + +zone name z50_azpesxctx30_A01F_8174_spb_iom_1_fc2 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:1f [azpesxctx30_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + +zone name z50_azpesxctx27_A029_8174_spb_iom_1_fc0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:29 [azpesxctx27_f0] + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + +zone name z50_azpesxctx27_A029_8174_spa_iom_1_fc3 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:29 [azpesxctx27_f0] + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + +zone name z50_azpesxctx35_A026_8174_spa_iom_1_fc1 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:26 [azpesxctx35_f0] + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + +zone name z50_azpesxctx35_A026_8174_spb_iom_1_fc2 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:26 [azpesxctx35_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + +zone name z50_azpesxctx37_A02A_8174_spb_iom_1_fc0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:2a [azpesxctx37_f0] + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + +zone name z50_azpesxctx37_A02A_8174_spa_iom_1_fc3 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:2a [azpesxctx37_f0] + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + +zone name z50_azpesxctx38_A02C_8174_spa_iom_1_fc1 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:2c [azpesxctx38_f0] + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + +zone name z50_azpesxctx38_A02C_8174_spb_iom_1_fc2 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:2c [azpesxctx38_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + +zone name z50_azpesxctx40_A020_8174_spb_iom_1_fc0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:20 [azpesxctx40_f0] + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + +zone name z50_azpesxctx40_A020_8174_spa_iom_1_fc3 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:20 [azpesxctx40_f0] + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + +zone name z50_azpesxctx34_A025_8174_spa_iom_1_fc1 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:25 [azpesxctx34_f0] + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + +zone name z50_azpesxctx34_A025_8174_spb_iom_1_fc2 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:25 [azpesxctx34_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + +zone name z50_azpesxctx41_A022_8174_spb_iom_1_fc0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:22 [azpesxctx41_f0] + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + +zone name z50_azpesxctx41_A022_8174_spa_iom_1_fc3 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:22 [azpesxctx41_f0] + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + +zone name z50_azpesxctx42_A02F_8174_spa_iom_1_fc1 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:2f [azpesxctx42_f0] + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + +zone name z50_azpesxctx42_A02F_8174_spb_iom_1_fc2 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:2f [azpesxctx42_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + +zone name z50_azpesxctx36_A028_8174_spb_iom_1_fc0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:28 [azpesxctx36_f0] + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + +zone name z50_azpesxctx36_A028_8174_spa_iom_1_fc3 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:28 [azpesxctx36_f0] + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + +zone name z50_azpesxctx43_A030_8174_spa_iom_1_fc1 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:30 [azpesxctx43_f0] + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + +zone name z50_azpesxctx43_A030_8174_spb_iom_1_fc2 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:30 [azpesxctx43_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + +zone name z50_azpesxctx44_A031_8174_spb_iom_1_fc0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:31 [azpesxctx44_f0] + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + +zone name z50_azpesxctx44_A031_8174_spa_iom_1_fc3 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:31 [azpesxctx44_f0] + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + +zone name z50_azpesxctx45_A032_8174_spa_iom_1_fc1 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:32 [azpesxctx45_f0] + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + +zone name z50_azpesxctx45_A032_8174_spb_iom_1_fc2 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:32 [azpesxctx45_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + +zone name z50_azpesxctx39_A02E_8174_spb_iom_1_fc0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:2e [azpesxctx39_f0] + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + +zone name z50_azpesxctx39_A02E_8174_spa_iom_1_fc3 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:2e [azpesxctx39_f0] + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + +zone name z50_azunim1_f0_unity8714_spa1 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azunim1_f0 vsan 50 + pwwn c0:50:76:09:5b:20:00:10 [azunim1_f0] + +zone name z50_azunim1_f2_unity8714_spb0 vsan 50 + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azunim1_f2 vsan 50 + pwwn c0:50:76:09:5b:20:00:14 [azunim1_f2] + +zone name z50_azusant_f2_unity8174_spb0 vsan 50 + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azusant_f2 vsan 50 + pwwn c0:50:76:09:5b:20:00:60 [azusant_f2] + +zone name z50_azucdrdb1_f0_unity8174_spa1 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azucdrdb1_f0 vsan 50 + pwwn c0:50:76:09:5b:20:00:3a [azucdrdb1_f0] + +zone name z50_azucdrdb1_f2_unity8174_spb0 vsan 50 + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azucdrdb1_f2 vsan 50 + pwwn c0:50:76:09:5b:20:00:3e [azucdrdb1_f2] + +zone name z50_azpups01_f0_unity8174_spa1 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azupsp1_f0 vsan 50 + pwwn c0:50:76:09:5b:20:00:1a [azupsp1_f0] + +zone name z50_azupsdbp1_f0_unity8174_spa1 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azupsdbp1_f0 vsan 50 + pwwn c0:50:76:09:5b:20:00:20 [azupsdbp1_f0] + +zone name z50_azupsdbp1_f2_unity8174_spb0 vsan 50 + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azupsdbp1_f2 vsan 50 + pwwn c0:50:76:09:5b:20:00:24 [azupsdbp1_f2] + +zone name z50_azucdrsr1_f0_unity1773_spa3 vsan 50 + fcalias name azseunty8174_SPA3 vsan 50 + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + + fcalias name azucdrsr1_f0 vsan 50 + pwwn c0:50:76:09:5b:20:00:44 [azucdrsr1_f0] + +zone name z50_azudbas1_f0_unity8174_spa1 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azudbas1_f0 vsan 50 + pwwn c0:50:76:09:5b:20:00:4a [azudbas1_f0] + +zone name z50_azudbas1_f2_unity8174_spb0 vsan 50 + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azudbas1_f2 vsan 50 + pwwn c0:50:76:09:5b:20:00:4e [azudbas1_f2] + +zone name z50_azukronp1_f0_unity8174_spa1 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azukronp1_f0 vsan 50 + pwwn c0:50:76:09:5b:20:00:2a [azukronp1_f0] + +zone name z50_azukronp1_f00_unity8174_spb0 vsan 50 + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azukronp1_f00 vsan 50 + pwwn c0:50:76:09:5b:20:00:2e [azukronp1_f00] + +zone name z50_azpups01_f2_unity8174_spb0 vsan 50 + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azupsp1_f2 vsan 50 + pwwn c0:50:76:09:5b:20:00:1e [azupsp1_f2] + +zone name z50_azucdrsr1_f2_unity1773_spb2 vsan 50 + fcalias name azseunty8174_SPB2 vsan 50 + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + fcalias name azucdrsr1_f2 vsan 50 + pwwn c0:50:76:09:5b:20:00:40 [azucdrsr1_f2] + +zone name z50_azuepicclarp1_f0_unity8174_spa3 vsan 50 + fcalias name azseunty8174_SPA3 vsan 50 + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + + fcalias name azuepicclarp1_f0 vsan 50 + pwwn c0:50:76:09:5b:20:00:50 [azuepicclarp1_f0] + +zone name z50_azuepicclarp1_f2_unity8174_spb2 vsan 50 + fcalias name azseunty8174_SPB2 vsan 50 + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + fcalias name azuepicclarp1_f2 vsan 50 + pwwn c0:50:76:09:5b:20:00:54 [azuepicclarp1_f2] + +zone name z50_azpwovd01_A001_8174_spb_iom_1_fc2 vsan 50 + pwwn 20:ff:00:25:b5:a2:a0:01 [azpwovd01_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/show_zoneset_active_vsan.out b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/show_zoneset_active_vsan.out new file mode 100644 index 00000000..4f65ee5f --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/show_zoneset_active_vsan.out @@ -0,0 +1,606 @@ +zoneset name z50_csphfab1_zoneset vsan 50 + zone name z50_azusant_f0_unity8174_spa1 vsan 50 + * fcid 0x3211cb [pwwn c0:50:76:09:5b:20:00:64] [azusant_f0] + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + + zone name z50_azplcbsx000652_san01-azsncbsx01_0ac vsan 50 + * fcid 0x321240 [pwwn 21:00:f4:e9:d4:57:6e:66] [azplcbsx000652_san01] + * fcid 0x321101 [pwwn 20:12:00:a0:98:fa:42:6e] [azsncbsx01_c01_0a] + * fcid 0x321100 [pwwn 20:32:00:a0:98:fa:42:6e] [azsncbsx01_c01_0c] + * fcid 0x321141 [pwwn 20:13:00:a0:98:fa:42:6e] [azsncbsx01_c02_0a] + * fcid 0x321140 [pwwn 20:33:00:a0:98:fa:42:6e] [azsncbsx01_c02_0c] + + zone name z50_azplcbsx000653_san01-azsncbsx01_0ac vsan 50 + * fcid 0x321260 [pwwn 21:00:f4:e9:d4:54:a7:c8] [azplcbsx000653_san01] + * fcid 0x321101 [pwwn 20:12:00:a0:98:fa:42:6e] [azsncbsx01_c01_0a] + * fcid 0x321100 [pwwn 20:32:00:a0:98:fa:42:6e] [azsncbsx01_c01_0c] + * fcid 0x321141 [pwwn 20:13:00:a0:98:fa:42:6e] [azsncbsx01_c02_0a] + * fcid 0x321140 [pwwn 20:33:00:a0:98:fa:42:6e] [azsncbsx01_c02_0c] + + zone name z50_azplwebodb01_f0_unity1773_spa3_spb2 vsan 50 + * fcid 0x320fc0 [pwwn 50:06:01:63:47:e4:22:97] [azseunty1773_SPA3] + * fcid 0x321020 [pwwn 50:06:01:6a:47:e4:22:97] [azseunty1773_SPB2] + * fcid 0x320120 [pwwn 21:00:00:24:ff:0c:58:37] [azplwebodb01_f0] + + zone name z50_azpwvnasql1_f0_unity8174_spa1_spb0 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x320b60 [pwwn 21:00:00:24:ff:0d:26:68] [azpwvnasql1_f0] + + zone name z50_azplcbsx000652_san01-azsncbsx02_0ac vsan 50 + * fcid 0x321240 [pwwn 21:00:f4:e9:d4:57:6e:66] [azplcbsx000652_san01] + pwwn 20:12:00:a0:98:42:fa:8c + * fcid 0x321040 [pwwn 20:32:00:a0:98:fa:42:8c] [azsncbsx02_c01_0c] + * fcid 0x3210a1 [pwwn 20:13:00:a0:98:fa:42:8c] [azsncbsx02_c02_0a] + * fcid 0x3210a0 [pwwn 20:33:00:a0:98:fa:42:8c] [azsncbsx02_c02_0c] + + zone name z50_azplcbsx000653_san01-azsncbsx02_0ac vsan 50 + * fcid 0x321260 [pwwn 21:00:f4:e9:d4:54:a7:c8] [azplcbsx000653_san01] + pwwn 20:12:00:a0:98:42:fa:8c + * fcid 0x321040 [pwwn 20:32:00:a0:98:fa:42:8c] [azsncbsx02_c01_0c] + * fcid 0x3210a1 [pwwn 20:13:00:a0:98:fa:42:8c] [azsncbsx02_c02_0a] + * fcid 0x3210a0 [pwwn 20:33:00:a0:98:fa:42:8c] [azsncbsx02_c02_0c] + + zone name z50_azpwovd01_A001_8174_spa_iom_1_fc1 vsan 50 + * fcid 0x320f5d [pwwn 20:ff:00:25:b5:a2:a0:01] [azpwovd01_f0] + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + + zone name z50_azplocat02_f0_unity8174_spa3_spb2 vsan 50 + * fcid 0x320fc0 [pwwn 50:06:01:63:47:e4:22:97] [azseunty1773_SPA3] + * fcid 0x321020 [pwwn 50:06:01:6a:47:e4:22:97] [azseunty1773_SPB2] + * fcid 0x320017 [pwwn 21:00:00:24:ff:01:18:5f] [azplocat02_f0] + + zone name z50_azpe123_A03B_8174_spa_iom_1_fc1 vsan 50 + * fcid 0x320f9f [pwwn 20:ff:00:25:b5:a1:a0:3b] [azpe123_f0] + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + + zone name z50_azpe001_f0_unity8174_spa1_spb0 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x320f5e [pwwn 20:ff:00:25:b5:a1:a0:1d] [azpe001_f0] + + zone name z50_azpe123_A03B_8174_spb_iom_1_fc2 vsan 50 + * fcid 0x320f9f [pwwn 20:ff:00:25:b5:a1:a0:3b] [azpe123_f0] + * fcid 0x321020 [pwwn 50:06:01:6a:47:e4:22:97] [azseunty1773_SPB2] + + zone name z50_azuqaunx_f1_f0_unity8174_spa1_spb0 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x3211a1 [pwwn c0:50:76:09:5b:20:00:0e] [azuqaunx-01_f0] + pwwn c0:50:76:09:5b:20:00:0f + + zone name z50_azplcbsx000309_san01-azsncbsx01_0ac vsan 50 + * fcid 0x321101 [pwwn 20:12:00:a0:98:fa:42:6e] [azsncbsx01_c01_0a] + * fcid 0x321100 [pwwn 20:32:00:a0:98:fa:42:6e] [azsncbsx01_c01_0c] + * fcid 0x321141 [pwwn 20:13:00:a0:98:fa:42:6e] [azsncbsx01_c02_0a] + * fcid 0x321140 [pwwn 20:33:00:a0:98:fa:42:6e] [azsncbsx01_c02_0c] + * fcid 0x321160 [pwwn 21:00:f4:e9:d4:55:f3:e6] [azplcbsx000309_san01] + + zone name z50_azpe002_f0_unity8174_spa1_spb0 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x320f5f [pwwn 20:ff:00:25:b5:a1:a0:1e] [azpe002_f0] + + zone name z50_azpe122_A03A_8174_spb_iom_1_fc0 vsan 50 + * fcid 0x320f9e [pwwn 20:ff:00:25:b5:a1:a0:3a] [azpe122_f0] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + + zone name z50_azpe122_A03A_8174_spa_iom_1_fc3 vsan 50 + * fcid 0x320f9e [pwwn 20:ff:00:25:b5:a1:a0:3a] [azpe122_f0] + * fcid 0x320fc0 [pwwn 50:06:01:63:47:e4:22:97] [azseunty1773_SPA3] + + zone name z50_azulaba_f0_unity8174_spa1 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x3211c5 [pwwn c0:50:76:09:5b:20:00:30] + pwwn c0:50:76:09:5b:20:00:31 + + zone name z50_azulaba_f2_unity8174_spb0 vsan 50 + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x321205 [pwwn c0:50:76:09:5b:20:00:34] [azulaba_f2] + pwwn c0:50:76:09:5b:20:00:35 + + zone name z50_azlonbasep1_f0_unity8174_spa3_spb2 vsan 50 + * fcid 0x320fc0 [pwwn 50:06:01:63:47:e4:22:97] [azseunty1773_SPA3] + * fcid 0x321020 [pwwn 50:06:01:6a:47:e4:22:97] [azseunty1773_SPB2] + * fcid 0x320018 [pwwn 21:00:00:24:ff:01:78:b0] [azlonbasep1_f0] + + zone name z50_azplcbsx000309_san01-azsncbsx02_0ac vsan 50 + pwwn 20:12:00:a0:98:42:fa:8c + * fcid 0x321040 [pwwn 20:32:00:a0:98:fa:42:8c] [azsncbsx02_c01_0c] + * fcid 0x3210a1 [pwwn 20:13:00:a0:98:fa:42:8c] [azsncbsx02_c02_0a] + * fcid 0x3210a0 [pwwn 20:33:00:a0:98:fa:42:8c] [azsncbsx02_c02_0c] + * fcid 0x321160 [pwwn 21:00:f4:e9:d4:55:f3:e6] [azplcbsx000309_san01] + + zone name z50_azplcslrpa1_f0_unity1773 vsan 50 + * fcid 0x320fc0 [pwwn 50:06:01:63:47:e4:22:97] [azseunty1773_SPA3] + * fcid 0x321020 [pwwn 50:06:01:6a:47:e4:22:97] [azseunty1773_SPB2] + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x320e20 [pwwn 50:01:24:80:0b:50:46:03] [azplcslrpa1-1_f0] + * fcid 0x320e60 [pwwn 50:01:24:80:00:a0:46:03] [azplcslrpa1-2_f0] + * fcid 0x320e40 [pwwn 50:01:24:80:09:c0:66:03] [azplcslrpa1-4_f0] + * fcid 0x320e80 [pwwn 50:01:24:80:0f:d0:46:03] [azplcslrpa1-3_f0] + + zone name z50_azpe120_A038_8174_spa_iom_1_fc1 vsan 50 + * fcid 0x320f9c [pwwn 20:ff:00:25:b5:a1:a0:38] [azpe120_f0] + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + + zone name z50_azpe120_A038_8174_spb_iom_1_fc2 vsan 50 + * fcid 0x320f9c [pwwn 20:ff:00:25:b5:a1:a0:38] [azpe120_f0] + * fcid 0x321020 [pwwn 50:06:01:6a:47:e4:22:97] [azseunty1773_SPB2] + + zone name z50_azpe121_A039_8174_spb_iom_1_fc0 vsan 50 + * fcid 0x320f9d [pwwn 20:ff:00:25:b5:a1:a0:39] [azpe121_f0] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + + zone name z50_azplcbsx000310_san01-azsncbsx01_0ac vsan 50 + * fcid 0x321101 [pwwn 20:12:00:a0:98:fa:42:6e] [azsncbsx01_c01_0a] + * fcid 0x321100 [pwwn 20:32:00:a0:98:fa:42:6e] [azsncbsx01_c01_0c] + * fcid 0x321141 [pwwn 20:13:00:a0:98:fa:42:6e] [azsncbsx01_c02_0a] + * fcid 0x321140 [pwwn 20:33:00:a0:98:fa:42:6e] [azsncbsx01_c02_0c] + * fcid 0x321180 [pwwn 21:00:f4:e9:d4:55:f4:4a] [azplcbsx000310_san01] + + zone name z50_azplcbsx000310_san01-azsncbsx02_0ac vsan 50 + pwwn 20:12:00:a0:98:42:fa:8c + * fcid 0x321040 [pwwn 20:32:00:a0:98:fa:42:8c] [azsncbsx02_c01_0c] + * fcid 0x3210a1 [pwwn 20:13:00:a0:98:fa:42:8c] [azsncbsx02_c02_0a] + * fcid 0x3210a0 [pwwn 20:33:00:a0:98:fa:42:8c] [azsncbsx02_c02_0c] + * fcid 0x321180 [pwwn 21:00:f4:e9:d4:55:f4:4a] [azplcbsx000310_san01] + + zone name z50_azpe121_A039_8174_spa_iom_1_fc3 vsan 50 + * fcid 0x320f9d [pwwn 20:ff:00:25:b5:a1:a0:39] [azpe121_f0] + * fcid 0x320fc0 [pwwn 50:06:01:63:47:e4:22:97] [azseunty1773_SPA3] + + zone name z50_azpesxctx48_A036_8174_spa_iom_1_fc1 vsan 50 + * fcid 0x320f99 [pwwn 20:ff:00:25:b5:a1:a0:36] [azpesxctx48_f0] + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + + zone name z50_azpesxctx48_A036_8174_spb_iom_1_fc2 vsan 50 + * fcid 0x320f99 [pwwn 20:ff:00:25:b5:a1:a0:36] [azpesxctx48_f0] + * fcid 0x321020 [pwwn 50:06:01:6a:47:e4:22:97] [azseunty1773_SPB2] + + zone name z50_azpesxctx50_A033_8174_spa_iom_1_fc1 vsan 50 + * fcid 0x320f9b [pwwn 20:ff:00:25:b5:a1:a0:33] [azpesxctx50_f0] + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + + zone name z50_azuqaunx_f0_unity8174_spa1 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + + zone name z50_azuqaunx_f2_unity8174_spb0 vsan 50 + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + + zone name z50_azpesxctx50_A033_8174_spb_iom_1_fc2 vsan 50 + * fcid 0x320f9b [pwwn 20:ff:00:25:b5:a1:a0:33] [azpesxctx50_f0] + * fcid 0x321020 [pwwn 50:06:01:6a:47:e4:22:97] [azseunty1773_SPB2] + + zone name z50_azpesxctx46_A034_8174_spb_iom_1_fc0 vsan 50 + * fcid 0x320f97 [pwwn 20:ff:00:25:b5:a1:a0:34] [azpesxctx46_f0] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + + zone name z50_azpesxctx46_A034_8174_spa_iom_1_fc3 vsan 50 + * fcid 0x320f97 [pwwn 20:ff:00:25:b5:a1:a0:34] [azpesxctx46_f0] + * fcid 0x320fc0 [pwwn 50:06:01:63:47:e4:22:97] [azseunty1773_SPA3] + + zone name z50_azpesxctx47_A035_8174_spa_iom_1_fc1 vsan 50 + * fcid 0x320f98 [pwwn 20:ff:00:25:b5:a1:a0:35] [azpesxctx47_f0] + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + + zone name z50_azplepicbu01_f0_unity8174_spa1_spb0 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x320f82 [pwwn 20:ff:00:25:b5:a3:a0:02] [azplepicbu01_f0] + + zone name z50_azxe01p_f0_unity8174_spa1_spb0 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x320ca0 [pwwn 21:00:00:24:ff:03:0f:ae] [azxe01p_f0] + + zone name z50_azxe02p_f0_unity8174_spa1_spb0 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x320da0 [pwwn 21:00:00:24:ff:03:10:69] [azxe02p_f0] + + zone name z50_azpesxclin01_f0_unity8174_spa3_spb2 vsan 50 + * fcid 0x320fc0 [pwwn 50:06:01:63:47:e4:22:97] [azseunty1773_SPA3] + * fcid 0x321020 [pwwn 50:06:01:6a:47:e4:22:97] [azseunty1773_SPB2] + * fcid 0x320f42 [pwwn 20:ff:00:25:b5:a1:a0:02] [azpesxclin01_f0] + + zone name z50_azpesxclin02_f0_unity8174_spa3_spb2 vsan 50 + * fcid 0x320fc0 [pwwn 50:06:01:63:47:e4:22:97] [azseunty1773_SPA3] + * fcid 0x321020 [pwwn 50:06:01:6a:47:e4:22:97] [azseunty1773_SPB2] + * fcid 0x320f43 [pwwn 20:ff:00:25:b5:a1:a0:03] [azpesxclin02_f0] + + zone name z50_azpesxclin03_f0_unity8174_spa3_spb2 vsan 50 + * fcid 0x320fc0 [pwwn 50:06:01:63:47:e4:22:97] [azseunty1773_SPA3] + * fcid 0x321020 [pwwn 50:06:01:6a:47:e4:22:97] [azseunty1773_SPB2] + * fcid 0x320f44 [pwwn 20:ff:00:25:b5:a1:a0:01] [azpesxclin03_f0] + + zone name z50_azpesxctx01_f0_unity8174_spa1_spb0 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x320f41 [pwwn 20:ff:00:25:b5:a1:a0:04] [azpesxctx01_f0] + + zone name z50_azpesxctx02_f0_unity8174_spa1_spb0 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x320f45 [pwwn 20:ff:00:25:b5:a1:a0:05] [azpesxctx02_f0] + + zone name z50_azpesxctx03_f0_unity8174_spa1_spb0 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x320f46 [pwwn 20:ff:00:25:b5:a1:a0:06] [azpesxctx03_f0] + + zone name z50_azpesxctx04_f0_unity8174_spa1_spb0 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x320f47 [pwwn 20:ff:00:25:b5:a1:a0:07] [azpesxctx04_f0] + + zone name z50_azpesxctx05_f0_unity8174_spa1_spb0 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x320f48 [pwwn 20:ff:00:25:b5:a1:a0:08] [azpesxctx05_f0] + + zone name z50_azpesxctx06_f0_unity8174_spa1_spb0 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x320f49 [pwwn 20:ff:00:25:b5:a1:a0:09] [azpesxctx06_f0] + + zone name z50_azpesxctx07_f0_unity8174_spa1_spb0 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x320f4a [pwwn 20:ff:00:25:b5:a1:a0:0a] [azpesxctx07_f0] + + zone name z50_azpesxctx08_f0_unity8174_spa1_spb0 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x320f4b [pwwn 20:ff:00:25:b5:a1:a0:0b] [azpesxctx08_f0] + + zone name z50_azpesxctx09_f0_unity8174_spa1_spb0 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x320f4c [pwwn 20:ff:00:25:b5:a1:a0:0c] [azpesxctx09_f0] + + zone name z50_azpesxctx10_f0_unity8174_spa1_spb0 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x320f4d [pwwn 20:ff:00:25:b5:a1:a0:0d] [azpesxctx10_f0] + + zone name z50_azpesxctx11_f0_unity8174_spa1_spb0 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x320f4e [pwwn 20:ff:00:25:b5:a1:a0:0e] [azpesxctx11_f0] + + zone name z50_azpesxctx12_f0_unity8174_spa1_spb0 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x320f4f [pwwn 20:ff:00:25:b5:a1:a0:0f] [azpesxctx12_f0] + + zone name z50_azpesxctx13_f0_unity8174_spa1_spb0 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x320f50 [pwwn 20:ff:00:25:b5:a1:a0:10] [azpesxctx13_f0] + + zone name z50_azpesxctx14_f0_unity8174_spa1_spb0 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x320f51 [pwwn 20:ff:00:25:b5:a1:a0:11] [azpesxctx14_f0] + + zone name z50_azpesxctx15_f0_unity8174_spa1_spb0 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x320f52 [pwwn 20:ff:00:25:b5:a1:a0:12] [azpesxctx15_f0] + + zone name z50_azpesxctx16_f0_unity8174_spa1_spb0 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x320f53 [pwwn 20:ff:00:25:b5:a1:a0:13] [azpesxctx16_f0] + + zone name z50_azpesxctx17_f0_unity8174_spa1_spb0 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x320f54 [pwwn 20:ff:00:25:b5:a1:a0:14] [azpesxctx17_f0] + + zone name z50_azpesxctx18_f0_unity8174_spa1_spb0 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x320f55 [pwwn 20:ff:00:25:b5:a1:a0:15] [azpesxctx18_f0] + + zone name z50_azpesxctx19_f0_unity8174_spa1_spb0 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x320f56 [pwwn 20:ff:00:25:b5:a1:a0:16] [azpesxctx19_f0] + + zone name z50_azpesxctx20_f0_unity8174_spa1_spb0 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x320f57 [pwwn 20:ff:00:25:b5:a1:a0:17] [azpesxctx20_f0] + + zone name z50_azpesxctx21_f0_unity8174_spa1_spb0 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x320f59 [pwwn 20:ff:00:25:b5:a1:a0:18] [azpesxctx21_f0] + + zone name z50_azpesxctx22_f0_unity8174_spa1_spb0 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x320f58 [pwwn 20:ff:00:25:b5:a1:a0:19] [azpesxctx22_f0] + + zone name z50_azpesxctx23_f0_unity8174_spa1_spb0 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x320f5a [pwwn 20:ff:00:25:b5:a1:a0:1b] [azpesxctx23_f0] + + zone name z50_azpesxctx24_f0_unity8174_spa1_spb0 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x320f5b [pwwn 20:ff:00:25:b5:a1:a0:1a] [azpesxctx24_f0] + + zone name z50_azpesxctx25_f0_unity8174_spa1_spb0 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x320f5c [pwwn 20:ff:00:25:b5:a1:a0:1c] [azpesxctx25_f0] + + zone name z50_azpesxpci01-x_f0_unity8174_spa3_spb2 vsan 50 + * fcid 0x320fc0 [pwwn 50:06:01:63:47:e4:22:97] [azseunty1773_SPA3] + * fcid 0x321020 [pwwn 50:06:01:6a:47:e4:22:97] [azseunty1773_SPB2] + * fcid 0x320f60 [pwwn 21:00:00:24:ff:10:02:00] [azpesxpci01-x_f0] + + zone name z50_azxe01p_0FAE_8174_spb_iom_1_fc2 vsan 50 + * fcid 0x320ca0 [pwwn 21:00:00:24:ff:03:0f:ae] [azxe01p_f0] + * fcid 0x321020 [pwwn 50:06:01:6a:47:e4:22:97] [azseunty1773_SPB2] + + zone name z50_azxe02p_1069_8174_spb_iom_1_fc2 vsan 50 + * fcid 0x320da0 [pwwn 21:00:00:24:ff:03:10:69] [azxe02p_f0] + * fcid 0x321020 [pwwn 50:06:01:6a:47:e4:22:97] [azseunty1773_SPB2] + + zone name z50_azpe001_A01D_8174_spa_iom_1_fc3 vsan 50 + * fcid 0x320f5e [pwwn 20:ff:00:25:b5:a1:a0:1d] [azpe001_f0] + * fcid 0x320fc0 [pwwn 50:06:01:63:47:e4:22:97] [azseunty1773_SPA3] + + zone name z50_azpe002_A01E_8174_spb_iom_1_fc2 vsan 50 + * fcid 0x320f5f [pwwn 20:ff:00:25:b5:a1:a0:1e] [azpe002_f0] + * fcid 0x321020 [pwwn 50:06:01:6a:47:e4:22:97] [azseunty1773_SPB2] + + zone name z50_azpesxctx47_A035_8174_spb_iom_1_fc2 vsan 50 + * fcid 0x320f98 [pwwn 20:ff:00:25:b5:a1:a0:35] [azpesxctx47_f0] + * fcid 0x321020 [pwwn 50:06:01:6a:47:e4:22:97] [azseunty1773_SPB2] + + zone name z50_azpesxctx49_A037_8174_spb_iom_1_fc0 vsan 50 + * fcid 0x320f9a [pwwn 20:ff:00:25:b5:a1:a0:37] [azpesxctx49_f0] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + + zone name z50_azpesxctx49_A037_8174_spa_iom_1_fc3 vsan 50 + * fcid 0x320f9a [pwwn 20:ff:00:25:b5:a1:a0:37] [azpesxctx49_f0] + * fcid 0x320fc0 [pwwn 50:06:01:63:47:e4:22:97] [azseunty1773_SPA3] + + zone name z50_azpesxctx26_A027_8174_spa_iom_1_fc1 vsan 50 + * fcid 0x320f83 [pwwn 20:ff:00:25:b5:a1:a0:27] [azpesxctx26_f0] + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + + zone name z50_azpesxctx26_A027_8174_spb_iom_1_fc2 vsan 50 + * fcid 0x320f83 [pwwn 20:ff:00:25:b5:a1:a0:27] [azpesxctx26_f0] + * fcid 0x321020 [pwwn 50:06:01:6a:47:e4:22:97] [azseunty1773_SPB2] + + zone name z50_azpesxctx28_A02B_8174_spb_iom_1_fc0 vsan 50 + * fcid 0x320f85 [pwwn 20:ff:00:25:b5:a1:a0:2b] [azpesxctx28_f0] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + + zone name z50_azpesxctx28_A02B_8174_spa_iom_1_fc3 vsan 50 + * fcid 0x320f85 [pwwn 20:ff:00:25:b5:a1:a0:2b] [azpesxctx28_f0] + * fcid 0x320fc0 [pwwn 50:06:01:63:47:e4:22:97] [azseunty1773_SPA3] + + zone name z50_azpesxctx31_A021_8174_spa_iom_1_fc1 vsan 50 + * fcid 0x320f88 [pwwn 20:ff:00:25:b5:a1:a0:21] [azpesxctx31_f0] + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + + zone name z50_azpesxctx31_A021_8174_spb_iom_1_fc2 vsan 50 + * fcid 0x320f88 [pwwn 20:ff:00:25:b5:a1:a0:21] [azpesxctx31_f0] + * fcid 0x321020 [pwwn 50:06:01:6a:47:e4:22:97] [azseunty1773_SPB2] + + zone name z50_azpesxctx32_A023_8174_spb_iom_1_fc0 vsan 50 + * fcid 0x320f89 [pwwn 20:ff:00:25:b5:a1:a0:23] [azpesxctx32_f0] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + + zone name z50_azpesxctx32_A023_8174_spa_iom_1_fc3 vsan 50 + * fcid 0x320f89 [pwwn 20:ff:00:25:b5:a1:a0:23] [azpesxctx32_f0] + * fcid 0x320fc0 [pwwn 50:06:01:63:47:e4:22:97] [azseunty1773_SPA3] + + zone name z50_azpesxctx29_A02D_8174_spa_iom_1_fc1 vsan 50 + * fcid 0x320f86 [pwwn 20:ff:00:25:b5:a1:a0:2d] [azpesxctx29_f0] + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + + zone name z50_azpesxctx29_A02D_8174_spb_iom_1_fc2 vsan 50 + * fcid 0x320f86 [pwwn 20:ff:00:25:b5:a1:a0:2d] [azpesxctx29_f0] + * fcid 0x321020 [pwwn 50:06:01:6a:47:e4:22:97] [azseunty1773_SPB2] + + zone name z50_azpesxctx33_A024_8174_spb_iom_1_fc0 vsan 50 + * fcid 0x320f8b [pwwn 20:ff:00:25:b5:a1:a0:24] [azpesxctx33_f0] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + + zone name z50_azpesxctx33_A024_8174_spa_iom_1_fc3 vsan 50 + * fcid 0x320f8b [pwwn 20:ff:00:25:b5:a1:a0:24] [azpesxctx33_f0] + * fcid 0x320fc0 [pwwn 50:06:01:63:47:e4:22:97] [azseunty1773_SPA3] + + zone name z50_azpesxctx30_A01F_8174_spa_iom_1_fc1 vsan 50 + * fcid 0x320f87 [pwwn 20:ff:00:25:b5:a1:a0:1f] [azpesxctx30_f0] + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + + zone name z50_azpesxctx30_A01F_8174_spb_iom_1_fc2 vsan 50 + * fcid 0x320f87 [pwwn 20:ff:00:25:b5:a1:a0:1f] [azpesxctx30_f0] + * fcid 0x321020 [pwwn 50:06:01:6a:47:e4:22:97] [azseunty1773_SPB2] + + zone name z50_azpesxctx27_A029_8174_spb_iom_1_fc0 vsan 50 + * fcid 0x320f84 [pwwn 20:ff:00:25:b5:a1:a0:29] [azpesxctx27_f0] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + + zone name z50_azpesxctx27_A029_8174_spa_iom_1_fc3 vsan 50 + * fcid 0x320f84 [pwwn 20:ff:00:25:b5:a1:a0:29] [azpesxctx27_f0] + * fcid 0x320fc0 [pwwn 50:06:01:63:47:e4:22:97] [azseunty1773_SPA3] + + zone name z50_azpesxctx35_A026_8174_spa_iom_1_fc1 vsan 50 + * fcid 0x320f8c [pwwn 20:ff:00:25:b5:a1:a0:26] [azpesxctx35_f0] + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + + zone name z50_azpesxctx35_A026_8174_spb_iom_1_fc2 vsan 50 + * fcid 0x320f8c [pwwn 20:ff:00:25:b5:a1:a0:26] [azpesxctx35_f0] + * fcid 0x321020 [pwwn 50:06:01:6a:47:e4:22:97] [azseunty1773_SPB2] + + zone name z50_azpesxctx37_A02A_8174_spb_iom_1_fc0 vsan 50 + * fcid 0x320f8e [pwwn 20:ff:00:25:b5:a1:a0:2a] [azpesxctx37_f0] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + + zone name z50_azpesxctx37_A02A_8174_spa_iom_1_fc3 vsan 50 + * fcid 0x320f8e [pwwn 20:ff:00:25:b5:a1:a0:2a] [azpesxctx37_f0] + * fcid 0x320fc0 [pwwn 50:06:01:63:47:e4:22:97] [azseunty1773_SPA3] + + zone name z50_azpesxctx38_A02C_8174_spa_iom_1_fc1 vsan 50 + * fcid 0x320f8f [pwwn 20:ff:00:25:b5:a1:a0:2c] [azpesxctx38_f0] + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + + zone name z50_azpesxctx38_A02C_8174_spb_iom_1_fc2 vsan 50 + * fcid 0x320f8f [pwwn 20:ff:00:25:b5:a1:a0:2c] [azpesxctx38_f0] + * fcid 0x321020 [pwwn 50:06:01:6a:47:e4:22:97] [azseunty1773_SPB2] + + zone name z50_azpesxctx40_A020_8174_spb_iom_1_fc0 vsan 50 + * fcid 0x320f91 [pwwn 20:ff:00:25:b5:a1:a0:20] [azpesxctx40_f0] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + + zone name z50_azpesxctx40_A020_8174_spa_iom_1_fc3 vsan 50 + * fcid 0x320f91 [pwwn 20:ff:00:25:b5:a1:a0:20] [azpesxctx40_f0] + * fcid 0x320fc0 [pwwn 50:06:01:63:47:e4:22:97] [azseunty1773_SPA3] + + zone name z50_azpesxctx34_A025_8174_spa_iom_1_fc1 vsan 50 + * fcid 0x320f8a [pwwn 20:ff:00:25:b5:a1:a0:25] [azpesxctx34_f0] + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + + zone name z50_azpesxctx34_A025_8174_spb_iom_1_fc2 vsan 50 + * fcid 0x320f8a [pwwn 20:ff:00:25:b5:a1:a0:25] [azpesxctx34_f0] + * fcid 0x321020 [pwwn 50:06:01:6a:47:e4:22:97] [azseunty1773_SPB2] + + zone name z50_azpesxctx41_A022_8174_spb_iom_1_fc0 vsan 50 + * fcid 0x320f92 [pwwn 20:ff:00:25:b5:a1:a0:22] [azpesxctx41_f0] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + + zone name z50_azpesxctx41_A022_8174_spa_iom_1_fc3 vsan 50 + * fcid 0x320f92 [pwwn 20:ff:00:25:b5:a1:a0:22] [azpesxctx41_f0] + * fcid 0x320fc0 [pwwn 50:06:01:63:47:e4:22:97] [azseunty1773_SPA3] + + zone name z50_azpesxctx42_A02F_8174_spa_iom_1_fc1 vsan 50 + * fcid 0x320f93 [pwwn 20:ff:00:25:b5:a1:a0:2f] [azpesxctx42_f0] + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + + zone name z50_azpesxctx42_A02F_8174_spb_iom_1_fc2 vsan 50 + * fcid 0x320f93 [pwwn 20:ff:00:25:b5:a1:a0:2f] [azpesxctx42_f0] + * fcid 0x321020 [pwwn 50:06:01:6a:47:e4:22:97] [azseunty1773_SPB2] + + zone name z50_azpesxctx36_A028_8174_spb_iom_1_fc0 vsan 50 + * fcid 0x320f8d [pwwn 20:ff:00:25:b5:a1:a0:28] [azpesxctx36_f0] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + + zone name z50_azpesxctx36_A028_8174_spa_iom_1_fc3 vsan 50 + * fcid 0x320f8d [pwwn 20:ff:00:25:b5:a1:a0:28] [azpesxctx36_f0] + * fcid 0x320fc0 [pwwn 50:06:01:63:47:e4:22:97] [azseunty1773_SPA3] + + zone name z50_azpesxctx43_A030_8174_spa_iom_1_fc1 vsan 50 + * fcid 0x320f94 [pwwn 20:ff:00:25:b5:a1:a0:30] [azpesxctx43_f0] + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + + zone name z50_azpesxctx43_A030_8174_spb_iom_1_fc2 vsan 50 + * fcid 0x320f94 [pwwn 20:ff:00:25:b5:a1:a0:30] [azpesxctx43_f0] + * fcid 0x321020 [pwwn 50:06:01:6a:47:e4:22:97] [azseunty1773_SPB2] + + zone name z50_azpesxctx44_A031_8174_spb_iom_1_fc0 vsan 50 + * fcid 0x320f95 [pwwn 20:ff:00:25:b5:a1:a0:31] [azpesxctx44_f0] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + + zone name z50_azpesxctx44_A031_8174_spa_iom_1_fc3 vsan 50 + * fcid 0x320f95 [pwwn 20:ff:00:25:b5:a1:a0:31] [azpesxctx44_f0] + * fcid 0x320fc0 [pwwn 50:06:01:63:47:e4:22:97] [azseunty1773_SPA3] + + zone name z50_azpesxctx45_A032_8174_spa_iom_1_fc1 vsan 50 + * fcid 0x320f96 [pwwn 20:ff:00:25:b5:a1:a0:32] [azpesxctx45_f0] + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + + zone name z50_azpesxctx45_A032_8174_spb_iom_1_fc2 vsan 50 + * fcid 0x320f96 [pwwn 20:ff:00:25:b5:a1:a0:32] [azpesxctx45_f0] + * fcid 0x321020 [pwwn 50:06:01:6a:47:e4:22:97] [azseunty1773_SPB2] + + zone name z50_azpesxctx39_A02E_8174_spb_iom_1_fc0 vsan 50 + * fcid 0x320f90 [pwwn 20:ff:00:25:b5:a1:a0:2e] [azpesxctx39_f0] + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + + zone name z50_azpesxctx39_A02E_8174_spa_iom_1_fc3 vsan 50 + * fcid 0x320f90 [pwwn 20:ff:00:25:b5:a1:a0:2e] [azpesxctx39_f0] + * fcid 0x320fc0 [pwwn 50:06:01:63:47:e4:22:97] [azseunty1773_SPA3] + + zone name z50_azunim1_f0_unity8714_spa1 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x3211c1 [pwwn c0:50:76:09:5b:20:00:10] [azunim1_f0] + + zone name z50_azunim1_f2_unity8714_spb0 vsan 50 + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x321201 [pwwn c0:50:76:09:5b:20:00:14] [azunim1_f2] + + zone name z50_azusant_f2_unity8174_spb0 vsan 50 + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x32120b [pwwn c0:50:76:09:5b:20:00:60] [azusant_f2] + + zone name z50_azucdrdb1_f0_unity8174_spa1 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x3211a7 [pwwn c0:50:76:09:5b:20:00:3a] [azucdrdb1_f0] + + zone name z50_azucdrdb1_f2_unity8174_spb0 vsan 50 + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x321229 [pwwn c0:50:76:09:5b:20:00:3e] [azucdrdb1_f2] + + zone name z50_azpups01_f0_unity8174_spa1 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x3211a3 [pwwn c0:50:76:09:5b:20:00:1a] [azupsp1_f0] + + zone name z50_azupsdbp1_f0_unity8174_spa1 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x321203 [pwwn c0:50:76:09:5b:20:00:20] [azupsdbp1_f0] + + zone name z50_azupsdbp1_f2_unity8174_spb0 vsan 50 + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x3211c3 [pwwn c0:50:76:09:5b:20:00:24] [azupsdbp1_f2] + + zone name z50_azucdrsr1_f0_unity1773_spa3 vsan 50 + * fcid 0x320fc0 [pwwn 50:06:01:63:47:e4:22:97] [azseunty1773_SPA3] + * fcid 0x3211c7 [pwwn c0:50:76:09:5b:20:00:44] [azucdrsr1_f0] + + zone name z50_azudbas1_f0_unity8174_spa1 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x32122b [pwwn c0:50:76:09:5b:20:00:4a] [azudbas1_f0] + + zone name z50_azudbas1_f2_unity8174_spb0 vsan 50 + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x3211a9 [pwwn c0:50:76:09:5b:20:00:4e] [azudbas1_f2] + + zone name z50_azukronp1_f0_unity8174_spa1 vsan 50 + * fcid 0x320fa0 [pwwn 50:06:01:61:47:e4:22:97] [azseunty1773_SPA1] + * fcid 0x321227 [pwwn c0:50:76:09:5b:20:00:2a] [azukronp1_f0] + + zone name z50_azukronp1_f00_unity8174_spb0 vsan 50 + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x3211a5 [pwwn c0:50:76:09:5b:20:00:2e] [azukronp1_f00] + + zone name z50_azpups01_f2_unity8174_spb0 vsan 50 + * fcid 0x321000 [pwwn 50:06:01:68:47:e4:22:97] [azseunty1773_SPB0] + * fcid 0x321225 [pwwn c0:50:76:09:5b:20:00:1e] [azupsp1_f2] + + zone name z50_azucdrsr1_f2_unity1773_spb2 vsan 50 + * fcid 0x321020 [pwwn 50:06:01:6a:47:e4:22:97] [azseunty1773_SPB2] + * fcid 0x321207 [pwwn c0:50:76:09:5b:20:00:40] [azucdrsr1_f2] + + zone name z50_azuepicclarp1_f0_unity8174_spa3 vsan 50 + * fcid 0x320fc0 [pwwn 50:06:01:63:47:e4:22:97] [azseunty1773_SPA3] + * fcid 0x3211c9 [pwwn c0:50:76:09:5b:20:00:50] [azuepicclarp1_f0] + + zone name z50_azuepicclarp1_f2_unity8174_spb2 vsan 50 + * fcid 0x321020 [pwwn 50:06:01:6a:47:e4:22:97] [azseunty1773_SPB2] + * fcid 0x321209 [pwwn c0:50:76:09:5b:20:00:54] [azuepicclarp1_f2] + + zone name z50_azpwovd01_A001_8174_spb_iom_1_fc2 vsan 50 + * fcid 0x320f5d [pwwn 20:ff:00:25:b5:a2:a0:01] [azpwovd01_f0] + * fcid 0x321020 [pwwn 50:06:01:6a:47:e4:22:97] [azseunty1773_SPB2] diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/show_zoneset_vsan.out b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/show_zoneset_vsan.out new file mode 100644 index 00000000..ba1d82b9 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/show_zoneset_vsan.out @@ -0,0 +1,947 @@ +zoneset name z50_csphfab1_zoneset vsan 50 + zone name z50_azusant_f0_unity8174_spa1 vsan 50 + pwwn c0:50:76:09:5b:20:00:64 [azusant_f0] + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + zone name z50_azplcbsx000652_san01-azsncbsx01_0ac vsan 50 + fcalias name azplcbsx000652_san01 vsan 50 + pwwn 21:00:f4:e9:d4:57:6e:66 [azplcbsx000652_san01] + + fcalias name azsncbsx01_c01_0a vsan 50 + pwwn 20:12:00:a0:98:fa:42:6e [azsncbsx01_c01_0a] + + fcalias name azsncbsx01_c01_0c vsan 50 + pwwn 20:32:00:a0:98:fa:42:6e [azsncbsx01_c01_0c] + + fcalias name azsncbsx01_c02_0a vsan 50 + pwwn 20:13:00:a0:98:fa:42:6e [azsncbsx01_c02_0a] + + fcalias name azsncbsx01_c02_0c vsan 50 + pwwn 20:33:00:a0:98:fa:42:6e [azsncbsx01_c02_0c] + + zone name z50_azplcbsx000653_san01-azsncbsx01_0ac vsan 50 + fcalias name azplcbsx000653_san01 vsan 50 + pwwn 21:00:f4:e9:d4:54:a7:c8 [azplcbsx000653_san01] + + fcalias name azsncbsx01_c01_0a vsan 50 + pwwn 20:12:00:a0:98:fa:42:6e [azsncbsx01_c01_0a] + + fcalias name azsncbsx01_c01_0c vsan 50 + pwwn 20:32:00:a0:98:fa:42:6e [azsncbsx01_c01_0c] + + fcalias name azsncbsx01_c02_0a vsan 50 + pwwn 20:13:00:a0:98:fa:42:6e [azsncbsx01_c02_0a] + + fcalias name azsncbsx01_c02_0c vsan 50 + pwwn 20:33:00:a0:98:fa:42:6e [azsncbsx01_c02_0c] + + zone name z50_azplwebodb01_f0_unity1773_spa3_spb2 vsan 50 + fcalias name azseunty8174_SPA3 vsan 50 + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + + fcalias name azseunty8174_SPB2 vsan 50 + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + fcalias name azplwebdb01_f0 vsan 50 + pwwn 21:00:00:24:ff:0c:58:37 [azplwebodb01_f0] + + zone name z50_azpwvnasql1_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpwvnasql1_f0 vsan 50 + pwwn 21:00:00:24:ff:0d:26:68 [azpwvnasql1_f0] + + zone name z50_azplcbsx000652_san01-azsncbsx02_0ac vsan 50 + fcalias name azplcbsx000652_san01 vsan 50 + pwwn 21:00:f4:e9:d4:57:6e:66 [azplcbsx000652_san01] + + fcalias name azsncbsx02_c01_0a vsan 50 + pwwn 20:12:00:a0:98:42:fa:8c + + fcalias name azsncbsx02_c01_0c vsan 50 + pwwn 20:32:00:a0:98:fa:42:8c [azsncbsx02_c01_0c] + + fcalias name azsncbsx02_c02_0a vsan 50 + pwwn 20:13:00:a0:98:fa:42:8c [azsncbsx02_c02_0a] + + fcalias name azsncbsx02_c02_0c vsan 50 + pwwn 20:33:00:a0:98:fa:42:8c [azsncbsx02_c02_0c] + + zone name z50_azplcbsx000653_san01-azsncbsx02_0ac vsan 50 + fcalias name azplcbsx000653_san01 vsan 50 + pwwn 21:00:f4:e9:d4:54:a7:c8 [azplcbsx000653_san01] + + fcalias name azsncbsx02_c01_0a vsan 50 + pwwn 20:12:00:a0:98:42:fa:8c + + fcalias name azsncbsx02_c01_0c vsan 50 + pwwn 20:32:00:a0:98:fa:42:8c [azsncbsx02_c01_0c] + + fcalias name azsncbsx02_c02_0a vsan 50 + pwwn 20:13:00:a0:98:fa:42:8c [azsncbsx02_c02_0a] + + fcalias name azsncbsx02_c02_0c vsan 50 + pwwn 20:33:00:a0:98:fa:42:8c [azsncbsx02_c02_0c] + + zone name z50_azpwovd01_A001_8174_spa_iom_1_fc1 vsan 50 + pwwn 20:ff:00:25:b5:a2:a0:01 [azpwovd01_f0] + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + zone name z50_azplocat02_f0_unity8174_spa3_spb2 vsan 50 + fcalias name azseunty8174_SPA3 vsan 50 + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + + fcalias name azseunty8174_SPB2 vsan 50 + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + fcalias name azplocat02_f0 vsan 50 + pwwn 21:00:00:24:ff:01:18:5f [azplocat02_f0] + + zone name z50_azpe123_A03B_8174_spa_iom_1_fc1 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:3b [azpe123_f0] + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + zone name z50_azpe001_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpe001_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:1d [azpe001_f0] + + zone name z50_azpe123_A03B_8174_spb_iom_1_fc2 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:3b [azpe123_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + zone name z50_azuqaunx_f1_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azuqaunx_01_f0 vsan 50 + pwwn c0:50:76:09:5b:20:00:0e [azuqaunx-01_f0] + pwwn c0:50:76:09:5b:20:00:0f + + zone name z50_azplcbsx000309_san01-azsncbsx01_0ac vsan 50 + fcalias name azsncbsx01_c01_0a vsan 50 + pwwn 20:12:00:a0:98:fa:42:6e [azsncbsx01_c01_0a] + + fcalias name azsncbsx01_c01_0c vsan 50 + pwwn 20:32:00:a0:98:fa:42:6e [azsncbsx01_c01_0c] + + fcalias name azsncbsx01_c02_0a vsan 50 + pwwn 20:13:00:a0:98:fa:42:6e [azsncbsx01_c02_0a] + + fcalias name azsncbsx01_c02_0c vsan 50 + pwwn 20:33:00:a0:98:fa:42:6e [azsncbsx01_c02_0c] + + fcalias name azplcbsx000309_san01 vsan 50 + pwwn 21:00:f4:e9:d4:55:f3:e6 [azplcbsx000309_san01] + + zone name z50_azpe002_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpe002_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:1e [azpe002_f0] + + zone name z50_azpe122_A03A_8174_spb_iom_1_fc0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:3a [azpe122_f0] + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + zone name z50_azpe122_A03A_8174_spa_iom_1_fc3 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:3a [azpe122_f0] + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + + zone name z50_azulaba_f0_unity8174_spa1 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azulaba_f0 vsan 50 + pwwn c0:50:76:09:5b:20:00:30 + pwwn c0:50:76:09:5b:20:00:31 + + zone name z50_azulaba_f2_unity8174_spb0 vsan 50 + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azulaba_f2 vsan 50 + pwwn c0:50:76:09:5b:20:00:34 [azulaba_f2] + pwwn c0:50:76:09:5b:20:00:35 + + zone name z50_azlonbasep1_f0_unity8174_spa3_spb2 vsan 50 + fcalias name azseunty8174_SPA3 vsan 50 + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + + fcalias name azseunty8174_SPB2 vsan 50 + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + fcalias name azlonbasep1_f0 vsan 50 + pwwn 21:00:00:24:ff:01:78:b0 [azlonbasep1_f0] + + zone name z50_azplcbsx000309_san01-azsncbsx02_0ac vsan 50 + fcalias name azsncbsx02_c01_0a vsan 50 + pwwn 20:12:00:a0:98:42:fa:8c + + fcalias name azsncbsx02_c01_0c vsan 50 + pwwn 20:32:00:a0:98:fa:42:8c [azsncbsx02_c01_0c] + + fcalias name azsncbsx02_c02_0a vsan 50 + pwwn 20:13:00:a0:98:fa:42:8c [azsncbsx02_c02_0a] + + fcalias name azsncbsx02_c02_0c vsan 50 + pwwn 20:33:00:a0:98:fa:42:8c [azsncbsx02_c02_0c] + + fcalias name azplcbsx000309_san01 vsan 50 + pwwn 21:00:f4:e9:d4:55:f3:e6 [azplcbsx000309_san01] + + zone name z50_azplcslrpa1_f0_unity1773 vsan 50 + fcalias name azseunty8174_SPA3 vsan 50 + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + + fcalias name azseunty8174_SPB2 vsan 50 + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azplcslrpa1-1_f0 vsan 50 + pwwn 50:01:24:80:0b:50:46:03 [azplcslrpa1-1_f0] + + fcalias name azplcslrpa1-2_f0 vsan 50 + pwwn 50:01:24:80:00:a0:46:03 [azplcslrpa1-2_f0] + + fcalias name azplcslrpa1-4_f0 vsan 50 + pwwn 50:01:24:80:09:c0:66:03 [azplcslrpa1-4_f0] + + fcalias name azplcslrpa1-3_f0 vsan 50 + pwwn 50:01:24:80:0f:d0:46:03 [azplcslrpa1-3_f0] + + zone name z50_azpe120_A038_8174_spa_iom_1_fc1 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:38 [azpe120_f0] + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + zone name z50_azpe120_A038_8174_spb_iom_1_fc2 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:38 [azpe120_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + zone name z50_azpe121_A039_8174_spb_iom_1_fc0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:39 [azpe121_f0] + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + zone name z50_azplcbsx000310_san01-azsncbsx01_0ac vsan 50 + fcalias name azsncbsx01_c01_0a vsan 50 + pwwn 20:12:00:a0:98:fa:42:6e [azsncbsx01_c01_0a] + + fcalias name azsncbsx01_c01_0c vsan 50 + pwwn 20:32:00:a0:98:fa:42:6e [azsncbsx01_c01_0c] + + fcalias name azsncbsx01_c02_0a vsan 50 + pwwn 20:13:00:a0:98:fa:42:6e [azsncbsx01_c02_0a] + + fcalias name azsncbsx01_c02_0c vsan 50 + pwwn 20:33:00:a0:98:fa:42:6e [azsncbsx01_c02_0c] + + fcalias name azplcbsx000310_san01 vsan 50 + pwwn 21:00:f4:e9:d4:55:f4:4a [azplcbsx000310_san01] + + zone name z50_azplcbsx000310_san01-azsncbsx02_0ac vsan 50 + fcalias name azsncbsx02_c01_0a vsan 50 + pwwn 20:12:00:a0:98:42:fa:8c + + fcalias name azsncbsx02_c01_0c vsan 50 + pwwn 20:32:00:a0:98:fa:42:8c [azsncbsx02_c01_0c] + + fcalias name azsncbsx02_c02_0a vsan 50 + pwwn 20:13:00:a0:98:fa:42:8c [azsncbsx02_c02_0a] + + fcalias name azsncbsx02_c02_0c vsan 50 + pwwn 20:33:00:a0:98:fa:42:8c [azsncbsx02_c02_0c] + + fcalias name azplcbsx000310_san01 vsan 50 + pwwn 21:00:f4:e9:d4:55:f4:4a [azplcbsx000310_san01] + + zone name z50_azpe121_A039_8174_spa_iom_1_fc3 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:39 [azpe121_f0] + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + + zone name z50_azpesxctx48_A036_8174_spa_iom_1_fc1 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:36 [azpesxctx48_f0] + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + zone name z50_azpesxctx48_A036_8174_spb_iom_1_fc2 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:36 [azpesxctx48_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + zone name z50_azpesxctx50_A033_8174_spa_iom_1_fc1 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:33 [azpesxctx50_f0] + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + zone name z50_azuqaunx_f0_unity8174_spa1 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + zone name z50_azuqaunx_f2_unity8174_spb0 vsan 50 + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + zone name z50_azpesxctx50_A033_8174_spb_iom_1_fc2 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:33 [azpesxctx50_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + zone name z50_azpesxctx46_A034_8174_spb_iom_1_fc0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:34 [azpesxctx46_f0] + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + zone name z50_azpesxctx46_A034_8174_spa_iom_1_fc3 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:34 [azpesxctx46_f0] + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + + zone name z50_azpesxctx47_A035_8174_spa_iom_1_fc1 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:35 [azpesxctx47_f0] + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + zone name z50_azplepicbu01_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azplepicbu01_f0 vsan 50 + pwwn 20:ff:00:25:b5:a3:a0:02 [azplepicbu01_f0] + + zone name z50_azxe01p_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azxe01p_f0 vsan 50 + pwwn 21:00:00:24:ff:03:0f:ae [azxe01p_f0] + + zone name z50_azxe02p_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azxe02p_f0 vsan 50 + pwwn 21:00:00:24:ff:03:10:69 [azxe02p_f0] + + zone name z50_azpesxclin01_f0_unity8174_spa3_spb2 vsan 50 + fcalias name azseunty8174_SPA3 vsan 50 + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + + fcalias name azseunty8174_SPB2 vsan 50 + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + fcalias name azpesxclin01_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:02 [azpesxclin01_f0] + + zone name z50_azpesxclin02_f0_unity8174_spa3_spb2 vsan 50 + fcalias name azseunty8174_SPA3 vsan 50 + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + + fcalias name azseunty8174_SPB2 vsan 50 + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + fcalias name azpesxclin02_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:03 [azpesxclin02_f0] + + zone name z50_azpesxclin03_f0_unity8174_spa3_spb2 vsan 50 + fcalias name azseunty8174_SPA3 vsan 50 + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + + fcalias name azseunty8174_SPB2 vsan 50 + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + fcalias name azpesxclin03_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:01 [azpesxclin03_f0] + + zone name z50_azpesxctx01_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx01_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:04 [azpesxctx01_f0] + + zone name z50_azpesxctx02_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx02_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:05 [azpesxctx02_f0] + + zone name z50_azpesxctx03_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx03_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:06 [azpesxctx03_f0] + + zone name z50_azpesxctx04_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx04_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:07 [azpesxctx04_f0] + + zone name z50_azpesxctx05_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx05_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:08 [azpesxctx05_f0] + + zone name z50_azpesxctx06_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx06_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:09 [azpesxctx06_f0] + + zone name z50_azpesxctx07_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx07_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:0a [azpesxctx07_f0] + + zone name z50_azpesxctx08_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx08_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:0b [azpesxctx08_f0] + + zone name z50_azpesxctx09_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx09_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:0c [azpesxctx09_f0] + + zone name z50_azpesxctx10_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx10_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:0d [azpesxctx10_f0] + + zone name z50_azpesxctx11_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx11_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:0e [azpesxctx11_f0] + + zone name z50_azpesxctx12_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx12_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:0f [azpesxctx12_f0] + + zone name z50_azpesxctx13_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx13_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:10 [azpesxctx13_f0] + + zone name z50_azpesxctx14_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx14_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:11 [azpesxctx14_f0] + + zone name z50_azpesxctx15_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx15_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:12 [azpesxctx15_f0] + + zone name z50_azpesxctx16_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx16_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:13 [azpesxctx16_f0] + + zone name z50_azpesxctx17_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx17_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:14 [azpesxctx17_f0] + + zone name z50_azpesxctx18_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx18_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:15 [azpesxctx18_f0] + + zone name z50_azpesxctx19_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx19_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:16 [azpesxctx19_f0] + + zone name z50_azpesxctx20_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx20_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:17 [azpesxctx20_f0] + + zone name z50_azpesxctx21_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx21_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:18 [azpesxctx21_f0] + + zone name z50_azpesxctx22_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx22_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:19 [azpesxctx22_f0] + + zone name z50_azpesxctx23_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx23_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:1b [azpesxctx23_f0] + + zone name z50_azpesxctx24_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx24_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:1a [azpesxctx24_f0] + + zone name z50_azpesxctx25_f0_unity8174_spa1_spb0 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azpesxctx25_f0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:1c [azpesxctx25_f0] + + zone name z50_azpesxpci01-x_f0_unity8174_spa3_spb2 vsan 50 + fcalias name azseunty8174_SPA3 vsan 50 + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + + fcalias name azseunty8174_SPB2 vsan 50 + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + fcalias name azpesxpci01-x_f0 vsan 50 + pwwn 21:00:00:24:ff:10:02:00 [azpesxpci01-x_f0] + + zone name z50_azxe01p_0FAE_8174_spb_iom_1_fc2 vsan 50 + pwwn 21:00:00:24:ff:03:0f:ae [azxe01p_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + zone name z50_azxe02p_1069_8174_spb_iom_1_fc2 vsan 50 + pwwn 21:00:00:24:ff:03:10:69 [azxe02p_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + zone name z50_azpe001_A01D_8174_spa_iom_1_fc3 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:1d [azpe001_f0] + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + + zone name z50_azpe002_A01E_8174_spb_iom_1_fc2 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:1e [azpe002_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + zone name z50_azpesxctx47_A035_8174_spb_iom_1_fc2 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:35 [azpesxctx47_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + zone name z50_azpesxctx49_A037_8174_spb_iom_1_fc0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:37 [azpesxctx49_f0] + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + zone name z50_azpesxctx49_A037_8174_spa_iom_1_fc3 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:37 [azpesxctx49_f0] + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + + zone name z50_azpesxctx26_A027_8174_spa_iom_1_fc1 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:27 [azpesxctx26_f0] + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + zone name z50_azpesxctx26_A027_8174_spb_iom_1_fc2 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:27 [azpesxctx26_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + zone name z50_azpesxctx28_A02B_8174_spb_iom_1_fc0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:2b [azpesxctx28_f0] + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + zone name z50_azpesxctx28_A02B_8174_spa_iom_1_fc3 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:2b [azpesxctx28_f0] + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + + zone name z50_azpesxctx31_A021_8174_spa_iom_1_fc1 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:21 [azpesxctx31_f0] + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + zone name z50_azpesxctx31_A021_8174_spb_iom_1_fc2 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:21 [azpesxctx31_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + zone name z50_azpesxctx32_A023_8174_spb_iom_1_fc0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:23 [azpesxctx32_f0] + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + zone name z50_azpesxctx32_A023_8174_spa_iom_1_fc3 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:23 [azpesxctx32_f0] + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + + zone name z50_azpesxctx29_A02D_8174_spa_iom_1_fc1 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:2d [azpesxctx29_f0] + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + zone name z50_azpesxctx29_A02D_8174_spb_iom_1_fc2 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:2d [azpesxctx29_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + zone name z50_azpesxctx33_A024_8174_spb_iom_1_fc0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:24 [azpesxctx33_f0] + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + zone name z50_azpesxctx33_A024_8174_spa_iom_1_fc3 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:24 [azpesxctx33_f0] + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + + zone name z50_azpesxctx30_A01F_8174_spa_iom_1_fc1 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:1f [azpesxctx30_f0] + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + zone name z50_azpesxctx30_A01F_8174_spb_iom_1_fc2 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:1f [azpesxctx30_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + zone name z50_azpesxctx27_A029_8174_spb_iom_1_fc0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:29 [azpesxctx27_f0] + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + zone name z50_azpesxctx27_A029_8174_spa_iom_1_fc3 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:29 [azpesxctx27_f0] + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + + zone name z50_azpesxctx35_A026_8174_spa_iom_1_fc1 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:26 [azpesxctx35_f0] + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + zone name z50_azpesxctx35_A026_8174_spb_iom_1_fc2 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:26 [azpesxctx35_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + zone name z50_azpesxctx37_A02A_8174_spb_iom_1_fc0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:2a [azpesxctx37_f0] + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + zone name z50_azpesxctx37_A02A_8174_spa_iom_1_fc3 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:2a [azpesxctx37_f0] + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + + zone name z50_azpesxctx38_A02C_8174_spa_iom_1_fc1 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:2c [azpesxctx38_f0] + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + zone name z50_azpesxctx38_A02C_8174_spb_iom_1_fc2 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:2c [azpesxctx38_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + zone name z50_azpesxctx40_A020_8174_spb_iom_1_fc0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:20 [azpesxctx40_f0] + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + zone name z50_azpesxctx40_A020_8174_spa_iom_1_fc3 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:20 [azpesxctx40_f0] + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + + zone name z50_azpesxctx34_A025_8174_spa_iom_1_fc1 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:25 [azpesxctx34_f0] + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + zone name z50_azpesxctx34_A025_8174_spb_iom_1_fc2 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:25 [azpesxctx34_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + zone name z50_azpesxctx41_A022_8174_spb_iom_1_fc0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:22 [azpesxctx41_f0] + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + zone name z50_azpesxctx41_A022_8174_spa_iom_1_fc3 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:22 [azpesxctx41_f0] + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + + zone name z50_azpesxctx42_A02F_8174_spa_iom_1_fc1 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:2f [azpesxctx42_f0] + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + zone name z50_azpesxctx42_A02F_8174_spb_iom_1_fc2 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:2f [azpesxctx42_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + zone name z50_azpesxctx36_A028_8174_spb_iom_1_fc0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:28 [azpesxctx36_f0] + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + zone name z50_azpesxctx36_A028_8174_spa_iom_1_fc3 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:28 [azpesxctx36_f0] + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + + zone name z50_azpesxctx43_A030_8174_spa_iom_1_fc1 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:30 [azpesxctx43_f0] + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + zone name z50_azpesxctx43_A030_8174_spb_iom_1_fc2 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:30 [azpesxctx43_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + zone name z50_azpesxctx44_A031_8174_spb_iom_1_fc0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:31 [azpesxctx44_f0] + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + zone name z50_azpesxctx44_A031_8174_spa_iom_1_fc3 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:31 [azpesxctx44_f0] + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + + zone name z50_azpesxctx45_A032_8174_spa_iom_1_fc1 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:32 [azpesxctx45_f0] + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + zone name z50_azpesxctx45_A032_8174_spb_iom_1_fc2 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:32 [azpesxctx45_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + zone name z50_azpesxctx39_A02E_8174_spb_iom_1_fc0 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:2e [azpesxctx39_f0] + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + zone name z50_azpesxctx39_A02E_8174_spa_iom_1_fc3 vsan 50 + pwwn 20:ff:00:25:b5:a1:a0:2e [azpesxctx39_f0] + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + + zone name z50_azunim1_f0_unity8714_spa1 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azunim1_f0 vsan 50 + pwwn c0:50:76:09:5b:20:00:10 [azunim1_f0] + + zone name z50_azunim1_f2_unity8714_spb0 vsan 50 + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azunim1_f2 vsan 50 + pwwn c0:50:76:09:5b:20:00:14 [azunim1_f2] + + zone name z50_azusant_f2_unity8174_spb0 vsan 50 + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azusant_f2 vsan 50 + pwwn c0:50:76:09:5b:20:00:60 [azusant_f2] + + zone name z50_azucdrdb1_f0_unity8174_spa1 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azucdrdb1_f0 vsan 50 + pwwn c0:50:76:09:5b:20:00:3a [azucdrdb1_f0] + + zone name z50_azucdrdb1_f2_unity8174_spb0 vsan 50 + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azucdrdb1_f2 vsan 50 + pwwn c0:50:76:09:5b:20:00:3e [azucdrdb1_f2] + + zone name z50_azpups01_f0_unity8174_spa1 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azupsp1_f0 vsan 50 + pwwn c0:50:76:09:5b:20:00:1a [azupsp1_f0] + + zone name z50_azupsdbp1_f0_unity8174_spa1 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azupsdbp1_f0 vsan 50 + pwwn c0:50:76:09:5b:20:00:20 [azupsdbp1_f0] + + zone name z50_azupsdbp1_f2_unity8174_spb0 vsan 50 + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azupsdbp1_f2 vsan 50 + pwwn c0:50:76:09:5b:20:00:24 [azupsdbp1_f2] + + zone name z50_azucdrsr1_f0_unity1773_spa3 vsan 50 + fcalias name azseunty8174_SPA3 vsan 50 + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + + fcalias name azucdrsr1_f0 vsan 50 + pwwn c0:50:76:09:5b:20:00:44 [azucdrsr1_f0] + + zone name z50_azudbas1_f0_unity8174_spa1 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azudbas1_f0 vsan 50 + pwwn c0:50:76:09:5b:20:00:4a [azudbas1_f0] + + zone name z50_azudbas1_f2_unity8174_spb0 vsan 50 + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azudbas1_f2 vsan 50 + pwwn c0:50:76:09:5b:20:00:4e [azudbas1_f2] + + zone name z50_azukronp1_f0_unity8174_spa1 vsan 50 + fcalias name azseunty8174_SPA1 vsan 50 + pwwn 50:06:01:61:47:e4:22:97 [azseunty1773_SPA1] + + fcalias name azukronp1_f0 vsan 50 + pwwn c0:50:76:09:5b:20:00:2a [azukronp1_f0] + + zone name z50_azukronp1_f00_unity8174_spb0 vsan 50 + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azukronp1_f00 vsan 50 + pwwn c0:50:76:09:5b:20:00:2e [azukronp1_f00] + + zone name z50_azpups01_f2_unity8174_spb0 vsan 50 + fcalias name azseunty8174_SPB0 vsan 50 + pwwn 50:06:01:68:47:e4:22:97 [azseunty1773_SPB0] + + fcalias name azupsp1_f2 vsan 50 + pwwn c0:50:76:09:5b:20:00:1e [azupsp1_f2] + + zone name z50_azucdrsr1_f2_unity1773_spb2 vsan 50 + fcalias name azseunty8174_SPB2 vsan 50 + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + fcalias name azucdrsr1_f2 vsan 50 + pwwn c0:50:76:09:5b:20:00:40 [azucdrsr1_f2] + + zone name z50_azuepicclarp1_f0_unity8174_spa3 vsan 50 + fcalias name azseunty8174_SPA3 vsan 50 + pwwn 50:06:01:63:47:e4:22:97 [azseunty1773_SPA3] + + fcalias name azuepicclarp1_f0 vsan 50 + pwwn c0:50:76:09:5b:20:00:50 [azuepicclarp1_f0] + + zone name z50_azuepicclarp1_f2_unity8174_spb2 vsan 50 + fcalias name azseunty8174_SPB2 vsan 50 + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] + + fcalias name azuepicclarp1_f2 vsan 50 + pwwn c0:50:76:09:5b:20:00:54 [azuepicclarp1_f2] + + zone name z50_azpwovd01_A001_8174_spb_iom_1_fc2 vsan 50 + pwwn 20:ff:00:25:b5:a2:a0:01 [azpwovd01_f0] + pwwn 50:06:01:6a:47:e4:22:97 [azseunty1773_SPB2] diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzone_0.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzone_0.cfg new file mode 100644 index 00000000..5ac63da9 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzone_0.cfg @@ -0,0 +1,7 @@ +zone name zoneA vsan 923 + pwwn 11:11:11:11:11:11:11:11 + device-alias test123 + +zone name zoneB vsan 923 + pwwn 10:11:11:11:11:11:11:11 + pwwn 62:62:62:62:21:21:21:21 diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzone_1.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzone_1.cfg new file mode 100644 index 00000000..ecd5b285 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzone_1.cfg @@ -0,0 +1,7 @@ +zone name zoneA vsan 922 + pwwn 11:11:11:11:11:11:11:11 + device-alias test123 both + +zone name zoneB vsan 922 + pwwn 10:11:11:11:11:11:11:11 + pwwn 62:62:62:62:21:21:21:21 diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzone_2.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzone_2.cfg new file mode 100644 index 00000000..530266d4 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzone_2.cfg @@ -0,0 +1,6 @@ +zone name zv221 vsan 221 + pwwn 21:01:00:1b:32:a1:c0:a8 [h181-dell-linux-top-p2] + pwwn 10:00:00:90:fa:c7:da:42 [h172-32ghost-p2] + pwwn 21:01:00:1b:32:aa:50:4b [h190-dell-linux-top-p2] + pwwn 50:06:01:6a:47:e4:6e:59 [VNX_UNITY_235_SPB-1-2] + pwwn 21:01:00:1b:32:aa:ff:4a [h189-dell-windows-bottom-p2] diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzone_bug339.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzone_bug339.cfg new file mode 100644 index 00000000..42517097 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzone_bug339.cfg @@ -0,0 +1,5 @@ +zone name SZ-WLD-IAAS1-HUABVA07 vsan 100 + pwwn 20:00:00:25:b5:10:a0:00 [P011W01ILBEX001-H0] init + pwwn 20:00:00:25:b5:10:a0:01 [P011W01ILBEX002-H0] init + pwwn 20:00:00:25:b5:10:a0:02 [P011W01ILBEX003-H0] init + pwwn 20:00:00:25:b5:10:a0:03 [P011W01ILBEX004-H0] init diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzoneset_0.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzoneset_0.cfg new file mode 100644 index 00000000..661b6729 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzoneset_0.cfg @@ -0,0 +1,9 @@ +zoneset name zsetname21 vsan 922 + zone name zone21A vsan 922 + pwwn 11:11:11:11:11:11:11:11 both + pwwn 62:62:62:62:12:12:12:12 + + zone name zone21B vsan 922 + pwwn 10:11:11:11:11:11:11:11 + pwwn 62:62:62:62:21:21:21:21 + device-alias somedummyname diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzoneset_1.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzoneset_1.cfg new file mode 100644 index 00000000..4d6fe470 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzoneset_1.cfg @@ -0,0 +1,8 @@ +zoneset name zsetname1 vsan 923 + zone name zoneA vsan 923 + pwwn 11:11:11:11:11:11:11:11 + device-alias test123 + + zone name zoneB vsan 923 + pwwn 10:11:11:11:11:11:11:11 + pwwn 62:62:62:62:21:21:21:21 diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzoneset_2.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzoneset_2.cfg new file mode 100644 index 00000000..923f54e4 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzoneset_2.cfg @@ -0,0 +1,7 @@ +zoneset name zsv221 vsan 221 + zone name zv221 vsan 221 + pwwn 21:01:00:1b:32:a1:c0:a8 [h181-dell-linux-top-p2] + pwwn 10:00:00:90:fa:c7:da:42 [h172-32ghost-p2] + pwwn 21:01:00:1b:32:aa:50:4b [h190-dell-linux-top-p2] + pwwn 50:06:01:6a:47:e4:6e:59 [VNX_UNITY_235_SPB-1-2] + pwwn 21:01:00:1b:32:aa:ff:4a [h189-dell-windows-bottom-p2] diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzonesetactive_0.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzonesetactive_0.cfg new file mode 100644 index 00000000..3db199ae --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzonesetactive_0.cfg @@ -0,0 +1,7 @@ +zoneset name zsv221 vsan 221 + zone name zv221 vsan 221 + * fcid 0x2f0000 [pwwn 21:01:00:1b:32:a1:c0:a8] [h181-dell-linux-top-p2] + * fcid 0xa90000 [pwwn 10:00:00:90:fa:c7:da:42] [h172-32ghost-p2] + * fcid 0xd50000 [pwwn 21:01:00:1b:32:aa:50:4b] [h190-dell-linux-top-p2] + * fcid 0xde0000 [pwwn 50:06:01:6a:47:e4:6e:59] [VNX_UNITY_235_SPB-1-2] + pwwn 21:01:00:1b:32:aa:ff:4a [h189-dell-windows-bottom-p2] diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzonestatus_0.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzonestatus_0.cfg new file mode 100644 index 00000000..b253ac3f --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzonestatus_0.cfg @@ -0,0 +1,21 @@ +VSAN: 922 default-zone: deny distribute: active only Interop: default + mode: basic merge-control: allow + session: none + hard-zoning: enabled broadcast: unsupported + smart-zoning: enabled + rscn-format: fabric-address + activation overwrite control: disabled +Default zone: + qos: none broadcast: unsupported ronly: unsupported +Full Zoning Database : + DB size: 358 bytes + Zonesets: 1 Zones: 2 Aliases: 0 +Active Zoning Database : + DB Size: 125 bytes + Name: zsetname21 Zonesets: 1 Zones: 2 +Current Total Zone DB Usage: 483 / 2097152 bytes (0 % used) +Pending (Session) DB size: + Full DB Copy size: n/a + Active DB Copy size: n/a +SFC size: 483 / 2097152 bytes (0 % used) +Status: Activation completed at 23:50:35 IST Jul 3 2019 diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzonestatus_1.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzonestatus_1.cfg new file mode 100644 index 00000000..ed5dd055 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzonestatus_1.cfg @@ -0,0 +1,21 @@ +VSAN: 922 default-zone: deny distribute: full Interop: default + mode: enhanced merge-control: allow + session: none + hard-zoning: enabled broadcast: unsupported + smart-zoning: disabled + rscn-format: fabric-address + activation overwrite control: disabled +Default zone: + qos: none broadcast: unsupported ronly: unsupported +Full Zoning Database : + DB size: 376 bytes + Zonesets: 1 Zones: 2 Aliases: 0 Attribute-groups: 1 +Active Zoning Database : + DB Size: 156 bytes + Name: zsetname21 Zonesets: 1 Zones: 2 +Current Total Zone DB Usage: 532 / 2097152 bytes (0 % used) +Pending (Session) DB size: + Full DB Copy size: 0 bytes + Active DB Copy size: 0 bytes +SFC size: 0 / 2097152 bytes (0 % used) +Status: Set zoning mode complete at 10:19:02 IST Jul 5 2019 diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzonestatus_2.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzonestatus_2.cfg new file mode 100644 index 00000000..5d4dc788 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzonestatus_2.cfg @@ -0,0 +1,22 @@ +VSAN: 923 default-zone: permit distribute: full Interop: default + mode: enhanced merge-control: allow + session: none + hard-zoning: enabled broadcast: unsupported + smart-zoning: disabled + rscn-format: fabric-address + activation overwrite control: disabled +Default zone: + qos: none broadcast: unsupported ronly: unsupported +Full Zoning Database : + DB size: 356 bytes + Zonesets: 1 Zones: 2 Aliases: 0 Attribute-groups: 1 +Active Zoning Database : + DB Size: 136 bytes + Name: zsetname1 Zonesets: 1 Zones: 2 +Current Total Zone DB Usage: 492 / 2097152 bytes (0 % used) +Pending (Session) DB size: + Full DB Copy size: 0 bytes + Active DB Copy size: 0 bytes +SFC size: 0 / 2097152 bytes (0 % used) +Status: Operation failed: [Error: WARNING: Specified zoneset already active and unchanged]: + at 11:06:21 IST Jul 5 2019 diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzonestatus_3.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzonestatus_3.cfg new file mode 100644 index 00000000..931a3f1f --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzonestatus_3.cfg @@ -0,0 +1,22 @@ +VSAN: 923 default-zone: permit distribute: full Interop: default + mode: basic merge-control: allow + session: none + hard-zoning: enabled broadcast: unsupported + smart-zoning: disabled + rscn-format: fabric-address + activation overwrite control: disabled +Default zone: + qos: none broadcast: unsupported ronly: unsupported +Full Zoning Database : + DB size: 356 bytes + Zonesets: 1 Zones: 2 Aliases: 0 Attribute-groups: 1 +Active Zoning Database : + DB Size: 136 bytes + Name: zsetname1 Zonesets: 1 Zones: 2 +Current Total Zone DB Usage: 492 / 2097152 bytes (0 % used) +Pending (Session) DB size: + Full DB Copy size: 0 bytes + Active DB Copy size: 0 bytes +SFC size: 0 / 2097152 bytes (0 % used) +Status: Operation failed: [Error: WARNING: Specified zoneset already active and unchanged]: + at 11:06:21 IST Jul 5 2019 diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzonestatus_4.cfg b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzonestatus_4.cfg new file mode 100644 index 00000000..8529d05f --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/fixtures/nxos_zone_zoneset/shzonestatus_4.cfg @@ -0,0 +1,21 @@ +VSAN: 221 default-zone: deny distribute: full Interop: default + mode: enhanced merge-control: allow + session: none + hard-zoning: enabled broadcast: unsupported + smart-zoning: disabled + rscn-format: fabric-address + activation overwrite control: disabled +Default zone: + qos: none broadcast: unsupported ronly: unsupported +Full Zoning Database : + DB size: 300 bytes + Zonesets: 1 Zones: 1 Aliases: 0 Attribute-groups: 1 +Active Zoning Database : + DB Size: 112 bytes + Name: zsv221 Zonesets: 1 Zones: 1 +Current Total Zone DB Usage: 412 / 2097152 bytes (0 % used) +Pending (Session) DB size: + Full DB Copy size: 0 bytes + Active DB Copy size: 0 bytes +SFC size: 0 / 2097152 bytes (0 % used) +Status: diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/nxos_module.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/nxos_module.py new file mode 100644 index 00000000..99e324da --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/nxos_module.py @@ -0,0 +1,128 @@ +# (c) 2016 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +import json +import os + +from ansible_collections.cisco.nxos.tests.unit.modules.utils import ( + AnsibleExitJson, + AnsibleFailJson, + ModuleTestCase, +) +from ansible_collections.cisco.nxos.tests.unit.modules.utils import ( + set_module_args as _set_module_args, +) + + +def set_module_args(args, ignore_provider=None): + return _set_module_args(args) + + +fixture_path = os.path.join(os.path.dirname(__file__), "fixtures") +fixture_data = {} + + +def load_fixture(module_name, name, device=""): + path = os.path.join(fixture_path, module_name, device, name) + if not os.path.exists(path): + path = os.path.join(fixture_path, module_name, name) + + if path in fixture_data: + return fixture_data[path] + + with open(path) as f: + data = f.read() + + try: + data = json.loads(data) + except Exception: + pass + + fixture_data[path] = data + return data + + +class TestNxosModule(ModuleTestCase): + def execute_module_devices( + self, + failed=False, + changed=False, + commands=None, + sort=True, + defaults=False, + ): + module_name = self.module.__name__.rsplit(".", 1)[1] + local_fixture_path = os.path.join(fixture_path, module_name) + + models = [] + for path in os.listdir(local_fixture_path): + path = os.path.join(local_fixture_path, path) + if os.path.isdir(path): + models.append(os.path.basename(path)) + if not models: + models = [""] + + retvals = {} + for model in models: + retvals[model] = self.execute_module(failed, changed, commands, sort, device=model) + + return retvals + + def execute_module(self, failed=False, changed=False, commands=None, sort=True, device=""): + self.load_fixtures(commands, device=device) + + if failed: + result = self.failed() + self.assertTrue(result["failed"], result) + else: + result = self.changed(changed) + self.assertEqual(result["changed"], changed, result) + if commands is not None and len(commands) > 0: + if sort: + self.assertEqual( + sorted(commands), + sorted(result["commands"]), + result["commands"], + ) + else: + self.assertEqual(commands, result["commands"], result["commands"]) + + return result + + def failed(self): + with self.assertRaises(AnsibleFailJson) as exc: + self.module.main() + result = exc.exception.args[0] + self.assertTrue(result["failed"], result) + return result + + def changed(self, changed=False): + with self.assertRaises(AnsibleExitJson) as exc: + self.module.main() + + result = exc.exception.args[0] + self.assertEqual(result["changed"], changed, result) + return result + + def load_fixtures(self, commands=None, device=""): + pass diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/storage/__init__.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/storage/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/storage/__init__.py diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/storage/test_nxos_devicealias.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/storage/test_nxos_devicealias.py new file mode 100644 index 00000000..a35896fb --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/storage/test_nxos_devicealias.py @@ -0,0 +1,384 @@ +#!/usr/bin/env python +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +import pytest + +from ansible_collections.cisco.nxos.plugins.modules.storage import nxos_devicealias +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch +from ansible_collections.cisco.nxos.tests.unit.modules.utils import AnsibleFailJson + +from ..nxos_module import TestNxosModule, load_fixture, set_module_args + + +class TestNxosDeviceAliasModule(TestNxosModule): + module = nxos_devicealias + + def setUp(self): + super(TestNxosDeviceAliasModule, self).setUp() + module_path = "ansible_collections.cisco.nxos.plugins.modules.storage.nxos_devicealias." + + self.mock_run_commands = patch(module_path + "run_commands") + self.run_commands = self.mock_run_commands.start() + + self.mock_execute_show_cmd = patch(module_path + "showDeviceAliasStatus.execute_show_cmd") + self.execute_show_cmd = self.mock_execute_show_cmd.start() + + self.mock_execute_show_cmd_1 = patch( + module_path + "showDeviceAliasDatabase.execute_show_cmd", + ) + self.execute_show_cmd_1 = self.mock_execute_show_cmd_1.start() + + self.mock_load_config = patch(module_path + "load_config") + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestNxosDeviceAliasModule, self).tearDown() + self.mock_run_commands.stop() + self.mock_execute_show_cmd.stop() + self.mock_execute_show_cmd_1.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, device=""): + self.load_config.return_value = None + + def test_da_mode_1(self): + # Playbook mode is basic + # Switch has mode as enahnced + set_module_args(dict(mode="basic"), True) + self.execute_show_cmd.return_value = load_fixture("nxos_devicealias", "shdastatus.cfg") + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "terminal dont-ask", + "no device-alias mode enhanced", + "device-alias commit", + "no terminal dont-ask", + ], + ) + + def test_da_mode_2(self): + # Playbook mode is enhanced + # Switch has mode as enahnced + set_module_args(dict(mode="enhanced"), True) + self.execute_show_cmd.return_value = load_fixture("nxos_devicealias", "shdastatus.cfg") + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_da_distribute_1(self): + # Playbook mode is enhanced , distrbute = True + # Switch has mode as enahnced, distrbute = True + set_module_args(dict(distribute=True, mode="enhanced"), True) + self.execute_show_cmd.return_value = load_fixture("nxos_devicealias", "shdastatus.cfg") + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_da_distribute_2(self): + # Playbook mode is enhanced , distrbute = False + # Switch has mode as enhanced, distrbute = True + set_module_args(dict(distribute=False, mode="enhanced"), True) + self.execute_show_cmd.return_value = load_fixture("nxos_devicealias", "shdastatus.cfg") + result = self.execute_module(changed=True) + self.assertEqual(result["commands"], ["no device-alias distribute"]) + + def test_da_distribute_3(self): + # Playbook mode is basic , distrbute = False + # Switch has mode as enahnced, distrbute = True + set_module_args(dict(distribute=False, mode="basic"), True) + self.execute_show_cmd.return_value = load_fixture("nxos_devicealias", "shdastatus.cfg") + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + ["no device-alias distribute", "no device-alias mode enhanced"], + ) + + def test_da_add_1(self): + # Playbook mode is enhanced , distrbute = true , some new da being added + # Switch has mode as enahnced, distrbute = True, switch doesnt have the new da being added + set_module_args( + dict( + distribute=True, + mode="enhanced", + da=[ + dict(name="somename", pwwn="10:00:00:00:89:a1:01:03"), + dict(name="somename1", pwwn="10:00:00:00:89:a1:02:03"), + ], + ), + True, + ) + self.execute_show_cmd.return_value = load_fixture("nxos_devicealias", "shdastatus.cfg") + self.execute_show_cmd_1.return_value = load_fixture("nxos_devicealias", "shdadatabse.cfg") + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "terminal dont-ask", + "device-alias database", + "device-alias name somename pwwn 10:00:00:00:89:a1:01:03", + "device-alias name somename1 pwwn 10:00:00:00:89:a1:02:03", + "device-alias commit", + "no terminal dont-ask", + ], + ) + + def test_da_add_2(self): + # Playbook mode is enhanced , distrbute = true , some new da being added + # Switch has mode as enahnced, distrbute = True, switch already has the pwwn:name + set_module_args( + dict( + distribute=True, + mode="enhanced", + da=[dict(name="tieHost-2", pwwn="10:00:00:00:89:a1:01:02")], + ), + True, + ) + self.execute_show_cmd.return_value = load_fixture("nxos_devicealias", "shdastatus.cfg") + self.execute_show_cmd_1.return_value = load_fixture("nxos_devicealias", "shdadatabse.cfg") + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_da_add_3(self): + # Playbook mode is enhanced , distrbute = true , some new da being added + # Switch has mode as enahnced, distrbute = True, switch same name present with different pwwn + set_module_args( + dict( + distribute=True, + mode="enhanced", + da=[dict(name="tieHost-2", pwwn="10:00:00:00:89:a1:01:ff")], + ), + True, + ) + self.execute_show_cmd.return_value = load_fixture("nxos_devicealias", "shdastatus.cfg") + self.execute_show_cmd_1.return_value = load_fixture("nxos_devicealias", "shdadatabse.cfg") + result = self.execute_module(changed=False, failed=True) + + def test_da_add_4(self): + # Playbook mode is enhanced , distrbute = true , some new da being added + # Switch has mode as enahnced, distrbute = True, switch same pwwn present with different name + set_module_args( + dict( + distribute=True, + mode="enhanced", + da=[dict(name="tieHost-2222", pwwn="10:00:00:00:89:a1:01:02")], + ), + True, + ) + self.execute_show_cmd.return_value = load_fixture("nxos_devicealias", "shdastatus.cfg") + self.execute_show_cmd_1.return_value = load_fixture("nxos_devicealias", "shdadatabse.cfg") + result = self.execute_module(changed=False, failed=True) + + def test_da_remove_1(self): + # Playbook mode is enhanced , distrbute = true , some da being removed + # Switch has mode as enahnced, distrbute = True, switch has the da that needs to be removed + set_module_args( + dict( + distribute=True, + mode="enhanced", + da=[ + dict( + name="tieHost-2", + pwwn="10:00:00:00:89:a1:01:02", + remove=True, + ), + ], + ), + True, + ) + self.execute_show_cmd.return_value = load_fixture("nxos_devicealias", "shdastatus.cfg") + self.execute_show_cmd_1.return_value = load_fixture("nxos_devicealias", "shdadatabse.cfg") + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "terminal dont-ask", + "device-alias database", + "no device-alias name tieHost-2", + "device-alias commit", + "no terminal dont-ask", + ], + ) + + def test_da_remove_2(self): + # Playbook mode is enhanced , distrbute = true , some da being removed + # Switch has mode as enahnced, distrbute = True, switch does NOT have the da that needs to be removed + set_module_args( + dict( + distribute=True, + mode="enhanced", + da=[ + dict( + name="somename", + pwwn="10:00:00:00:89:a1:01:02", + remove=True, + ), + ], + ), + True, + ) + self.execute_show_cmd.return_value = load_fixture("nxos_devicealias", "shdastatus.cfg") + self.execute_show_cmd_1.return_value = load_fixture("nxos_devicealias", "shdadatabse.cfg") + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_da_lock(self): + # Playbook mode with some data, but switch has cfs lock acq + set_module_args( + dict( + distribute=True, + mode="enhanced", + da=[ + dict( + name="somename", + pwwn="10:00:00:00:89:a1:01:02", + remove=True, + ), + ], + ), + True, + ) + self.execute_show_cmd.return_value = load_fixture("nxos_devicealias", "shdastatuslock.cfg") + self.execute_module(failed=True) + + def test_da_paramete_not_supported(self): + # Playbook mode with some data, but switch has cfs lock acq + # the below one instead of 'mode' we are passing 'mod', kind of typo in playbook + set_module_args( + dict( + distribute=True, + mod="enhanced", + da=[ + dict( + name="somename", + pwwn="10:00:00:00:89:a1:01:02", + remove=True, + ), + ], + ), + True, + ) + self.execute_show_cmd.return_value = load_fixture("nxos_devicealias", "shdastatus.cfg") + self.execute_show_cmd_1.return_value = load_fixture("nxos_devicealias", "shdadatabse.cfg") + with pytest.raises(AnsibleFailJson) as errinfo: + self.execute_module() + testdata = errinfo.value.args[0] + assert "Unsupported parameters" in str(testdata["msg"]) + assert testdata["failed"] + + def test_da_name_parameter_missing(self): + # Lets say you are trying to add a device alias but forgot to put 'name' in the 'da' parameter + set_module_args( + dict( + distribute=True, + mode="enhanced", + da=[dict(pwwn="10:00:00:00:89:a1:01:02")], + ), + True, + ) + self.execute_show_cmd.return_value = load_fixture("nxos_devicealias", "shdastatus.cfg") + self.execute_show_cmd_1.return_value = load_fixture("nxos_devicealias", "shdadatabse.cfg") + with pytest.raises(AnsibleFailJson) as errinfo: + self.execute_module() + testdata = errinfo.value.args[0] + assert "missing required arguments" in str(testdata["msg"]) + assert testdata["failed"] + + def test_da_rename_1(self): + # rename works + set_module_args( + dict( + rename=[ + dict(old_name="test1_add", new_name="test234"), + dict(old_name="tieHost-1", new_name="tieTarget-1"), + ], + ), + True, + ) + self.execute_show_cmd.return_value = load_fixture("nxos_devicealias", "shdastatus.cfg") + self.execute_show_cmd_1.return_value = load_fixture("nxos_devicealias", "shdadatabse.cfg") + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "terminal dont-ask", + "device-alias database", + "device-alias rename test1_add test234", + "device-alias rename tieHost-1 tieTarget-1", + "device-alias commit", + "no terminal dont-ask", + ], + ) + + def test_da_rename_2(self): + # rename : oldname not present + set_module_args( + dict( + rename=[ + dict(old_name="test1", new_name="test234"), + dict(old_name="tie", new_name="tieTarget-1"), + ], + ), + True, + ) + self.execute_show_cmd.return_value = load_fixture("nxos_devicealias", "shdastatus.cfg") + self.execute_show_cmd_1.return_value = load_fixture("nxos_devicealias", "shdadatabse.cfg") + result = self.execute_module(changed=False, failed=True) + self.assertEqual(result["commands"], []) + + def test_da_mansi(self): + set_module_args({"distribute": True, "mode": "enhanced"}, True) + self.execute_show_cmd.return_value = load_fixture( + "nxos_devicealias", + "shdastatus_mansi.cfg", + ) + self.execute_show_cmd_1.return_value = load_fixture("nxos_devicealias", "shdadatabse.cfg") + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "device-alias distribute", + "terminal dont-ask", + "device-alias mode enhanced", + "device-alias commit", + "no terminal dont-ask", + ], + ) + + def test_da_add_bad(self): + # Playbook mode is enhanced , distrbute = true , some new da being added + # Switch has mode as enahnced, distrbute = True, switch doesnt have the new da being added + set_module_args( + dict( + distribute=True, + mode="enhanced", + da=[dict(name="*somename*", pwwn="10:00:00:00:89:a1:01:03")], + ), + True, + ) + self.execute_show_cmd.return_value = load_fixture("nxos_devicealias", "shdastatus.cfg") + self.execute_show_cmd_1.return_value = load_fixture("nxos_devicealias", "shdadatabse.cfg") + + result = self.execute_module(changed=False, failed=True) + assert "it must start with a letter" in str(result["msg"]) + + def test_da_add_bad_1(self): + # Playbook mode is enhanced , distrbute = true , some new da being added + # Switch has mode as enahnced, distrbute = True, switch doesnt have the new da being added + set_module_args( + dict( + distribute=True, + mode="enhanced", + da=[dict(name="somename*", pwwn="10:00:00:00:89:a1:01:03")], + ), + True, + ) + self.execute_show_cmd.return_value = load_fixture("nxos_devicealias", "shdastatus.cfg") + self.execute_show_cmd_1.return_value = load_fixture("nxos_devicealias", "shdadatabse.cfg") + + result = self.execute_module(changed=False, failed=True) + assert "and can only contain these characters" in str(result["msg"]) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/storage/test_nxos_vsan.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/storage/test_nxos_vsan.py new file mode 100644 index 00000000..db79f866 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/storage/test_nxos_vsan.py @@ -0,0 +1,214 @@ +#!/usr/bin/env python +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +import pytest + +from ansible_collections.cisco.nxos.plugins.modules.storage import nxos_vsan +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch +from ansible_collections.cisco.nxos.tests.unit.modules.utils import AnsibleFailJson + +from ..nxos_module import TestNxosModule, load_fixture, set_module_args + + +class TestNxosVsanModule(TestNxosModule): + module = nxos_vsan + + def setUp(self): + super(TestNxosVsanModule, self).setUp() + module_path = "ansible_collections.cisco.nxos.plugins.modules.storage.nxos_vsan." + + self.mock_run_commands = patch(module_path + "run_commands") + self.run_commands = self.mock_run_commands.start() + + self.mock_execute_show_vsan_cmd = patch( + module_path + "GetVsanInfoFromSwitch.execute_show_vsan_cmd", + ) + self.execute_show_vsan_cmd = self.mock_execute_show_vsan_cmd.start() + + self.mock_execute_show_vsanmemcmd = patch( + module_path + "GetVsanInfoFromSwitch.execute_show_vsan_mem_cmd", + ) + self.execute_show_vsanmem_cmd = self.mock_execute_show_vsanmemcmd.start() + + self.mock_load_config = patch(module_path + "load_config") + self.load_config = self.mock_load_config.start() + + self.maxDiff = None + + def tearDown(self): + super(TestNxosVsanModule, self).tearDown() + self.mock_run_commands.stop() + self.execute_show_vsan_cmd.stop() + self.execute_show_vsanmem_cmd.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, device=""): + self.load_config.return_value = None + + def test_vsan_add_remove_but_present_in_switch(self): + margs = { + "vsan": [ + { + "interface": ["fc1/1", "port-channel 55"], + "id": 922, + "remove": False, + "name": "vsan-SAN-A", + }, + { + "interface": ["fc1/11", "fc1/21", "port-channel 56"], + "id": 923, + "remove": False, + "name": "vsan-SAN-B", + }, + {"id": 1923, "remove": True, "name": "vsan-SAN-Old"}, + ], + } + set_module_args(margs, True) + self.execute_show_vsan_cmd.return_value = load_fixture("nxos_vsan", "shvsan.cfg") + self.execute_show_vsanmem_cmd.return_value = load_fixture("nxos_vsan", "shvsanmem.cfg") + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_vsan_remove(self): + margs = {"vsan": [{"id": 922, "remove": True}, {"id": 923, "remove": True}]} + set_module_args(margs, True) + self.execute_show_vsan_cmd.return_value = load_fixture("nxos_vsan", "shvsan.cfg") + self.execute_show_vsanmem_cmd.return_value = load_fixture("nxos_vsan", "shvsanmem.cfg") + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + ["terminal dont-ask"] + + ["vsan database"] + + ["no vsan 922", "no vsan 923"] + + ["no terminal dont-ask"], + ) + + def test_vsan_add(self): + margs = { + "vsan": [ + { + "interface": ["fc1/1", "port-channel 55"], + "id": 924, + "name": "vsan-SAN-924", + }, + { + "interface": ["fc1/11", "fc1/21", "port-channel 56"], + "id": 925, + "name": "vsan-SAN-925", + }, + ], + } + set_module_args(margs, True) + self.execute_show_vsan_cmd.return_value = load_fixture("nxos_vsan", "shvsan.cfg") + self.execute_show_vsanmem_cmd.return_value = load_fixture("nxos_vsan", "shvsanmem.cfg") + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + ["terminal dont-ask"] + + ["vsan database"] + + [ + "vsan 924", + "vsan 924 name vsan-SAN-924", + "no vsan 924 suspend", + "vsan 924 interface fc1/1", + "vsan 924 interface port-channel 55", + ] + + [ + "vsan 925", + "vsan 925 name vsan-SAN-925", + "no vsan 925 suspend", + "vsan 925 interface fc1/11", + "vsan 925 interface fc1/21", + "vsan 925 interface port-channel 56", + ] + + ["no terminal dont-ask"], + ) + + def test_vsan_suspend(self): + margs = { + "vsan": [ + { + "interface": ["fc1/1", "port-channel 55"], + "id": 924, + "name": "vsan-SAN-924", + }, + {"id": 925, "name": "vsan-SAN-925", "suspend": True}, + ], + } + set_module_args(margs, True) + self.execute_show_vsan_cmd.return_value = load_fixture("nxos_vsan", "shvsan.cfg") + self.execute_show_vsanmem_cmd.return_value = load_fixture("nxos_vsan", "shvsanmem.cfg") + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + ["terminal dont-ask"] + + ["vsan database"] + + [ + "vsan 924", + "vsan 924 name vsan-SAN-924", + "no vsan 924 suspend", + "vsan 924 interface fc1/1", + "vsan 924 interface port-channel 55", + ] + + ["vsan 925", "vsan 925 name vsan-SAN-925", "vsan 925 suspend"] + + ["no terminal dont-ask"], + ) + + def test_vsan_invalid_vsan(self): + margs = {"vsan": [{"id": 4096, "name": "vsan-SAN-925", "suspend": True}]} + set_module_args(margs, True) + self.execute_show_vsan_cmd.return_value = load_fixture("nxos_vsan", "shvsan.cfg") + self.execute_show_vsanmem_cmd.return_value = load_fixture("nxos_vsan", "shvsanmem.cfg") + with pytest.raises(AnsibleFailJson) as errinfo: + self.execute_module() + testdata = errinfo.value.args[0] + assert "invalid vsan" in str(testdata["msg"]) + assert testdata["failed"] + + def test_vsan_change_reserved_vsan(self): + margs = {"vsan": [{"id": 4094, "name": "vsan-SAN-925", "suspend": True}]} + set_module_args(margs, True) + self.execute_show_vsan_cmd.return_value = load_fixture("nxos_vsan", "shvsan.cfg") + self.execute_show_vsanmem_cmd.return_value = load_fixture("nxos_vsan", "shvsanmem.cfg") + result = self.execute_module(changed=False) + assert "reserved vsan" in str(result["messages"]) + self.assertEqual(result["commands"], []) + + def test_vsan_add_int_existing_vsan(self): + margs = { + "vsan": [ + { + "interface": ["fc1/1", "fc1/40", "port-channel 155"], + "id": 922, + }, + ], + } + set_module_args(margs, True) + self.execute_show_vsan_cmd.return_value = load_fixture("nxos_vsan", "shvsan.cfg") + self.execute_show_vsanmem_cmd.return_value = load_fixture("nxos_vsan", "shvsanmem.cfg") + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + ["terminal dont-ask"] + + ["vsan database"] + + [ + "vsan 922 interface fc1/40", + "vsan 922 interface port-channel 155", + ] + + ["no terminal dont-ask"], + ) + + def test_vsan_remove_non_existing_vsan(self): + margs = {"vsan": [{"id": 1111, "remove": True}]} + set_module_args(margs, True) + self.execute_show_vsan_cmd.return_value = load_fixture("nxos_vsan", "shvsan.cfg") + self.execute_show_vsanmem_cmd.return_value = load_fixture("nxos_vsan", "shvsanmem.cfg") + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + assert "no vsan" in str(result["messages"]) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/storage/test_nxos_zone_zoneset.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/storage/test_nxos_zone_zoneset.py new file mode 100644 index 00000000..b49dbf2f --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/storage/test_nxos_zone_zoneset.py @@ -0,0 +1,785 @@ +#!/usr/bin/env python +# Copyright: Ansible Project +# GNU General Public License v3.0+ (see COPYING or +# https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from ansible_collections.cisco.nxos.plugins.modules.storage import nxos_zone_zoneset +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from ..nxos_module import TestNxosModule, load_fixture, set_module_args + + +class TestNxosZoneZonesetModule(TestNxosModule): + module = nxos_zone_zoneset + + def setUp(self): + super(TestNxosZoneZonesetModule, self).setUp() + module_path = "ansible_collections.cisco.nxos.plugins.modules.storage.nxos_zone_zoneset." + + self.mock_run_commands = patch(module_path + "run_commands") + self.run_commands = self.mock_run_commands.start() + + self.mock_execute_show_cmd_zoneset_active = patch( + module_path + "ShowZonesetActive.execute_show_zoneset_active_cmd", + ) + self.execute_show_cmd_zoneset_active = self.mock_execute_show_cmd_zoneset_active.start() + + self.mock_execute_show_cmd_zoneset = patch( + module_path + "ShowZoneset.execute_show_zoneset_cmd", + ) + self.execute_show_cmd_zoneset = self.mock_execute_show_cmd_zoneset.start() + + self.mock_execute_show_cmd_zone = patch(module_path + "ShowZone.execute_show_zone_vsan_cmd") + self.execute_show_cmd_zone = self.mock_execute_show_cmd_zone.start() + + self.mock_execute_show_cmd_zone_status = patch( + module_path + "ShowZoneStatus.execute_show_zone_status_cmd", + ) + self.execute_show_cmd_zone_status = self.mock_execute_show_cmd_zone_status.start() + + self.mock_load_config = patch(module_path + "load_config") + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestNxosZoneZonesetModule, self).tearDown() + self.mock_run_commands.stop() + + self.execute_show_cmd_zoneset_active.stop() + self.execute_show_cmd_zoneset.stop() + self.execute_show_cmd_zone.stop() + self.execute_show_cmd_zone_status.stop() + + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, device=""): + self.load_config.return_value = None + + # Test def zone from deny to permit and vice versa + def test_zone_defzone_deny_to_permit(self): + # switch has def-zone deny and mode basic + a = dict(zone_zoneset_details=[dict(vsan=922, default_zone="permit")]) + set_module_args(a, True) + self.execute_show_cmd_zone_status.return_value = load_fixture( + "nxos_zone_zoneset", + "shzonestatus_0.cfg", + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "terminal dont-ask", + "zone default-zone permit vsan 922", + "no terminal dont-ask", + ], + ) + + def test_zone_defzone_deny_to_permit_1(self): + # switch has def-zone deny and mode enhanced + a = dict(zone_zoneset_details=[dict(vsan=922, default_zone="permit")]) + set_module_args(a, True) + self.execute_show_cmd_zone_status.return_value = load_fixture( + "nxos_zone_zoneset", + "shzonestatus_1.cfg", + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "terminal dont-ask", + "zone default-zone permit vsan 922", + "zone commit vsan 922", + "no terminal dont-ask", + ], + ) + + def test_zone_defzone_permit_to_deny_1(self): + # switch has def-zone deny and mode enhanced + a = dict(zone_zoneset_details=[dict(vsan=923, default_zone="deny")]) + set_module_args(a, True) + self.execute_show_cmd_zone_status.return_value = load_fixture( + "nxos_zone_zoneset", + "shzonestatus_2.cfg", + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "terminal dont-ask", + "no zone default-zone permit vsan 923", + "zone commit vsan 923", + "no terminal dont-ask", + ], + ) + + def test_zone_defzone_permit_to_deny_2(self): + # switch has def-zone deny and mode enhanced + a = dict(zone_zoneset_details=[dict(vsan=923, default_zone="deny")]) + set_module_args(a, True) + self.execute_show_cmd_zone_status.return_value = load_fixture( + "nxos_zone_zoneset", + "shzonestatus_3.cfg", + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "terminal dont-ask", + "no zone default-zone permit vsan 923", + "no terminal dont-ask", + ], + ) + + # Test zone mode from basic to enhanced and vice versa + def test_zone_mode_basic_to_enh(self): + # switch has def-zone deny and mode basic + a = dict(zone_zoneset_details=[dict(vsan=922, mode="enhanced")]) + set_module_args(a, True) + self.execute_show_cmd_zone_status.return_value = load_fixture( + "nxos_zone_zoneset", + "shzonestatus_0.cfg", + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "terminal dont-ask", + "zone mode enhanced vsan 922", + "zone commit vsan 922", + "no terminal dont-ask", + ], + ) + + # Test zone mode from basic to enhanced and vice versa + def test_zone_mode_basic_to_enh_1(self): + # switch has def-zone deny and mode basic + a = dict(zone_zoneset_details=[dict(vsan=922, mode="basic")]) + set_module_args(a, True) + self.execute_show_cmd_zone_status.return_value = load_fixture( + "nxos_zone_zoneset", + "shzonestatus_1.cfg", + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "terminal dont-ask", + "no zone mode enhanced vsan 922", + "no terminal dont-ask", + ], + ) + + # Test zone smart-zone from enabled to disabled and vice versa + def test_zone_smart_zone(self): + # switch has def-zone deny and mode basic + a = dict(zone_zoneset_details=[dict(vsan=922, smart_zoning=False)]) + set_module_args(a, True) + self.execute_show_cmd_zone_status.return_value = load_fixture( + "nxos_zone_zoneset", + "shzonestatus_0.cfg", + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "terminal dont-ask", + "no zone smart-zoning enable vsan 922", + "no terminal dont-ask", + ], + ) + + def test_zone_smart_zone_1(self): + # switch has def-zone deny and mode basic + a = dict(zone_zoneset_details=[dict(vsan=923, smart_zoning=True)]) + set_module_args(a, True) + self.execute_show_cmd_zone_status.return_value = load_fixture( + "nxos_zone_zoneset", + "shzonestatus_1.cfg", + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "terminal dont-ask", + "zone smart-zoning enable vsan 923", + "zone commit vsan 923", + "no terminal dont-ask", + ], + ) + + # Test zone add/removal + def test_zone_add_rem(self): + a = dict(zone_zoneset_details=[dict(vsan=923, zone=[dict(name="zoneB", remove=True)])]) + set_module_args(a, True) + self.execute_show_cmd_zone_status.return_value = load_fixture( + "nxos_zone_zoneset", + "shzonestatus_1.cfg", + ) + self.execute_show_cmd_zone.return_value = load_fixture("nxos_zone_zoneset", "shzone_0.cfg") + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "terminal dont-ask", + "no zone name zoneB vsan 923", + "zone commit vsan 923", + "no terminal dont-ask", + ], + ) + + def test_zone_add_rem_1(self): + a = dict(zone_zoneset_details=[dict(vsan=923, zone=[dict(name="zoneC", remove=True)])]) + set_module_args(a, True) + self.execute_show_cmd_zone_status.return_value = load_fixture( + "nxos_zone_zoneset", + "shzonestatus_1.cfg", + ) + self.execute_show_cmd_zone.return_value = load_fixture("nxos_zone_zoneset", "shzone_0.cfg") + result = self.execute_module(changed=False, failed=False) + m = "zone 'zoneC' is not present in vsan 923" + assert m in str(result["messages"]) + self.assertEqual(result["commands"], []) + + def test_zone_add_rem_2(self): + a = dict(zone_zoneset_details=[dict(vsan=923, zone=[dict(name="zoneBNew")])]) + set_module_args(a, True) + self.execute_show_cmd_zone_status.return_value = load_fixture( + "nxos_zone_zoneset", + "shzonestatus_1.cfg", + ) + self.execute_show_cmd_zone.return_value = load_fixture("nxos_zone_zoneset", "shzone_0.cfg") + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "terminal dont-ask", + "zone name zoneBNew vsan 923", + "zone commit vsan 923", + "no terminal dont-ask", + ], + ) + + def test_zone_add_rem_3(self): + a = dict(zone_zoneset_details=[dict(vsan=923, zone=[dict(name="zoneB")])]) + set_module_args(a, True) + self.execute_show_cmd_zone_status.return_value = load_fixture( + "nxos_zone_zoneset", + "shzonestatus_1.cfg", + ) + self.execute_show_cmd_zone.return_value = load_fixture("nxos_zone_zoneset", "shzone_0.cfg") + result = self.execute_module(changed=False, failed=False) + m = "zone 'zoneB' is already present in vsan 923" + assert m in str(result["messages"]) + self.assertEqual(result["commands"], []) + + # Test zone mem add/removal + def test_zonemem_add_rem(self): + mem1 = {"pwwn": "10:00:10:94:00:00:00:01"} + mem2 = {"device_alias": "somename"} + a = dict( + zone_zoneset_details=[ + dict( + vsan=923, + zone=[dict(name="zoneBNew", members=[mem1, mem2])], + ), + ], + ) + set_module_args(a, True) + self.execute_show_cmd_zone_status.return_value = load_fixture( + "nxos_zone_zoneset", + "shzonestatus_1.cfg", + ) + self.execute_show_cmd_zone.return_value = load_fixture("nxos_zone_zoneset", "shzone_0.cfg") + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "terminal dont-ask", + "zone name zoneBNew vsan 923", + "member pwwn 10:00:10:94:00:00:00:01", + "member device-alias somename", + "zone commit vsan 923", + "no terminal dont-ask", + ], + ) + + # Test zone mem add/removal + def test_zonemem_add_rem_1(self): + mem1 = {"pwwn": "11:11:11:11:11:11:11:11", "remove": True} + mem2 = {"device_alias": "test123", "remove": True} + a = dict( + zone_zoneset_details=[dict(vsan=923, zone=[dict(name="zoneA", members=[mem1, mem2])])], + ) + set_module_args(a, True) + self.execute_show_cmd_zone_status.return_value = load_fixture( + "nxos_zone_zoneset", + "shzonestatus_1.cfg", + ) + self.execute_show_cmd_zone.return_value = load_fixture("nxos_zone_zoneset", "shzone_0.cfg") + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "terminal dont-ask", + "zone name zoneA vsan 923", + "no member pwwn 11:11:11:11:11:11:11:11", + "no member device-alias test123", + "zone commit vsan 923", + "no terminal dont-ask", + ], + ) + + # Test zone mem add/removal + def test_zonemem_add_rem_2(self): + mem1 = {"pwwn": "11:11:11:11:11:11:11:11", "remove": True} + mem2 = {"device_alias": "test123", "remove": True} + a = dict( + zone_zoneset_details=[dict(vsan=923, zone=[dict(name="zoneA1", members=[mem1, mem2])])], + ) + set_module_args(a, True) + self.execute_show_cmd_zone_status.return_value = load_fixture( + "nxos_zone_zoneset", + "shzonestatus_1.cfg", + ) + self.execute_show_cmd_zone.return_value = load_fixture("nxos_zone_zoneset", "shzone_0.cfg") + result = self.execute_module(changed=False, failed=False) + m = "zone 'zoneA1' is not present in vsan 923 , hence cannot remove the members" + assert m in str(result["messages"]) + self.assertEqual(result["commands"], []) + + def test_zonemem_add_rem_3(self): + mem1 = {"pwwn": "10:00:10:94:00:00:00:01", "devtype": "initiator"} + mem2 = {"device_alias": "somename", "devtype": "target"} + mem3 = {"device_alias": "somenameWithBoth", "devtype": "both"} + + a = dict( + zone_zoneset_details=[ + dict( + vsan=922, + zone=[dict(name="zoneBNew", members=[mem1, mem2, mem3])], + ), + ], + ) + set_module_args(a, True) + self.execute_show_cmd_zone_status.return_value = load_fixture( + "nxos_zone_zoneset", + "shzonestatus_0.cfg", + ) + self.execute_show_cmd_zone.return_value = load_fixture("nxos_zone_zoneset", "shzone_1.cfg") + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "terminal dont-ask", + "zone name zoneBNew vsan 922", + "member pwwn 10:00:10:94:00:00:00:01 initiator", + "member device-alias somename target", + "member device-alias somenameWithBoth both", + "no terminal dont-ask", + ], + ) + + # Test zone mem add/removal with devtype + def test_zonemem_add_rem_4(self): + mem2 = {"device_alias": "test123", "devtype": "both", "remove": True} + + a = dict(zone_zoneset_details=[dict(vsan=922, zone=[dict(name="zoneA", members=[mem2])])]) + set_module_args(a, True) + self.execute_show_cmd_zone_status.return_value = load_fixture( + "nxos_zone_zoneset", + "shzonestatus_0.cfg", + ) + self.execute_show_cmd_zone.return_value = load_fixture("nxos_zone_zoneset", "shzone_1.cfg") + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "terminal dont-ask", + "zone name zoneA vsan 922", + "no member device-alias test123 both", + "no terminal dont-ask", + ], + ) + + # Test zoneset add/removal + def test_zoneset_add_rem(self): + a = dict( + zone_zoneset_details=[dict(vsan=922, zoneset=[dict(name="zsetname21", remove=True)])], + ) + set_module_args(a, True) + self.execute_show_cmd_zone_status.return_value = load_fixture( + "nxos_zone_zoneset", + "shzonestatus_0.cfg", + ) + self.execute_show_cmd_zoneset.return_value = load_fixture( + "nxos_zone_zoneset", + "shzoneset_0.cfg", + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "terminal dont-ask", + "no zoneset name zsetname21 vsan 922", + "no terminal dont-ask", + ], + ) + + def test_zoneset_add_rem_1(self): + a = dict(zone_zoneset_details=[dict(vsan=922, zoneset=[dict(name="zsetname21New")])]) + set_module_args(a, True) + self.execute_show_cmd_zone_status.return_value = load_fixture( + "nxos_zone_zoneset", + "shzonestatus_0.cfg", + ) + self.execute_show_cmd_zoneset.return_value = load_fixture( + "nxos_zone_zoneset", + "shzoneset_0.cfg", + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "terminal dont-ask", + "zoneset name zsetname21New vsan 922", + "no terminal dont-ask", + ], + ) + + def test_zoneset_add_rem_2(self): + a = dict(zone_zoneset_details=[dict(vsan=922, zoneset=[dict(name="zsetname21")])]) + set_module_args(a, True) + self.execute_show_cmd_zone_status.return_value = load_fixture( + "nxos_zone_zoneset", + "shzonestatus_0.cfg", + ) + self.execute_show_cmd_zoneset.return_value = load_fixture( + "nxos_zone_zoneset", + "shzoneset_0.cfg", + ) + result = self.execute_module(changed=False, failed=False) + m = "zoneset 'zsetname21' is already present in vsan 922" + self.assertEqual(result["commands"], []) + self.assertEqual(result["messages"], [m]) + + def test_zoneset_add_rem_3(self): + a = dict( + zone_zoneset_details=[ + dict(vsan=922, zoneset=[dict(name="zsetname21New", remove=True)]), + ], + ) + set_module_args(a, True) + self.execute_show_cmd_zone_status.return_value = load_fixture( + "nxos_zone_zoneset", + "shzonestatus_0.cfg", + ) + self.execute_show_cmd_zoneset.return_value = load_fixture( + "nxos_zone_zoneset", + "shzoneset_0.cfg", + ) + result = self.execute_module(changed=False, failed=False) + m = "zoneset 'zsetname21New' is not present in vsan 922 ,hence there is nothing to remove" + self.assertEqual(result["commands"], []) + self.assertEqual(result["messages"], [m]) + + # Test zoneset mem add/removal + def test_zoneset_mem_add_rem(self): + mem1 = {"name": "newZoneV100"} + + a = dict( + zone_zoneset_details=[ + dict(vsan=922, zoneset=[dict(name="zsetname21", members=[mem1])]), + ], + ) + set_module_args(a, True) + self.execute_show_cmd_zone_status.return_value = load_fixture( + "nxos_zone_zoneset", + "shzonestatus_0.cfg", + ) + self.execute_show_cmd_zoneset.return_value = load_fixture( + "nxos_zone_zoneset", + "shzoneset_0.cfg", + ) + result = self.execute_module(changed=True, failed=False) + self.assertEqual( + result["commands"], + [ + "terminal dont-ask", + "zoneset name zsetname21 vsan 922", + "member newZoneV100", + "no terminal dont-ask", + ], + ) + + # Test zoneset mem add/removal + def test_zoneset_mem_add_rem_1(self): + mem1 = {"name": "zone21A", "remove": True} + + a = dict( + zone_zoneset_details=[ + dict(vsan=922, zoneset=[dict(name="zsetname21", members=[mem1])]), + ], + ) + set_module_args(a, True) + self.execute_show_cmd_zone_status.return_value = load_fixture( + "nxos_zone_zoneset", + "shzonestatus_0.cfg", + ) + self.execute_show_cmd_zoneset.return_value = load_fixture( + "nxos_zone_zoneset", + "shzoneset_0.cfg", + ) + result = self.execute_module(changed=True, failed=False) + self.assertEqual( + result["commands"], + [ + "terminal dont-ask", + "zoneset name zsetname21 vsan 922", + "no member zone21A", + "no terminal dont-ask", + ], + ) + + # Test zoneset mem add/removal + def test_zoneset_mem_add_rem_2(self): + mem1 = {"name": "zone21", "remove": True} + + a = dict( + zone_zoneset_details=[ + dict(vsan=922, zoneset=[dict(name="zsetname21", members=[mem1])]), + ], + ) + set_module_args(a, True) + self.execute_show_cmd_zone_status.return_value = load_fixture( + "nxos_zone_zoneset", + "shzonestatus_0.cfg", + ) + self.execute_show_cmd_zoneset.return_value = load_fixture( + "nxos_zone_zoneset", + "shzoneset_0.cfg", + ) + result = self.execute_module(changed=False, failed=False) + m = "zoneset member 'zone21' is not present in zoneset 'zsetname21' in vsan 922 ,hence there is nothing to remove" + self.assertEqual(result["commands"], []) + self.assertEqual(result["messages"], [m]) + + # Test zoneset activate/deactivate + def test_zoneset_activate_deactivate(self): + a = dict( + zone_zoneset_details=[dict(vsan=221, zoneset=[dict(name="zsv221", action="activate")])], + ) + set_module_args(a, True) + self.execute_show_cmd_zone_status.return_value = load_fixture( + "nxos_zone_zoneset", + "shzonestatus_4.cfg", + ) + self.execute_show_cmd_zoneset.return_value = load_fixture( + "nxos_zone_zoneset", + "shzoneset_2.cfg", + ) + self.execute_show_cmd_zoneset_active.return_value = load_fixture( + "nxos_zone_zoneset", + "shzonesetactive_0.cfg", + ) + result = self.execute_module(changed=False, failed=False) + self.assertEqual(result["commands"], []) + + def test_zoneset_activate_deactivate_1(self): + a = dict( + zone_zoneset_details=[ + dict( + vsan=221, + zoneset=[dict(name="zsv221", action="deactivate")], + ), + ], + ) + set_module_args(a, True) + self.execute_show_cmd_zone_status.return_value = load_fixture( + "nxos_zone_zoneset", + "shzonestatus_4.cfg", + ) + self.execute_show_cmd_zoneset.return_value = load_fixture( + "nxos_zone_zoneset", + "shzoneset_2.cfg", + ) + self.execute_show_cmd_zoneset_active.return_value = load_fixture( + "nxos_zone_zoneset", + "shzonesetactive_0.cfg", + ) + result = self.execute_module(changed=True, failed=False) + self.assertEqual( + result["commands"], + [ + "terminal dont-ask", + "no zoneset activate name zsv221 vsan 221", + "zone commit vsan 221", + "no terminal dont-ask", + ], + ) + + def test_zoneset_activate_deactivate_2(self): + a = dict( + zone_zoneset_details=[ + dict( + vsan=221, + zoneset=[dict(name="zsv221New", action="activate")], + ), + ], + ) + set_module_args(a, True) + self.execute_show_cmd_zone_status.return_value = load_fixture( + "nxos_zone_zoneset", + "shzonestatus_4.cfg", + ) + self.execute_show_cmd_zoneset.return_value = load_fixture( + "nxos_zone_zoneset", + "shzoneset_2.cfg", + ) + self.execute_show_cmd_zoneset_active.return_value = load_fixture( + "nxos_zone_zoneset", + "shzonesetactive_0.cfg", + ) + result = self.execute_module(changed=True, failed=False) + self.assertEqual( + result["commands"], + [ + "terminal dont-ask", + "zoneset name zsv221New vsan 221", + "zoneset activate name zsv221New vsan 221", + "zone commit vsan 221", + "no terminal dont-ask", + ], + ) + + def test_bug_zone_remove(self): + mem1 = {"pwwn": "21:01:00:1b:32:a1:c0:a8", "remove": True} + mem2 = {"pwwn": "50:06:01:6a:47:e4:6e:59", "remove": True} + a = dict( + zone_zoneset_details=[dict(vsan=221, zone=[dict(name="zv221", members=[mem1, mem2])])], + ) + set_module_args(a, True) + self.execute_show_cmd_zone_status.return_value = load_fixture( + "nxos_zone_zoneset", + "shzonestatus_4.cfg", + ) + self.execute_show_cmd_zone.return_value = load_fixture("nxos_zone_zoneset", "shzone_2.cfg") + self.execute_show_cmd_zoneset_active.return_value = load_fixture( + "nxos_zone_zoneset", + "shzonesetactive_0.cfg", + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "terminal dont-ask", + "zone name zv221 vsan 221", + "no member pwwn 21:01:00:1b:32:a1:c0:a8", + "no member pwwn 50:06:01:6a:47:e4:6e:59", + "zone commit vsan 221", + "no terminal dont-ask", + ], + ) + + def test_bug_from_active_zoneset_act(self): + a = dict( + zone_zoneset_details=[ + dict( + vsan=221, + zoneset=[dict(name="zsv221New", action="activate")], + ), + ], + ) + set_module_args(a, True) + self.execute_show_cmd_zone_status.return_value = load_fixture( + "nxos_zone_zoneset", + "shzonestatus_4.cfg", + ) + self.execute_show_cmd_zoneset.return_value = load_fixture( + "nxos_zone_zoneset", + "shzoneset_2.cfg", + ) + self.execute_show_cmd_zoneset_active.return_value = load_fixture( + "nxos_zone_zoneset", + "shzonesetactive_0.cfg", + ) + result = self.execute_module(changed=True, failed=False) + self.assertEqual( + result["commands"], + [ + "terminal dont-ask", + "zoneset name zsv221New vsan 221", + "zoneset activate name zsv221New vsan 221", + "zone commit vsan 221", + "no terminal dont-ask", + ], + ) + + # Test for bug 339 + def test_for_bug_339(self): + mem1 = {"pwwn": "20:00:00:25:b5:10:a0:00", "devtype": "initiator"} + a = dict( + zone_zoneset_details=[ + dict( + vsan=100, + smart_zoning=True, + zone=[dict(name="SZ-WLD-IAAS1-HUABVA07", members=[mem1])], + ), + ], + ) + + self.execute_show_cmd_zone.return_value = load_fixture( + "nxos_zone_zoneset", + "shzone_bug339.cfg", + ) + self.execute_show_cmd_zone_status.return_value = load_fixture( + "nxos_zone_zoneset", + "shzonestatus_0.cfg", + ) + set_module_args(a, True) + result = self.execute_module(changed=False, failed=False) + self.assertEqual(result["commands"], []) + m = "zone member '20:00:00:25:b5:10:a0:00' of device type 'initiator' is already present in zone 'SZ-WLD-IAAS1-HUABVA07'" + assert m in str(result["messages"]) + + def test_bug_zone_remove_oliver(self): + mem1 = {"pwwn": "c0:50:76:09:5b:20:00:64", "remove": True} + a = dict( + zone_zoneset_details=[ + dict( + vsan=50, + zone=[ + dict( + name="z50_azusant_f0_unity8174_spa1", + members=[mem1], + ), + ], + ), + ], + ) + set_module_args(a, True) + self.execute_show_cmd_zone_status.return_value = load_fixture( + "nxos_zone_zoneset", + "show_zone_status_vsan.out", + ) + self.execute_show_cmd_zone.return_value = load_fixture( + "nxos_zone_zoneset", + "show_zone_vsan.out", + ) + self.execute_show_cmd_zoneset_active.return_value = load_fixture( + "nxos_zone_zoneset", + "show_zoneset_active_vsan.out", + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "terminal dont-ask", + "zone name z50_azusant_f0_unity8174_spa1 vsan 50", + "no member pwwn c0:50:76:09:5b:20:00:64", + "no terminal dont-ask", + ], + ) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos.py new file mode 100644 index 00000000..fd5cdb36 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos.py @@ -0,0 +1,124 @@ +# +# (c) 2020 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. +# +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from os import path + + +try: + from unittest.mock import MagicMock +except ImportError: + from mock import MagicMock + +from ansible.module_utils._text import to_bytes, to_text + +from ansible_collections.cisco.nxos.plugins.cliconf import nxos +from ansible_collections.cisco.nxos.tests.unit.compat import unittest + + +class TestPluginCLIConfNXOS(unittest.TestCase): + """Test class for NXOS CLI Conf Methods""" + + def setUp(self): + self._mock_connection = MagicMock() + self._prepare() + self._cliconf = nxos.Cliconf(self._mock_connection) + self.maxDiff = None + + def _prepare(self, platform="nxos"): + b_FIXTURE_DIR = b"%s/fixtures/cliconf/%s" % ( + to_bytes( + path.dirname(path.abspath(__file__)), + errors="surrogate_or_strict", + ), + to_bytes(platform), + ) + + def _connection_side_effect(*args, **kwargs): + try: + if args: + value = args[0] + else: + value = kwargs.get("command") + + fixture_path = path.abspath( + b"%s/%s" % (b_FIXTURE_DIR, b"_".join(value.split(b" "))), + ) + with open(fixture_path, "rb") as file_desc: + return to_text(file_desc.read()) + except (OSError, IOError): + if args: + value = args[0] + return value + elif kwargs.get("command"): + value = kwargs.get("command") + return value + return "NO-OP" + + self._mock_connection.send.side_effect = _connection_side_effect + + def tearDown(self): + pass + + def test_get_device_info_nxos(self): + """Test get_device_info for nxos""" + device_info = self._cliconf.get_device_info() + + mock_device_info = { + "network_os": "nxos", + "network_os_hostname": "nxos-9kv-933", + "network_os_image": "bootflash:///nxos.9.3.3.bin", + "network_os_model": "Nexus9000 C9300v Chassis", + "network_os_platform": "N9K-C9300v", + "network_os_version": "9.3(3)", + } + + self.assertEqual(device_info, mock_device_info) + + def test_get_device_info_mds(self): + """Test get_device_info for mds""" + self._prepare(platform="mds") + device_info = self._cliconf.get_device_info() + mock_device_info = { + "network_os": "nxos", + "network_os_version": "8.4(2b)", + "network_os_model": 'MDS 9148S 16G 48 FC (1 Slot) Chassis ("2/4/8/16 Gbps FC/Supervisor")', + "network_os_hostname": "sw109-Mini", + "network_os_image": "bootflash:///m9100-s5ek9-mz.8.4.2b.bin", + "network_os_platform": "DS-C9710", + } + + self.assertEqual(device_info, mock_device_info) + + def test_get_command_with_output_nxos(self): + """Test _get_command_with_output for nxos""" + self._prepare() + cmd = self._cliconf._get_command_with_output(command="show version", output="json") + + self.assertEqual(cmd, "show version | json") + + def test_get_command_with_output_mds(self): + """Test _get_command_with_output for mds""" + self._prepare(platform="mds") + cmd = self._cliconf._get_command_with_output(command="show version", output="json") + + self.assertEqual(cmd, "show version | json native") diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_acl_interfaces.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_acl_interfaces.py new file mode 100644 index 00000000..ae56208f --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_acl_interfaces.py @@ -0,0 +1,389 @@ +# +# (c) 2019, Ansible by Red Hat, inc +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +# + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from ansible_collections.cisco.nxos.plugins.modules import nxos_acl_interfaces +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch +from ansible_collections.cisco.nxos.tests.unit.modules.utils import set_module_args + +from .nxos_module import TestNxosModule + + +class TestNxosAclInterfacesModule(TestNxosModule): + module = nxos_acl_interfaces + + def setUp(self): + super(TestNxosAclInterfacesModule, self).setUp() + + self.mock_get_config = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.get_config", + ) + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_get_resource_connection_config = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base.get_resource_connection", + ) + self.get_resource_connection_config = self.mock_get_resource_connection_config.start() + + self.mock_get_resource_connection_facts = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection", + ) + self.get_resource_connection_facts = self.mock_get_resource_connection_facts.start() + + self.mock_edit_config = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.config.acl_interfaces.acl_interfaces.Acl_interfaces.edit_config", + ) + self.edit_config = self.mock_edit_config.start() + + self.mock_execute_show_command = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.facts.acl_interfaces.acl_interfaces.Acl_interfacesFacts.get_device_data", + ) + self.execute_show_command = self.mock_execute_show_command.start() + + def tearDown(self): + super(TestNxosAclInterfacesModule, self).tearDown() + self.mock_get_resource_connection_config.stop() + self.mock_get_resource_connection_facts.stop() + self.mock_edit_config.stop() + self.mock_get_config.stop() + self.mock_load_config.stop() + self.mock_execute_show_command.stop() + + def load_fixtures(self, commands=None, device=""): + def load_from_file(*args, **kwargs): + output = """interface Ethernet1/2\n ip access-group ACL1v4 out\n interface Ethernet1/4\n ipv6 port traffic-filter ACL2v6 in\n""" + return output + + self.execute_show_command.side_effect = load_from_file + + def test_nxos_acl_interfaces_merged(self): + set_module_args( + dict( + config=[ + dict( + name="Ethernet1/3", + access_groups=[ + dict( + afi="ipv4", + acls=[dict(name="ACL1-v4", direction="in")], + ), + ], + ), + ], + state="merged", + ), + ) + commands = ["interface Ethernet1/3", "ip access-group ACL1-v4 in"] + self.execute_module(changed=True, commands=commands) + + def test_nxos_acl_interfaces_merged_idempotent(self): + set_module_args( + dict( + config=[ + dict( + name="Ethernet1/2", + access_groups=[ + dict( + afi="ipv4", + acls=[dict(name="ACL1v4", direction="out")], + ), + ], + ), + dict( + name="Ethernet1/4", + access_groups=[ + dict( + afi="ipv6", + acls=[ + dict( + name="ACL2v6", + direction="in", + port=True, + ), + ], + ), + ], + ), + ], + state="merged", + ), + ) + self.execute_module(changed=False, commands=[]) + + def test_nxos_acl_interfaces_replaced(self): + set_module_args( + dict( + config=[ + dict( + name="Ethernet1/2", + access_groups=[ + dict( + afi="ipv6", + acls=[ + dict( + name="ACL1v6", + direction="in", + port=True, + ), + ], + ), + ], + ), + dict( + name="Ethernet1/5", + access_groups=[ + dict( + afi="ipv4", + acls=[ + dict( + name="ACL2v4", + direction="in", + port=True, + ), + ], + ), + ], + ), + ], + state="replaced", + ), + ) + commands = [ + "interface Ethernet1/2", + "no ip access-group ACL1v4 out", + "ipv6 port traffic-filter ACL1v6 in", + "interface Ethernet1/5", + "ip port access-group ACL2v4 in", + ] + self.execute_module(changed=True, commands=commands) + + def test_nxos_acl_interfaces_replaced_idempotent(self): + set_module_args( + dict( + config=[ + dict( + name="Ethernet1/2", + access_groups=[ + dict( + afi="ipv4", + acls=[dict(name="ACL1v4", direction="out")], + ), + ], + ), + ], + state="replaced", + ), + ) + self.execute_module(changed=False, commands=[]) + + def test_nxos_acl_interfaces_overridden(self): + set_module_args( + dict( + config=[ + dict( + name="Ethernet1/3", + access_groups=[ + dict( + afi="ipv4", + acls=[ + dict(name="ACL2v4", direction="out"), + dict( + name="PortACL", + direction="in", + port=True, + ), + ], + ), + ], + ), + ], + state="overridden", + ), + ) + commands = [ + "interface Ethernet1/2", + "no ip access-group ACL1v4 out", + "interface Ethernet1/4", + "no ipv6 port traffic-filter ACL2v6 in", + "interface Ethernet1/3", + "ip access-group ACL2v4 out", + "ip port access-group PortACL in", + ] + self.execute_module(changed=True, commands=commands) + + def test_nxos_acl_interfaces_overridden_idempotent(self): + set_module_args( + dict( + config=[ + dict( + name="Ethernet1/2", + access_groups=[ + dict( + afi="ipv4", + acls=[dict(name="ACL1v4", direction="out")], + ), + ], + ), + dict( + name="Ethernet1/4", + access_groups=[ + dict( + afi="ipv6", + acls=[ + dict( + name="ACL2v6", + direction="in", + port=True, + ), + ], + ), + ], + ), + ], + state="overridden", + ), + ) + self.execute_module(changed=False, commands=[]) + + def test_nxos_acl_interfaces_deletedname(self): + set_module_args(dict(config=[dict(name="Ethernet1/2")], state="deleted")) + commands = ["interface Ethernet1/2", "no ip access-group ACL1v4 out"] + self.execute_module(changed=True, commands=commands) + + def test_nxos_acl_interfaces_deletedafi(self): + set_module_args( + dict( + config=[dict(name="Ethernet1/2", access_groups=[dict(afi="ipv4")])], + state="deleted", + ), + ) + commands = ["interface Ethernet1/2", "no ip access-group ACL1v4 out"] + self.execute_module(changed=True, commands=commands) + + def test_nxos_acl_interfaces_deletedacl(self): + set_module_args( + dict( + config=[ + dict( + name="Ethernet1/2", + access_groups=[ + dict( + afi="ipv4", + acls=[dict(name="ACL1v4", direction="out")], + ), + ], + ), + ], + state="deleted", + ), + ) + commands = ["interface Ethernet1/2", "no ip access-group ACL1v4 out"] + self.execute_module(changed=True, commands=commands) + + def test_nxos_acl_interfaces_rendered(self): + set_module_args( + dict( + config=[ + dict( + name="Ethernet1/2", + access_groups=[ + dict( + afi="ipv4", + acls=[dict(name="ACL1v4", direction="out")], + ), + ], + ), + dict( + name="Ethernet1/4", + access_groups=[ + dict( + afi="ipv6", + acls=[ + dict( + name="ACL2v6", + direction="in", + port=True, + ), + ], + ), + ], + ), + ], + state="rendered", + ), + ) + commands = [ + "interface Ethernet1/2", + "ip access-group ACL1v4 out", + "interface Ethernet1/4", + "ipv6 port traffic-filter ACL2v6 in", + ] + result = self.execute_module(changed=False) + self.assertEqual(sorted(result["rendered"]), sorted(commands), result["rendered"]) + + def test_nxos_acl_interfaces_parsed(self): + set_module_args( + dict( + running_config="""interface Ethernet1/2\n ip access-group ACL1v4 out\n interface Ethernet1/4\n \ + ipv6 port traffic-filter ACL2v6 in""", + state="parsed", + ), + ) + result = self.execute_module(changed=False) + compare_list = [ + { + "access_groups": [ + { + "acls": [{"direction": "out", "name": "ACL1v4"}], + "afi": "ipv4", + }, + ], + "name": "Ethernet1/2", + }, + { + "access_groups": [ + { + "acls": [{"direction": "in", "name": "ACL2v6", "port": True}], + "afi": "ipv6", + }, + ], + "name": "Ethernet1/4", + }, + ] + self.assertEqual(result["parsed"], compare_list, result["parsed"]) + + def test_nxos_acl_interfaces_gathered(self): + set_module_args(dict(config=[], state="gathered")) + result = self.execute_module(changed=False) + compare_list = [ + { + "access_groups": [ + { + "acls": [{"direction": "out", "name": "ACL1v4"}], + "afi": "ipv4", + }, + ], + "name": "Ethernet1/2", + }, + { + "access_groups": [ + { + "acls": [{"direction": "in", "name": "ACL2v6", "port": True}], + "afi": "ipv6", + }, + ], + "name": "Ethernet1/4", + }, + ] + self.assertEqual(result["gathered"], compare_list, result["gathered"]) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_acls.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_acls.py new file mode 100644 index 00000000..6436e065 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_acls.py @@ -0,0 +1,855 @@ +# +# (c) 2019, Ansible by Red Hat, inc +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +# + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from textwrap import dedent + +from ansible_collections.cisco.nxos.plugins.modules import nxos_acls +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch +from ansible_collections.cisco.nxos.tests.unit.modules.utils import set_module_args + +from .nxos_module import TestNxosModule + + +class TestNxosAclsModule(TestNxosModule): + module = nxos_acls + + def setUp(self): + super(TestNxosAclsModule, self).setUp() + + self.mock_get_config = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.get_config", + ) + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_get_resource_connection_config = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base.get_resource_connection", + ) + self.get_resource_connection_config = self.mock_get_resource_connection_config.start() + + self.mock_get_resource_connection_facts = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection", + ) + self.get_resource_connection_facts = self.mock_get_resource_connection_facts.start() + + self.mock_edit_config = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.config.acls.acls.Acls.edit_config", + ) + self.edit_config = self.mock_edit_config.start() + + self.mock_execute_show_command = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.facts.acls.acls.AclsFacts.get_device_data", + ) + self.execute_show_command = self.mock_execute_show_command.start() + + v4 = """\nip access-list ACL1v4\n 10 permit ip any any\n 20 deny udp any any""" + v6 = """\nipv6 access-list ACL1v6\n 10 permit sctp any any""" + self.execute_show_command.return_value = dedent(v4 + v6) + + def tearDown(self): + super(TestNxosAclsModule, self).tearDown() + self.mock_get_resource_connection_config.stop() + self.mock_get_resource_connection_facts.stop() + self.mock_edit_config.stop() + self.mock_get_config.stop() + self.mock_load_config.stop() + self.mock_execute_show_command.stop() + + def test_nxos_acls_merged(self): + set_module_args( + dict( + config=[ + dict( + afi="ipv4", + acls=[ + dict( + name="ACL2v4", + aces=[ + dict( + grant="deny", + destination=dict(any=True), + source=dict(any=True), + fragments=True, + sequence=20, + protocol="tcp", + protocol_options=dict(tcp=dict(ack=True)), + ), + dict( + destination=dict( + address="1.2.2.2", + wildcard_bits="0.0.255.255", + ), + dscp="31", + grant="permit", + protocol="ip", + sequence="25", + source=dict( + address="1.1.1.1", + wildcard_bits="0.0.0.255", + ), + ), + dict( + grant="deny", + destination=dict(prefix="2002:2:2:2::/64"), + source=dict(prefix="2002:1:1:1::/64"), + sequence=30, + protocol="icmp", + protocol_options=dict(icmp=dict(echo_request=True)), + ), + ], + ), + ], + ), + dict(afi="ipv6", acls=[dict(name="ACL2v6")]), + ], + state="merged", + ), + ) + commands = [ + "ip access-list ACL2v4", + "20 deny tcp any any ack fragments", + "25 permit ip 1.1.1.1 0.0.0.255 1.2.2.2 0.0.255.255 dscp 31", + "30 deny icmp 2002:1:1:1::/64 2002:2:2:2::/64 echo-request", + "ipv6 access-list ACL2v6", + ] + self.execute_module(changed=True, commands=commands) + + def test_nxos_acls_merged_idempotent(self): + set_module_args( + dict( + config=[ + dict( + afi="ipv4", + acls=[ + dict( + name="ACL1v4", + aces=[ + dict( + grant="permit", + destination=dict(any=True), + source=dict(any=True), + sequence=10, + protocol="ip", + ), + dict( + grant="deny", + destination=dict(any=True), + source=dict(any=True), + sequence=20, + protocol="udp", + ), + ], + ), + ], + ), + dict( + afi="ipv6", + acls=[ + dict( + name="ACL1v6", + aces=[ + dict( + grant="permit", + destination=dict(any=True), + source=dict(any=True), + sequence=10, + protocol="sctp", + ), + ], + ), + ], + ), + ], + state="merged", + ), + ) + self.execute_module(changed=False, commands=[]) + + def test_nxos_acls_replaced(self): + set_module_args( + dict( + config=[ + dict( + afi="ipv4", + acls=[ + dict( + name="ACL1v4", + aces=[ + dict( + grant="permit", + destination=dict(host="192.0.2.28"), + source=dict(any=True), + log=True, + sequence=50, + protocol="icmp", + protocol_options=dict( + icmp=dict(administratively_prohibited=True), + ), + ), + ], + ), + ], + ), + ], + state="replaced", + ), + ) + commands = [ + "ip access-list ACL1v4", + "no 20 deny udp any any", + "no 10 permit ip any any", + "50 permit icmp any host 192.0.2.28 administratively-prohibited log", + ] + self.execute_module(changed=True, commands=commands) + + def test_nxos_acls_replaced_idempotent(self): + set_module_args( + dict( + config=[ + dict( + afi="ipv4", + acls=[ + dict( + name="ACL1v4", + aces=[ + dict( + grant="permit", + destination=dict(any=True), + source=dict(any=True), + sequence=10, + protocol="ip", + ), + dict( + grant="deny", + destination=dict(any=True), + source=dict(any=True), + sequence=20, + protocol="udp", + ), + ], + ), + ], + ), + dict( + afi="ipv6", + acls=[ + dict( + name="ACL1v6", + aces=[ + dict( + grant="permit", + destination=dict(any=True), + source=dict(any=True), + sequence=10, + protocol="sctp", + ), + ], + ), + ], + ), + ], + state="replaced", + ), + ) + self.execute_module(changed=False, commands=[]) + + def test_nxos_acls_overridden(self): + set_module_args( + dict( + config=[ + dict( + afi="ipv4", + acls=[ + dict( + name="ACL2v4", + aces=[ + dict( + grant="permit", + destination=dict(host="192.0.2.28"), + source=dict(any=True), + log=True, + sequence=50, + protocol="icmp", + protocol_options=dict( + icmp=dict(administratively_prohibited=True), + ), + ), + dict(remark="Overridden ACL"), + ], + ), + ], + ), + ], + state="overridden", + ), + ) + commands = [ + "no ip access-list ACL1v4", + "no ipv6 access-list ACL1v6", + "ip access-list ACL2v4", + "50 permit icmp any host 192.0.2.28 administratively-prohibited log", + "remark Overridden ACL", + ] + self.execute_module(changed=True, commands=commands) + + def test_nxos_acls_overridden_idempotent(self): + set_module_args( + dict( + config=[ + dict( + afi="ipv4", + acls=[ + dict( + name="ACL1v4", + aces=[ + dict( + grant="permit", + destination=dict(any=True), + source=dict(any=True), + sequence=10, + protocol="ip", + ), + dict( + grant="deny", + destination=dict(any=True), + source=dict(any=True), + sequence=20, + protocol="udp", + ), + ], + ), + ], + ), + dict( + afi="ipv6", + acls=[ + dict( + name="ACL1v6", + aces=[ + dict( + grant="permit", + destination=dict(any=True), + source=dict(any=True), + sequence=10, + protocol="sctp", + ), + ], + ), + ], + ), + ], + state="overridden", + ), + ) + self.execute_module(changed=False, commands=[]) + + def test_nxos_acls_deletedafi(self): + set_module_args(dict(config=[dict(afi="ipv4")], state="deleted")) + commands = ["no ip access-list ACL1v4"] + self.execute_module(changed=True, commands=commands) + + def test_nxos_acls_deletedall(self): + set_module_args(dict(config=[], state="deleted")) + commands = ["no ipv6 access-list ACL1v6", "no ip access-list ACL1v4"] + self.execute_module(changed=True, commands=commands) + + def test_nxos_acls_rendered(self): + set_module_args( + dict( + config=[ + dict( + afi="ipv4", + acls=[ + dict( + name="ACL1v4", + aces=[ + dict( + grant="permit", + destination=dict(any=True), + source=dict(any=True), + sequence=10, + protocol="ip", + ), + dict( + grant="deny", + destination=dict(any=True), + source=dict(any=True), + sequence=20, + protocol="udp", + ), + ], + ), + ], + ), + dict( + afi="ipv6", + acls=[ + dict( + name="ACL1v6", + aces=[ + dict( + grant="permit", + destination=dict(any=True), + source=dict(any=True), + sequence=10, + protocol="sctp", + ), + ], + ), + ], + ), + ], + state="rendered", + ), + ) + commands = [ + "ip access-list ACL1v4", + "10 permit ip any any", + "20 deny udp any any", + "ipv6 access-list ACL1v6", + "10 permit sctp any any", + ] + result = self.execute_module(changed=False) + self.assertEqual(sorted(result["rendered"]), sorted(commands), result["rendered"]) + + def test_nxos_acls_parsed(self): + set_module_args( + dict( + running_config=dedent( + """ + ip access-list ACL1v4 + statistics per-entry + 10 permit ip any any + 20 deny udp any any dscp AF23 precedence critical + """, + ), + state="parsed", + ), + ) + result = self.execute_module(changed=False) + compare_list = [ + { + "afi": "ipv4", + "acls": [ + { + "name": "ACL1v4", + "aces": [ + { + "grant": "permit", + "sequence": 10, + "protocol": "ip", + "source": {"any": True}, + "destination": {"any": True}, + }, + { + "grant": "deny", + "sequence": 20, + "protocol": "udp", + "source": {"any": True}, + "destination": {"any": True}, + "dscp": "AF23", + "precedence": "critical", + }, + ], + }, + ], + }, + ] + self.assertEqual(result["parsed"], compare_list, result["parsed"]) + + def test_nxos_acls_gathered(self): + set_module_args(dict(config=[], state="gathered")) + result = self.execute_module(changed=False) + compare_list = [ + { + "acls": [ + { + "aces": [ + { + "destination": {"any": True}, + "sequence": 10, + "protocol": "sctp", + "source": {"any": True}, + "grant": "permit", + }, + ], + "name": "ACL1v6", + }, + ], + "afi": "ipv6", + }, + { + "acls": [ + { + "aces": [ + { + "destination": {"any": True}, + "sequence": 10, + "protocol": "ip", + "source": {"any": True}, + "grant": "permit", + }, + { + "destination": {"any": True}, + "sequence": 20, + "protocol": "udp", + "source": {"any": True}, + "grant": "deny", + }, + ], + "name": "ACL1v4", + }, + ], + "afi": "ipv4", + }, + ] + self.assertEqual(result["gathered"], compare_list, result["gathered"]) + + def test_nxos_acls_replaced_2(self): + self.execute_show_command.return_value = dedent( + """\ + ip access-list 99 + 10 remark TEST-COMMENT-1 + 20 permit ip 192.0.2.4/32 any + 30 permit ip 192.0.2.5/32 any + 40 remark TEST-COMMENT-2 + 50 permit ip 198.51.100.6/32 any + 60 permit ip 198.51.100.7/32 any + """, + ) + set_module_args( + dict( + config=[ + dict( + afi="ipv4", + acls=[ + dict( + name="99", + aces=[ + dict( + grant="permit", + destination=dict(any=True), + source=dict(host="192.0.2.1"), + sequence=10, + protocol="ip", + ), + dict( + grant="permit", + destination=dict(any=True), + source=dict(host="192.0.2.2"), + sequence=20, + protocol="ip", + ), + dict( + grant="permit", + destination=dict(any=True), + source=dict(host="192.0.2.3"), + sequence=30, + protocol="ip", + ), + dict( + grant="permit", + destination=dict(any=True), + source=dict(host="192.0.2.1"), + sequence=40, + protocol="ip", + ), + ], + ), + ], + ), + ], + state="replaced", + ), + ) + + commands = [ + "ip access-list 99", + "no 10 remark TEST-COMMENT-1", + "no 20 permit ip host 192.0.2.4 any", + "no 30 permit ip host 192.0.2.5 any", + "no 40 remark TEST-COMMENT-2", + "no 50 permit ip host 198.51.100.6 any", + "no 60 permit ip host 198.51.100.7 any", + "10 permit ip host 192.0.2.1 any", + "20 permit ip host 192.0.2.2 any", + "30 permit ip host 192.0.2.3 any", + "40 permit ip host 192.0.2.1 any", + ] + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_nxos_acls_merged_failure(self): + self.execute_show_command.return_value = dedent( + """\ + ip access-list 99 + 10 remark TEST-COMMENT-1 + """, + ) + set_module_args( + dict( + config=[ + dict( + afi="ipv4", + acls=[ + dict( + name="99", + aces=[ + dict( + grant="permit", + destination=dict(any=True), + source=dict(host="192.0.2.1"), + sequence=10, + protocol="ip", + ), + ], + ), + ], + ), + ], + state="merged", + ), + ) + + result = self.execute_module(failed=True) + failure_msg = "Cannot update existing ACE 99 of ACL 10 with state merged. Please use state replaced or overridden." + self.assertEqual(result["msg"], failure_msg) + + def test_nxos_acls_parse_remark(self): + self.execute_show_command.return_value = dedent( + """\ + ip access-list TEST_RESEQUENCE + 10 permit ip 10.0.0.0/24 any + 20 deny tcp any eq ftp-data any eq domain + 25 permit icmp any any echo-reply + 27 permit icmp any any port-unreachable + 30 remark for resetting to default run resequence ip access-list TEST_RESEQUENCE 2 3 + ipv6 access-list TEST_RESEQUENCE_ipv6 + 10 permit udp any any + 20 deny tcp any any + 30 remark for resetting to default run resequence ip access-list TEST_RESEQUENCE_ipv6 2 3 + ipv6 access-list TEST_PREFIX_HOST + 10 permit ipv6 fd00:976a::/32 any + 20 permit ipv6 2001:db8:85a3::8a2e:370:7334/128 any + ipv6 access-list TEST_ICMPv6 + 10 permit icmp any any nd-na + 20 deny icmp any any nd-ns telemetry_path + """, + ) + set_module_args(dict(state="gathered")) + + gathered = [ + { + "acls": [ + { + "name": "TEST_RESEQUENCE_ipv6", + "aces": [ + { + "sequence": 10, + "grant": "permit", + "protocol": "udp", + "source": {"any": True}, + "destination": {"any": True}, + }, + { + "sequence": 20, + "grant": "deny", + "protocol": "tcp", + "source": {"any": True}, + "destination": {"any": True}, + }, + { + "sequence": 30, + "remark": "for resetting to default run resequence ip access-list TEST_RESEQUENCE_ipv6 2 3", + }, + ], + }, + { + "name": "TEST_PREFIX_HOST", + "aces": [ + { + "sequence": 10, + "grant": "permit", + "protocol": "ipv6", + "source": {"prefix": "fd00:976a::/32"}, + "destination": {"any": True}, + }, + { + "sequence": 20, + "grant": "permit", + "protocol": "ipv6", + "source": {"host": "2001:db8:85a3::8a2e:370:7334"}, + "destination": {"any": True}, + }, + ], + }, + { + "name": "TEST_ICMPv6", + "aces": [ + { + "sequence": 10, + "grant": "permit", + "protocol": "icmpv6", + "protocol_options": { + "icmpv6": { + "nd_na": True, + }, + }, + "source": {"any": True}, + "destination": {"any": True}, + }, + { + "sequence": 20, + "grant": "deny", + "protocol": "icmpv6", + "protocol_options": { + "icmpv6": { + "nd_ns": True, + "telemetry_path": True, + }, + }, + "source": {"any": True}, + "destination": {"any": True}, + }, + ], + }, + ], + "afi": "ipv6", + }, + { + "acls": [ + { + "name": "TEST_RESEQUENCE", + "aces": [ + { + "sequence": 10, + "grant": "permit", + "protocol": "ip", + "source": {"prefix": "10.0.0.0/24"}, + "destination": {"any": True}, + }, + { + "sequence": 20, + "grant": "deny", + "protocol": "tcp", + "source": { + "any": True, + "port_protocol": {"eq": "ftp-data"}, + }, + "destination": { + "any": True, + "port_protocol": {"eq": "domain"}, + }, + }, + { + "sequence": 25, + "grant": "permit", + "protocol": "icmp", + "protocol_options": { + "icmp": { + "echo_reply": True, + }, + }, + "source": { + "any": True, + }, + "destination": { + "any": True, + }, + }, + { + "sequence": 27, + "grant": "permit", + "protocol": "icmp", + "protocol_options": { + "icmp": { + "port_unreachable": True, + }, + }, + "source": { + "any": True, + }, + "destination": { + "any": True, + }, + }, + { + "sequence": 30, + "remark": "for resetting to default run resequence ip access-list TEST_RESEQUENCE 2 3", + }, + ], + }, + ], + "afi": "ipv4", + }, + ] + result = self.execute_module(changed=False) + self.assertEqual(result["gathered"], gathered) + + def test_nxos_acls_icmpv6_1(self): + self.execute_show_command.return_value = dedent( + """\ + ipv6 access-list TEST_ICMPv6 + 20 deny icmp any any nd-ns telemetry_path + """, + ) + set_module_args( + dict( + config=[ + dict( + afi="ipv6", + acls=[ + dict( + name="TEST_ICMPv6", + aces=[ + dict( + grant="permit", + destination=dict(any=True), + source=dict(host="192.0.2.1"), + sequence=10, + protocol="icmpv6", + protocol_options=dict( + icmpv6=dict( + nd_na=True, + ), + ), + ), + dict( + grant="deny", + destination=dict(any=True), + source=dict(any=True), + sequence=20, + protocol="icmpv6", + protocol_options=dict( + icmpv6=dict( + nd_ns=True, + telemetry_path=True, + ), + ), + ), + ], + ), + ], + ), + ], + state="merged", + ), + ) + + commands = [ + "ipv6 access-list TEST_ICMPv6", + "10 permit icmp host 192.0.2.1 any nd-na", + ] + result = self.execute_module(changed=True) + self.assertEqual(result["commands"], commands) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_banner.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_banner.py new file mode 100644 index 00000000..7f8faf3a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_banner.py @@ -0,0 +1,102 @@ +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from ansible_collections.cisco.nxos.plugins.modules import nxos_banner +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, set_module_args + + +class TestNxosBannerModule(TestNxosModule): + module = nxos_banner + + def setUp(self): + super(TestNxosBannerModule, self).setUp() + self.mock_run_commands = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_banner.run_commands", + ) + self.run_commands = self.mock_run_commands.start() + + self.mock_load_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_banner.load_config", + ) + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestNxosBannerModule, self).tearDown() + self.mock_run_commands.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, device=""): + self.load_config.return_value = dict(diff=None, session="session") + + def test_nxos_banner_exec_create(self): + set_module_args(dict(banner="exec", text="test\nbanner\nstring")) + commands = ["banner exec @\ntest\nbanner\nstring\n@"] + self.run_commands.return_value = commands + self.execute_module(changed=True, commands=commands) + + def test_nxos_banner_exec_remove(self): + set_module_args(dict(banner="exec", state="absent")) + commands = ["no banner exec"] + self.run_commands.return_value = commands + self.execute_module(changed=True, commands=commands) + + def test_nxos_banner_exec_fail_create(self): + set_module_args(dict(banner="exec", text="test\nbanner\nstring")) + commands = ["banner exec @\ntest\nbanner\nstring\n@"] + err_rsp = ["Invalid command"] + self.run_commands.return_value = err_rsp + result = self.execute_module(failed=True, changed=True) + self.assertEqual( + result["msg"], + "banner: exec may not be supported on this platform. Possible values are : exec | motd", + ) + + def test_nxos_banner_exec_fail_remove(self): + set_module_args(dict(banner="exec", state="absent")) + commands = ["no banner exec"] + err_rsp = ["Invalid command"] + self.run_commands.return_value = err_rsp + result = self.execute_module(failed=True, changed=True) + self.assertEqual( + result["msg"], + "banner: exec may not be supported on this platform. Possible values are : exec | motd", + ) + + def test_nxos_banner_motd_create(self): + set_module_args(dict(banner="motd", text="test\nbanner\nstring")) + commands = ["banner motd @\ntest\nbanner\nstring\n@"] + self.run_commands.return_value = commands + self.execute_module(changed=True, commands=commands) + + def test_nxos_banner_motd_remove(self): + set_module_args(dict(banner="motd", state="absent")) + commands = ["no banner motd"] + self.run_commands.return_value = commands + self.execute_module(changed=True, commands=commands) + + def test_nxos_banner_with_preserved_spaces(self): + set_module_args(dict(banner="motd", text=" foo \n")) + commands = ["banner motd @\n foo \n\n@"] + self.run_commands.return_value = commands + self.execute_module(changed=True, commands=commands) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_bfd_global.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_bfd_global.py new file mode 100644 index 00000000..e0e48ac7 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_bfd_global.py @@ -0,0 +1,327 @@ +# (c) 2019 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +# TBD: These imports / import checks are only needed as a workaround for +# shippable, which fails this test due to import yaml & import ordereddict. +import pytest + +from ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.nxos import ( + nxosCmdRef_import_check, +) +from ansible_collections.cisco.nxos.plugins.modules import nxos_bfd_global +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, load_fixture, set_module_args + + +msg = nxosCmdRef_import_check() + + +@pytest.mark.skipif(len(msg), reason=msg) +class TestNxosBfdGlobalModule(TestNxosModule): + module = nxos_bfd_global + + def setUp(self): + super(TestNxosBfdGlobalModule, self).setUp() + + self.mock_load_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_bfd_global.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_execute_show_command = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.nxos.NxosCmdRef.execute_show_command", + ) + self.execute_show_command = self.mock_execute_show_command.start() + + self.mock_get_platform_shortname = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.nxos.NxosCmdRef.get_platform_shortname", + ) + self.get_platform_shortname = self.mock_get_platform_shortname.start() + + def tearDown(self): + super(TestNxosBfdGlobalModule, self).tearDown() + self.mock_load_config.stop() + self.execute_show_command.stop() + self.get_platform_shortname.stop() + + def load_fixtures(self, commands=None, device=""): + self.load_config.return_value = None + + def test_bfd_defaults_n9k(self): + # feature bfd is enabled, no non-defaults are set. + self.execute_show_command.return_value = "feature bfd" + self.get_platform_shortname.return_value = "N9K" + set_module_args( + dict( + echo_interface="deleted", + echo_rx_interval=50, + interval={"tx": 50, "min_rx": 50, "multiplier": 3}, + slow_timer=2000, + startup_timer=5, + ipv4_echo_rx_interval=50, + ipv4_interval={"tx": 50, "min_rx": 50, "multiplier": 3}, + ipv4_slow_timer=2000, + ipv6_echo_rx_interval=50, + ipv6_interval={"tx": 50, "min_rx": 50, "multiplier": 3}, + ipv6_slow_timer=2000, + ), + ) + self.execute_module(changed=False) + + def test_bfd_non_defaults_n9k(self): + # feature bfd is enabled, apply all non-default values. + # This testcase also tests reordering of echo_interface to make sure + # it gets applied last. + self.execute_show_command.return_value = "feature bfd" + self.get_platform_shortname.return_value = "N9K" + set_module_args( + dict( + echo_interface="loopback1", + echo_rx_interval=51, + interval={"tx": 51, "min_rx": 51, "multiplier": 4}, + slow_timer=2001, + startup_timer=6, + ipv4_echo_rx_interval=51, + ipv4_interval={"tx": 51, "min_rx": 51, "multiplier": 4}, + ipv4_slow_timer=2001, + ipv6_echo_rx_interval=51, + ipv6_interval={"tx": 51, "min_rx": 51, "multiplier": 4}, + ipv6_slow_timer=2001, + ), + ) + self.execute_module( + changed=True, + commands=[ + "bfd interval 51 min_rx 51 multiplier 4", + "bfd ipv4 echo-rx-interval 51", + "bfd ipv4 interval 51 min_rx 51 multiplier 4", + "bfd ipv4 slow-timer 2001", + "bfd ipv6 echo-rx-interval 51", + "bfd ipv6 interval 51 min_rx 51 multiplier 4", + "bfd ipv6 slow-timer 2001", + "bfd slow-timer 2001", + "bfd startup-timer 6", + "bfd echo-interface loopback1", + "bfd echo-rx-interval 51", + ], + ) + + def test_bfd_defaults_n3k(self): + # feature bfd is enabled, no non-defaults are set. + self.execute_show_command.return_value = "feature bfd" + self.get_platform_shortname.return_value = "N3K" + set_module_args( + dict( + echo_interface="deleted", + echo_rx_interval=250, + interval={"tx": 250, "min_rx": 250, "multiplier": 3}, + slow_timer=2000, + startup_timer=5, + ipv4_echo_rx_interval=250, + ipv4_interval={"tx": 250, "min_rx": 250, "multiplier": 3}, + ipv4_slow_timer=2000, + ipv6_echo_rx_interval=250, + ipv6_interval={"tx": 250, "min_rx": 250, "multiplier": 3}, + ipv6_slow_timer=2000, + ), + ) + self.execute_module(changed=False) + + def test_bfd_defaults_n35(self): + # feature bfd is enabled, no non-defaults are set. + self.execute_show_command.return_value = "feature bfd" + self.get_platform_shortname.return_value = "N35" + set_module_args( + dict( + echo_interface="deleted", + echo_rx_interval=50, + interval={"tx": 50, "min_rx": 50, "multiplier": 3}, + slow_timer=2000, + startup_timer=5, + ipv4_echo_rx_interval=50, + ipv4_interval={"tx": 50, "min_rx": 50, "multiplier": 3}, + ipv4_slow_timer=2000, + ), + ) + self.execute_module(changed=False) + + def test_bfd_defaults_n6k(self): + # feature bfd is enabled, no non-defaults are set. + self.execute_show_command.return_value = "feature bfd" + self.get_platform_shortname.return_value = "N6K" + set_module_args( + dict( + echo_interface="deleted", + interval={"tx": 50, "min_rx": 50, "multiplier": 3}, + slow_timer=2000, + fabricpath_interval={"tx": 50, "min_rx": 50, "multiplier": 3}, + fabricpath_slow_timer=2000, + fabricpath_vlan=1, + ), + ) + self.execute_module(changed=False) + + def test_bfd_defaults_n7k(self): + # feature bfd is enabled, no non-defaults are set. + self.execute_show_command.return_value = "feature bfd" + self.get_platform_shortname.return_value = "N7K" + set_module_args( + dict( + echo_interface="deleted", + echo_rx_interval=50, + interval={"tx": 50, "min_rx": 50, "multiplier": 3}, + slow_timer=2000, + ipv4_echo_rx_interval=50, + ipv4_interval={"tx": 50, "min_rx": 50, "multiplier": 3}, + ipv4_slow_timer=2000, + ipv6_echo_rx_interval=50, + ipv6_interval={"tx": 50, "min_rx": 50, "multiplier": 3}, + ipv6_slow_timer=2000, + fabricpath_interval={"tx": 50, "min_rx": 50, "multiplier": 3}, + fabricpath_slow_timer=2000, + fabricpath_vlan=1, + ), + ) + self.execute_module(changed=False) + + def test_bfd_existing_n9k(self): + module_name = self.module.__name__.rsplit(".", 1)[1] + self.execute_show_command.return_value = load_fixture(module_name, "N9K.cfg") + self.get_platform_shortname.return_value = "N9K" + set_module_args( + dict( + echo_interface="deleted", + echo_rx_interval=51, + interval={"tx": 51, "min_rx": 51, "multiplier": 3}, + slow_timer=2000, + startup_timer=5, + ipv4_echo_rx_interval=50, + ipv4_interval={"tx": 51, "min_rx": 51, "multiplier": 3}, + ipv4_slow_timer=2000, + ipv6_echo_rx_interval=50, + ipv6_interval={"tx": 51, "min_rx": 51, "multiplier": 3}, + ipv6_slow_timer=2000, + ), + ) + self.execute_module( + changed=True, + commands=[ + "no bfd echo-interface loopback2", + "bfd echo-rx-interval 51", + "bfd interval 51 min_rx 51 multiplier 3", + "bfd slow-timer 2000", + "bfd startup-timer 5", + "bfd ipv4 echo-rx-interval 50", + "bfd ipv4 interval 51 min_rx 51 multiplier 3", + "bfd ipv4 slow-timer 2000", + "bfd ipv6 echo-rx-interval 50", + "bfd ipv6 interval 51 min_rx 51 multiplier 3", + "bfd ipv6 slow-timer 2000", + ], + ) + + def test_bfd_idempotence_n9k(self): + module_name = self.module.__name__.rsplit(".", 1)[1] + self.execute_show_command.return_value = load_fixture(module_name, "N9K.cfg") + self.get_platform_shortname.return_value = "N9K" + set_module_args( + dict( + echo_interface="loopback2", + echo_rx_interval=56, + interval={"tx": 51, "min_rx": 52, "multiplier": 4}, + slow_timer=2001, + startup_timer=6, + ipv4_echo_rx_interval=54, + ipv4_interval={"tx": 54, "min_rx": 54, "multiplier": 4}, + ipv4_slow_timer=2004, + ipv6_echo_rx_interval=56, + ipv6_interval={"tx": 56, "min_rx": 56, "multiplier": 6}, + ipv6_slow_timer=2006, + ), + ) + self.execute_module(changed=False) + + def test_bfd_existing_n7k(self): + module_name = self.module.__name__.rsplit(".", 1)[1] + self.execute_show_command.return_value = load_fixture(module_name, "N7K.cfg") + self.get_platform_shortname.return_value = "N7K" + set_module_args( + dict( + echo_interface="deleted", + echo_rx_interval=51, + interval={"tx": 51, "min_rx": 51, "multiplier": 3}, + slow_timer=2002, + ipv4_echo_rx_interval=51, + ipv4_interval={"tx": 51, "min_rx": 51, "multiplier": 3}, + ipv4_slow_timer=2002, + ipv6_echo_rx_interval=51, + ipv6_interval={"tx": 51, "min_rx": 51, "multiplier": 3}, + ipv6_slow_timer=2002, + fabricpath_interval={"tx": 51, "min_rx": 51, "multiplier": 3}, + fabricpath_slow_timer=2003, + fabricpath_vlan=3, + ), + ) + self.execute_module( + changed=True, + commands=[ + "no bfd echo-interface loopback2", + "bfd echo-rx-interval 51", + "bfd interval 51 min_rx 51 multiplier 3", + "bfd slow-timer 2002", + "bfd ipv4 echo-rx-interval 51", + "bfd ipv4 interval 51 min_rx 51 multiplier 3", + "bfd ipv4 slow-timer 2002", + "bfd ipv6 echo-rx-interval 51", + "bfd ipv6 interval 51 min_rx 51 multiplier 3", + "bfd ipv6 slow-timer 2002", + "bfd fabricpath interval 51 min_rx 51 multiplier 3", + "bfd fabricpath slow-timer 2003", + "bfd fabricpath vlan 3", + ], + ) + + def test_bfd_idempotence_n7k(self): + module_name = self.module.__name__.rsplit(".", 1)[1] + self.execute_show_command.return_value = load_fixture(module_name, "N7K.cfg") + self.get_platform_shortname.return_value = "N7K" + set_module_args( + dict( + echo_interface="loopback2", + echo_rx_interval=56, + interval={"tx": 51, "min_rx": 52, "multiplier": 4}, + slow_timer=2001, + ipv4_echo_rx_interval=54, + ipv4_interval={"tx": 54, "min_rx": 54, "multiplier": 4}, + ipv4_slow_timer=2004, + ipv6_echo_rx_interval=56, + ipv6_interval={"tx": 56, "min_rx": 56, "multiplier": 6}, + ipv6_slow_timer=2006, + fabricpath_interval={"tx": 58, "min_rx": 58, "multiplier": 8}, + fabricpath_slow_timer=2008, + fabricpath_vlan=2, + ), + ) + self.execute_module(changed=False) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_bfd_interfaces.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_bfd_interfaces.py new file mode 100644 index 00000000..e40f5fc2 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_bfd_interfaces.py @@ -0,0 +1,338 @@ +# (c) 2019 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from textwrap import dedent + +from ansible_collections.cisco.nxos.plugins.modules import nxos_bfd_interfaces +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, set_module_args + + +ignore_provider_arg = True + + +class TestNxosBfdInterfacesModule(TestNxosModule): + module = nxos_bfd_interfaces + + def setUp(self): + super(TestNxosBfdInterfacesModule, self).setUp() + + self.mock_FACT_LEGACY_SUBSETS = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.facts.facts.FACT_LEGACY_SUBSETS", + ) + self.FACT_LEGACY_SUBSETS = self.mock_FACT_LEGACY_SUBSETS.start() + + self.mock_get_resource_connection_config = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base.get_resource_connection", + ) + self.get_resource_connection_config = self.mock_get_resource_connection_config.start() + + self.mock_get_resource_connection_facts = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection", + ) + self.get_resource_connection_facts = self.mock_get_resource_connection_facts.start() + + self.mock_edit_config = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.config.bfd_interfaces.bfd_interfaces.Bfd_interfaces.edit_config", + ) + self.edit_config = self.mock_edit_config.start() + + def tearDown(self): + super(TestNxosBfdInterfacesModule, self).tearDown() + self.mock_FACT_LEGACY_SUBSETS.stop() + self.mock_get_resource_connection_config.stop() + self.mock_get_resource_connection_facts.stop() + self.mock_edit_config.stop() + + def load_fixtures(self, commands=None, device=""): + self.mock_FACT_LEGACY_SUBSETS.return_value = dict() + self.get_resource_connection_config.return_value = None + self.edit_config.return_value = None + + # --------------------------- + # Bfd_interfaces Test Cases + # --------------------------- + + # 'state' logic behaviors + # + # - 'merged' : Update existing device state with any differences in the play. + # - 'deleted' : Reset existing device state to default values. Ignores any + # play attrs other than 'name'. Scope is limited to interfaces + # in the play. + # - 'overridden': The play is the source of truth. Similar to replaced but the + # scope includes all interfaces; ie. it will also reset state + # on interfaces not found in the play. + # - 'replaced' : Scope is limited to the interfaces in the play. + + SHOW_CMD = "show running-config | section '^interface|^feature bfd'" + + def test_1(self): + # Setup: No BFD configs shown on device interfaces + # NOTE: The bfd 'enable' state is the default and does not nvgen. + existing = dedent( + """\ + feature bfd + interface Ethernet1/1 + interface Ethernet1/2 + interface Ethernet1/3 + """, + ) + self.get_resource_connection_facts.return_value = {self.SHOW_CMD: existing} + playbook = dict( + config=[ + dict(name="Ethernet1/1", bfd="disable", echo="disable"), + dict(name="Ethernet1/2", bfd="disable"), + ], + ) + # Expected result commands for each 'state' + merged = [ + "interface Ethernet1/1", + "no bfd", + "no bfd echo", + "interface Ethernet1/2", + "no bfd", + ] + deleted = [] + overridden = merged + replaced = merged + + playbook["state"] = "merged" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=merged) + + playbook["state"] = "deleted" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=False, commands=deleted) + + playbook["state"] = "overridden" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=overridden) + + playbook["state"] = "replaced" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=replaced) + + def test_2(self): + # Change existing BFD configs + existing = dedent( + """\ + feature bfd + interface Ethernet1/1 + no bfd + interface Ethernet1/2 + no bfd echo + interface Ethernet1/3 + no bfd + no bfd echo + """, + ) + self.get_resource_connection_facts.return_value = {self.SHOW_CMD: existing} + playbook = dict( + config=[ + dict(name="Ethernet1/1", bfd="enable", echo="disable"), + dict(name="Ethernet1/2"), + # Eth1/3 not present! Thus overridden should set Eth1/3 to defaults; + # replaced should ignore Eth1/3. + ], + ) + # Expected result commands for each 'state' + merged = ["interface Ethernet1/1", "bfd", "no bfd echo"] + deleted = [ + "interface Ethernet1/1", + "bfd", + "interface Ethernet1/2", + "bfd echo", + ] + overridden = [ + "interface Ethernet1/3", + "bfd", + "bfd echo", + "interface Ethernet1/1", + "bfd", + "no bfd echo", + "interface Ethernet1/2", + "bfd echo", + ] + replaced = [ + "interface Ethernet1/1", + "bfd", + "no bfd echo", + "interface Ethernet1/2", + "bfd echo", + ] + + playbook["state"] = "merged" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=merged) + + playbook["state"] = "deleted" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=deleted) + + playbook["state"] = "overridden" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=overridden) + + playbook["state"] = "replaced" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=replaced) + + def test_3(self): + # Device has bfd configs, playbook has no values + existing = dedent( + """\ + feature bfd + interface Ethernet1/1 + no bfd + interface Ethernet1/2 + no bfd echo + interface Ethernet1/3 + no bfd + no bfd echo + """, + ) + self.get_resource_connection_facts.return_value = {self.SHOW_CMD: existing} + playbook = dict(config=[dict(name="Ethernet1/1")]) + # Expected result commands for each 'state' + merged = [] + deleted = ["interface Ethernet1/1", "bfd"] + overridden = [ + "interface Ethernet1/1", + "bfd", + "interface Ethernet1/2", + "bfd echo", + "interface Ethernet1/3", + "bfd", + "bfd echo", + ] + replaced = ["interface Ethernet1/1", "bfd"] + + playbook["state"] = "merged" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=False, commands=merged) + + playbook["state"] = "deleted" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=deleted) + + playbook["state"] = "overridden" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=overridden) + + playbook["state"] = "replaced" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=replaced) + + def test_4(self): + # Test with interface that doesn't exist yet + existing = dedent( + """\ + feature bfd + interface Ethernet1/1 + no bfd + """, + ) + self.get_resource_connection_facts.return_value = {self.SHOW_CMD: existing} + playbook = dict(config=[dict(name="Ethernet1/1.42", bfd="enable", echo="disable")]) + # Expected result commands for each 'state' + merged = ["interface Ethernet1/1.42", "bfd", "no bfd echo"] + deleted = [] + overridden = [ + "interface Ethernet1/1.42", + "bfd", + "no bfd echo", + "interface Ethernet1/1", + "bfd", + ] + replaced = ["interface Ethernet1/1.42", "bfd", "no bfd echo"] + + playbook["state"] = "merged" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=merged) + + playbook["state"] = "deleted" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=False, commands=deleted) + + playbook["state"] = "overridden" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=overridden) + + playbook["state"] = "replaced" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=replaced) + + def test_5(self): + # idempotence + existing = dedent( + """\ + feature bfd + interface Ethernet1/1 + no bfd + no bfd echo + interface Ethernet1/2 + """, + ) + self.get_resource_connection_facts.return_value = {self.SHOW_CMD: existing} + playbook = dict( + config=[ + dict(name="Ethernet1/1", bfd="disable", echo="disable"), + dict(name="Ethernet1/2", bfd="enable", echo="enable"), + ], + ) + # Expected result commands for each 'state' + merged = [] + deleted = ["interface Ethernet1/1", "bfd", "bfd echo"] + overridden = [] + replaced = [] + + playbook["state"] = "merged" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=False, commands=merged) + + playbook["state"] = "deleted" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=deleted) + + playbook["state"] = "overridden" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=False, commands=overridden) + + playbook["state"] = "replaced" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=False, commands=replaced) + + +def build_args(data, type, state=None, check_mode=None): + if state is None: + state = "merged" + if check_mode is None: + check_mode = False + args = { + "state": state, + "_ansible_check_mode": check_mode, + "config": {type: data}, + } + return args diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_bgp.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_bgp.py new file mode 100644 index 00000000..9c57817c --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_bgp.py @@ -0,0 +1,150 @@ +# (c) 2016 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from ansible_collections.cisco.nxos.plugins.modules import nxos_bgp +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, load_fixture, set_module_args + + +class TestNxosBgpModule(TestNxosModule): + module = nxos_bgp + + def setUp(self): + super(TestNxosBgpModule, self).setUp() + + self.mock_load_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_bgp.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_get_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_bgp.get_config", + ) + self.get_config = self.mock_get_config.start() + + def tearDown(self): + super(TestNxosBgpModule, self).tearDown() + self.mock_load_config.stop() + self.mock_get_config.stop() + + def load_fixtures(self, commands=None, device=""): + self.get_config.return_value = load_fixture("nxos_bgp", "config.cfg") + self.load_config.return_value = [] + + def test_nxos_bgp(self): + set_module_args(dict(asn=65535, router_id="192.0.2.1")) + result = self.execute_module(changed=True) + self.assertEqual(result["commands"], ["router bgp 65535", "router-id 192.0.2.1"]) + + def test_nxos_bgp_change_nothing(self): + set_module_args(dict(asn=65535, router_id="192.168.1.1")) + self.execute_module(changed=False) + + def test_nxos_bgp_wrong_asn(self): + set_module_args(dict(asn=10, router_id="192.168.1.1")) + result = self.execute_module(failed=True) + self.assertEqual(result["msg"], "Another BGP ASN already exists.") + + def test_nxos_bgp_remove(self): + set_module_args(dict(asn=65535, state="absent")) + self.execute_module(changed=True, commands=["no router bgp 65535"]) + + def test_nxos_bgp_remove_vrf(self): + set_module_args(dict(asn=65535, vrf="test2", state="absent")) + self.execute_module(changed=True, commands=["router bgp 65535", "no vrf test2"]) + + def test_nxos_bgp_remove_nonexistant_vrf(self): + set_module_args(dict(asn=65535, vrf="foo", state="absent")) + self.execute_module(changed=False) + + def test_nxos_bgp_remove_wrong_asn(self): + set_module_args(dict(asn=10, state="absent")) + self.execute_module(changed=False) + + def test_nxos_bgp_vrf(self): + set_module_args(dict(asn=65535, vrf="test", router_id="192.0.2.1")) + result = self.execute_module( + changed=True, + commands=["router bgp 65535", "vrf test", "router-id 192.0.2.1"], + ) + self.assertEqual(result["warnings"], ["VRF test doesn't exist."]) + + def test_nxos_bgp_global_param(self): + set_module_args(dict(asn=65535, shutdown=True)) + self.execute_module(changed=True, commands=["router bgp 65535", "shutdown"]) + + def test_nxos_bgp_global_param_outside_default(self): + set_module_args(dict(asn=65535, vrf="test", shutdown=True)) + result = self.execute_module(failed=True) + self.assertEqual( + result["msg"], + 'Global params can be modified only under "default" VRF.', + ) + + def test_nxos_bgp_default_value(self): + set_module_args(dict(asn=65535, graceful_restart_timers_restart="default")) + self.execute_module( + changed=True, + commands=["router bgp 65535", "graceful-restart restart-time 120"], + ) + + +class TestNxosBgp32BitsAS(TestNxosModule): + module = nxos_bgp + + def setUp(self): + super(TestNxosBgp32BitsAS, self).setUp() + + self.mock_load_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_bgp.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_get_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_bgp.get_config", + ) + self.get_config = self.mock_get_config.start() + + def tearDown(self): + super(TestNxosBgp32BitsAS, self).tearDown() + self.mock_load_config.stop() + self.mock_get_config.stop() + + def load_fixtures(self, commands=None, device=""): + self.get_config.return_value = load_fixture("nxos_bgp", "config_32_bits_as.cfg") + self.load_config.return_value = [] + + def test_nxos_bgp_change_nothing(self): + set_module_args(dict(asn="65535.65535", router_id="192.168.1.1")) + self.execute_module(changed=False) + + def test_nxos_bgp_wrong_asn(self): + set_module_args(dict(asn="65535.10", router_id="192.168.1.1")) + result = self.execute_module(failed=True) + self.assertEqual(result["msg"], "Another BGP ASN already exists.") + + def test_nxos_bgp_remove(self): + set_module_args(dict(asn="65535.65535", state="absent")) + self.execute_module(changed=True, commands=["no router bgp 65535.65535"]) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_bgp_address_family.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_bgp_address_family.py new file mode 100644 index 00000000..d9c6c235 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_bgp_address_family.py @@ -0,0 +1,2442 @@ +# (c) 2021 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from textwrap import dedent + +from ansible_collections.cisco.nxos.plugins.modules import nxos_bgp_address_family +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, set_module_args + + +ignore_provider_arg = True + + +class TestNxosBGPAddressFamilyModule(TestNxosModule): + # Testing strategy + # ------------------ + # (a) The unit tests cover `merged` and `replaced` for every attribute. + # Since `overridden` is essentially `replaced` but at a larger + # scale, these indirectly cover `overridden` as well. + # (b) For linear attributes replaced is not valid and hence, those tests + # delete the attributes from the config subsection. + # (c) The argspec for VRFs is same as the top-level spec and the config logic + # is re-used. Hence, those attributes are not explictly covered. However, a + # combination of VRF + top-level spec + AF is tested. + + module = nxos_bgp_address_family + + def setUp(self): + super(TestNxosBGPAddressFamilyModule, self).setUp() + + self.mock_get_resource_connection = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module_base.get_resource_connection", + ) + self.get_resource_connection = self.mock_get_resource_connection.start() + + self.mock_get_config = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.facts.bgp_address_family.bgp_address_family.Bgp_address_familyFacts.get_config", + ) + self.get_config = self.mock_get_config.start() + + def tearDown(self): + super(TestNxosBGPAddressFamilyModule, self).tearDown() + self.get_resource_connection.stop() + self.get_config.stop() + + def test_nxos_bgp_additional_paths_merged(self): + # test merged for config->address_family->additional_paths + self.get_config.return_value = dedent( + """\ + router bgp 65563 + vrf site-1 + address-family ipv4 unicast + additional-paths install backup + additional-paths send + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + additional_paths=dict( + install_backup=True, + receive=True, + selection=dict(route_map="rmap1"), + send=True, + ), + ), + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + additional_paths=dict( + install_backup=False, + receive=True, + selection=dict(route_map="rmap2"), + send=False, + ), + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "address-family ipv4 multicast", + "additional-paths install backup", + "additional-paths receive", + "additional-paths selection route-map rmap1", + "additional-paths send", + "vrf site-1", + "address-family ipv4 unicast", + "no additional-paths install backup", + "additional-paths receive", + "additional-paths selection route-map rmap2", + "no additional-paths send", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_additional_paths_replaced(self): + # test replaced for config->address_family->additional_paths + self.get_config.return_value = dedent( + """\ + router bgp 65563 + address-family ipv4 multicast + additional-paths install backup + additional-paths receive + additional-paths selection route-map rmap1 + additional-paths send + vrf site-1 + address-family ipv4 unicast + additional-paths send + vrf site-2 + address-family ipv6 multicast + additional-paths receive + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + additional_paths=dict(selection=dict(route_map="rmap1")), + ), + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + additional_paths=dict(install_backup=True), + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "address-family ipv4 multicast", + "no additional-paths install backup", + "no additional-paths receive", + "no additional-paths send", + "vrf site-1", + "address-family ipv4 unicast", + "additional-paths install backup", + "no additional-paths send", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_l2vpn_keys_merged(self): + # test merged for config->address_family->advertise_pip, advertise_system_mac, allow_vni_in_ethertag + self.get_config.return_value = dedent( + """\ + router bgp 65563 + address-family l2vpn evpn + advertise-pip + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict( + afi="l2vpn", + safi="evpn", + advertise_pip=False, + advertise_system_mac=True, + allow_vni_in_ethertag=True, + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "address-family l2vpn evpn", + "no advertise-pip", + "advertise-system-mac", + "allow-vni-in-ethertag", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_l2vpn_keys_replaced(self): + # test replaced for config->address_family->advertise_pip, advertise_system_mac, allow_vni_in_ethertag + self.get_config.return_value = dedent( + """\ + router bgp 65563 + address-family l2vpn evpn + advertise-system-mac + allow-vni-in-ethertag + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[dict(afi="l2vpn", safi="evpn", advertise_pip=True)], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "address-family l2vpn evpn", + "advertise-pip", + "no advertise-system-mac", + "no allow-vni-in-ethertag", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_client_to_client_merged(self): + # test merged for config->address_family->client_to_client + self.get_config.return_value = dedent( + """\ + router bgp 65563 + vrf site-1 + address-family ipv4 unicast + no client-to-client reflection + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + client_to_client=dict(no_reflection=True), + ), + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + client_to_client=dict(no_reflection=False), + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "address-family ipv4 multicast", + "no client-to-client reflection", + "vrf site-1", + "address-family ipv4 unicast", + "client-to-client reflection", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_client_to_client_replaced(self): + # test replaced for config->address_family->client_to_client + self.get_config.return_value = dedent( + """\ + router bgp 65563 + address-family ipv4 unicast + no client-client reflection + address-family ipv4 multicast + vrf site-1 + address-family ipv4 unicast + no client-to-client reflection + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + client_to_client=dict(no_reflection=True), + ), + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + client_to_client=dict(no_reflection=True), + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "address-family ipv4 multicast", + "client-to-client reflection", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_aggregate_address_merged(self): + # test merged for config->address_family->aggregate_address + self.get_config.return_value = dedent( + """\ + router bgp 65563 + vrf site-1 + address-family ipv4 unicast + aggregate-address 192.168.1.0/24 as-set + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + aggregate_address=[ + dict(prefix="192.168.1.0/24", summary_only=True), + dict( + prefix="192.168.2.0/24", + advertise_map="rmap1", + as_set=True, + attribute_map="rmap2", + ), + dict( + prefix="192.168.3.0/24", + suppress_map="rmap3", + ), + ], + ), + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + aggregate_address=[ + dict(prefix="10.0.0.0/8", summary_only=True), + dict( + prefix="11.0.0.0/8", + advertise_map="rmap1", + as_set=True, + attribute_map="rmap2", + ), + ], + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "address-family ipv4 multicast", + "aggregate-address 192.168.1.0/24 summary-only", + "aggregate-address 192.168.2.0/24 advertise-map rmap1 as-set attribute-map rmap2", + "aggregate-address 192.168.3.0/24 suppress-map rmap3", + "vrf site-1", + "address-family ipv4 unicast", + "aggregate-address 10.0.0.0/8 summary-only", + "aggregate-address 11.0.0.0/8 advertise-map rmap1 as-set attribute-map rmap2", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_aggregate_address_replaced(self): + # test replaced for config->address_family->aggregate_address + self.get_config.return_value = dedent( + """\ + router bgp 65563 + address-family ipv4 multicast + aggregate-address 192.168.1.0/24 summary-only + aggregate-address 192.168.2.0/24 advertise-map rmap1 as-set attribute-map rmap2 + aggregate-address 192.168.3.0/24 suppress-map rmap3 + address-family ipv4 unicast + aggregate-address 192.168.4.0/24 summary-only + vrf site-1 + address-family ipv4 unicast + aggregate-address 10.0.0.0/8 summary-only + aggregate-address 11.0.0.0/8 advertise-map rmap1 as-set attribute-map rmap2 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + aggregate_address=[ + dict( + prefix="192.168.2.0/24", + advertise_map="rmap1", + as_set=True, + attribute_map="rmap2", + ), + ], + ), + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + aggregate_address=[ + dict(prefix="12.0.0.0/8", summary_only=True), + dict( + prefix="14.0.0.0/8", + advertise_map="rmap1", + as_set=True, + attribute_map="rmap3", + ), + ], + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "address-family ipv4 multicast", + "aggregate-address 192.168.2.0/24 advertise-map rmap1 as-set attribute-map rmap2", + "no aggregate-address 192.168.1.0/24 summary-only", + "no aggregate-address 192.168.3.0/24 suppress-map rmap3", + "vrf site-1", + "address-family ipv4 unicast", + "no aggregate-address 10.0.0.0/8 summary-only", + "aggregate-address 12.0.0.0/8 summary-only", + "aggregate-address 14.0.0.0/8 advertise-map rmap1 as-set attribute-map rmap3", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_dampen_igp_metric_merged(self): + # test merged for config->address_family->dampen_igp_metric + self.get_config.return_value = dedent( + """\ + router bgp 65563 + vrf site-1 + address-family ipv4 unicast + dampen-igp-metric 1200 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict(afi="ipv4", safi="multicast", dampen_igp_metric=300), + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + dampen_igp_metric=1800, + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "address-family ipv4 multicast", + "dampen-igp-metric 300", + "vrf site-1", + "address-family ipv4 unicast", + "dampen-igp-metric 1800", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_dampen_igp_metric_replaced(self): + # test merged for config->address_family->dampen_igp_metric + self.get_config.return_value = dedent( + """\ + router bgp 65563 + address-family ipv4 multicast + dampen-igp-metric 300 + vrf site-1 + address-family ipv4 unicast + dampen-igp-metric 1800 + address-family ipv6 unicast + dampen-igp-metric 1200 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict(afi="ipv4", safi="multicast"), + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + dampen_igp_metric=1800, + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "address-family ipv4 multicast", + "no dampen-igp-metric 300", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_dampening_merged(self): + # test merged for config->address_family->dampening + self.get_config.return_value = dedent( + """\ + router bgp 65563 + address-family ipv4 unicast + dampening + vrf site-1 + address-family ipv4 unicast + dampening 3 22 23 23 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict( + afi="ipv4", + safi="unicast", + dampening=dict(set=False), + ), + dict( + afi="ipv4", + safi="multicast", + dampening=dict( + decay_half_life=4, + start_reuse_route=23, + start_suppress_route=24, + max_suppress_time=25, + ), + ), + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + dampening=dict( + decay_half_life=3, + start_reuse_route=22, + start_suppress_route=23, + max_suppress_time=24, + ), + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "address-family ipv4 unicast", + "no dampening", + "address-family ipv4 multicast", + "dampening 4 23 24 25", + "vrf site-1", + "address-family ipv4 unicast", + "dampening 3 22 23 24", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_dampening_replaced(self): + # test replaced for config->address_family->dampening + self.get_config.return_value = dedent( + """\ + router bgp 65563 + address-family ipv4 multicast + dampening 4 23 24 25 + address-family ipv4 unicast + dampening 4 23 25 27 + vrf site-1 + address-family ipv4 unicast + dampening 3 22 23 23 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict(afi="ipv4", safi="multicast"), + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + dampening=dict( + decay_half_life=3, + start_reuse_route=22, + start_suppress_route=23, + max_suppress_time=23, + ), + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "address-family ipv4 multicast", + "no dampening 4 23 24 25", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_dampening_route_map_merged(self): + # test merged for config->address_family->dampening->route_map + self.get_config.return_value = dedent( + """\ + router bgp 65563 + vrf site-1 + address-family ipv4 unicast + dampening route-map rmap1 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + dampening=dict(route_map="rmap3"), + ), + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + dampening=dict(route_map="rmap2"), + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "address-family ipv4 multicast", + "dampening route-map rmap3", + "vrf site-1", + "address-family ipv4 unicast", + "dampening route-map rmap2", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_dampening_route_map_replaced(self): + # test replaced for config->address_family->dampening->route_map + self.get_config.return_value = dedent( + """\ + router bgp 65563 + address-family ipv4 multicast + dampening route-map rmap3 + vrf site-1 + address-family ipv4 unicast + dampening route-map rmap1 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + dampening=dict(route_map="rmap3"), + ), + dict(vrf="site-1", afi="ipv4", safi="unicast"), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "vrf site-1", + "address-family ipv4 unicast", + "no dampening route-map rmap1", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_default_information_merged(self): + # test merged for config->address_family->default_information + self.get_config.return_value = dedent( + """\ + router bgp 65563 + vrf site-1 + address-family ipv4 unicast + default-information originate + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + default_information=dict(originate=True), + ), + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + default_information=dict(originate=False), + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "address-family ipv4 multicast", + "default-information originate", + "vrf site-1", + "address-family ipv4 unicast", + "no default-information originate", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_default_information_replaced(self): + # test replaced for config->address_family->default_information + self.get_config.return_value = dedent( + """\ + router bgp 65563 + address-family ipv4 multicast + default-information originate + vrf site-1 + address-family ipv4 unicast + default-information originate + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict(afi="ipv4", safi="multicast"), + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + default_information=dict(originate=True), + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "address-family ipv4 multicast", + "no default-information originate", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_default_metric_merged(self): + # test merged for config->address_family->default_metric + self.get_config.return_value = dedent( + """\ + router bgp 65563 + vrf site-1 + address-family ipv4 unicast + default-metric 6400 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict(afi="ipv4", safi="multicast", default_metric=7200), + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + default_metric=10000, + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "address-family ipv4 multicast", + "default-metric 7200", + "vrf site-1", + "address-family ipv4 unicast", + "default-metric 10000", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_default_metric_replaced(self): + # test replaced for config->address_family->default_metric + self.get_config.return_value = dedent( + """\ + router bgp 65563 + address-family ipv4 multicast + default-metric 7200 + addres-family ipv6 unicast + default-metric 8400 + vrf site-1 + address-family ipv4 unicast + default-metric 6400 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict(afi="ipv4", safi="multicast"), + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + default_metric=6400, + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "address-family ipv4 multicast", + "no default-metric 8400", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_distance_merged(self): + # test merged for config->address_family->distance + self.get_config.return_value = dedent( + """\ + router bgp 65563 + vrf site-1 + address-family ipv4 unicast + distance 20 18 2 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + distance=dict(ebgp_routes=25, ibgp_routes=12, local_routes=4), + ), + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + distance=dict(ebgp_routes=20, ibgp_routes=18, local_routes=3), + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "address-family ipv4 multicast", + "distance 25 12 4", + "vrf site-1", + "address-family ipv4 unicast", + "distance 20 18 3", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_distance_replaced(self): + # test replaced for config->address_family->distance + self.get_config.return_value = dedent( + """\ + router bgp 65563 + address-family ipv4 multicast + distance 25 12 4 + address-family ipv4 unicast + distance 26 12 4 + vrf site-1 + address-family ipv4 unicast + distance 20 18 2 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict(afi="ipv4", safi="multicast"), + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + distance=dict(ebgp_routes=20, ibgp_routes=18, local_routes=2), + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "address-family ipv4 multicast", + "no distance 25 12 4", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_export_gateway_ip_merged(self): + # test merged for config->address_family->export_gateway_ip + self.get_config.return_value = dedent( + """\ + router bgp 65563 + vrf site-1 + address-family ipv4 unicast + export-gateway-ip + vrf site-2 + address-family ipv4 unicast + export-gateway-ip + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + export_gateway_ip=False, + ), + dict( + vrf="site-1", + afi="ipv4", + safi="multicast", + export_gateway_ip=True, + ), + dict( + vrf="site-2", + afi="ipv4", + safi="multicast", + export_gateway_ip=True, + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "vrf site-1", + "address-family ipv4 unicast", + "no export-gateway-ip", + "address-family ipv4 multicast", + "export-gateway-ip", + "vrf site-2", + "address-family ipv4 multicast", + "export-gateway-ip", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_export_gateway_ip_replaced(self): + # test replaced for config->address_family->export_gateway_ip + self.get_config.return_value = dedent( + """\ + router bgp 65563 + vrf site-1 + address-family ipv4 unicast + export-gateway-ip + address-family ipv4 multicast + export-gateway-ip + vrf site-2 + address-family ipv4 unicast + export-gateway-ip + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + export_gateway_ip=False, + ), + dict(vrf="site-1", afi="ipv4", safi="multicast"), + dict( + vrf="site-2", + afi="ipv4", + safi="unicast", + export_gateway_ip=True, + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "vrf site-1", + "address-family ipv4 unicast", + "no export-gateway-ip", + "address-family ipv4 multicast", + "no export-gateway-ip", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_inject_map_merged(self): + # test merged for config->address_family->inject_map + self.get_config.return_value = dedent( + """\ + router bgp 65563 + vrf site-1 + address-family ipv4 unicast + inject-map rmap1 exist-map rmap2 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + inject_map=[ + dict( + route_map="rmap1", + exist_map="rmap2", + copy_attributes=True, + ), + dict(route_map="rmap1", exist_map="rmap3"), + ], + ), + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + inject_map=[ + dict( + route_map="rmap3", + exist_map="rmap4", + copy_attributes=True, + ), + ], + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "address-family ipv4 multicast", + "inject-map rmap1 exist-map rmap2 copy-attributes", + "inject-map rmap1 exist-map rmap3", + "vrf site-1", + "address-family ipv4 unicast", + "inject-map rmap3 exist-map rmap4 copy-attributes", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_inject_map_replaced(self): + # test replaced for config->address_family->inject_map + self.get_config.return_value = dedent( + """\ + router bgp 65563 + address-family ipv4 multicast + inject-map rmap1 exist-map rmap2 copy-attributes + inject-map rmap1 exist-map rmap3 + vrf site-1 + address-family ipv4 unicast + inject-map rmap3 exist-map rmap4 copy-attributes + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + inject_map=[dict(route_map="rmap1", exist_map="rmap3")], + ), + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + inject_map=[ + dict( + route_map="rmap3", + exist_map="rmap4", + copy_attributes=True, + ), + ], + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "address-family ipv4 multicast", + "no inject-map rmap1 exist-map rmap2 copy-attributes", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_maximum_paths_merged(self): + # test merged for config->address_family->maximum_paths + self.get_config.return_value = dedent( + """\ + router bgp 65563 + address-family ipv4 multicast + maximum-paths 12 + vrf site-1 + address-family ipv4 unicast + maximum-paths 14 + maximum-paths eibgp 64 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + maximum_paths=dict(parallel_paths=15, ibgp=dict(parallel_paths=64)), + ), + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + maximum_paths=dict( + parallel_paths=14, + eibgp=dict(parallel_paths=68), + local=dict(parallel_paths=30), + ), + ), + dict( + vrf="site-1", + afi="ipv4", + safi="multicast", + maximum_paths=dict(mixed=dict(parallel_paths=40)), + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "address-family ipv4 multicast", + "maximum-paths 15", + "maximum-paths ibgp 64", + "vrf site-1", + "address-family ipv4 unicast", + "maximum-paths eibgp 68", + "maximum-paths local 30", + "address-family ipv4 multicast", + "maximum-paths mixed 40", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_maximum_paths_replaced(self): + # test replaced for config->address_family->maximum_paths + self.get_config.return_value = dedent( + """\ + router bgp 65563 + address-family ipv4 multicast + maximum-paths 15 + maximum-paths ibgp 64 + vrf site-1 + address-family ipv4 unicast + maximum-paths eibgp 68 + maximum-paths local 30 + address-family ipv4 multicast + maximum-paths mixed 40 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + maximum_paths=dict(parallel_paths=15, ibgp=dict(parallel_paths=64)), + ), + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + maximum_paths=dict(local=dict(parallel_paths=30)), + ), + dict(vrf="site-1", afi="ipv4", safi="multicast"), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "vrf site-1", + "address-family ipv4 unicast", + "no maximum-paths eibgp 68", + "address-family ipv4 multicast", + "no maximum-paths mixed 40", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_network_merged(self): + # test merged for config->address_family->network + self.get_config.return_value = dedent( + """\ + router bgp 65563 + vrf site-1 + address-family ipv4 unicast + network 192.168.1.0/24 route-map rmap1 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + networks=[ + dict(prefix="192.168.1.0/24", route_map="rmap2"), + dict(prefix="192.168.2.0/24"), + dict(prefix="192.168.3.0/24", route_map="rmap3"), + ], + ), + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + networks=[ + dict(prefix="10.0.0.0/8"), + dict(prefix="11.0.0.0/8", route_map="rmap2"), + ], + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "address-family ipv4 multicast", + "network 192.168.1.0/24 route-map rmap2", + "network 192.168.2.0/24", + "network 192.168.3.0/24 route-map rmap3", + "vrf site-1", + "address-family ipv4 unicast", + "network 10.0.0.0/8", + "network 11.0.0.0/8 route-map rmap2", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_network_replaced(self): + # test replaced for config->address_family->network + self.get_config.return_value = dedent( + """\ + router bgp 65563 + address-family ipv4 multicast + network 192.168.1.0/24 route-map rmap2 + network 192.168.2.0/24 + network 192.168.3.0/24 route-map rmap3 + vrf site-1 + address-family ipv4 unicast + network 10.0.0.0/8 + network 11.0.0.0/8 route-map rmap2 + network 192.168.1.0/24 route-map rmap1 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + networks=[dict(prefix="192.168.3.0/24", route_map="rmap4")], + ), + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + networks=[dict(prefix="11.0.0.0/8", route_map="rmap2")], + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "address-family ipv4 multicast", + "no network 192.168.1.0/24 route-map rmap2", + "no network 192.168.2.0/24", + "network 192.168.3.0/24 route-map rmap4", + "vrf site-1", + "address-family ipv4 unicast", + "no network 10.0.0.0/8", + "no network 192.168.1.0/24 route-map rmap1", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_nexthop_merged(self): + # test merged for config->address_family->network + self.get_config.return_value = dedent( + """\ + router bgp 65563 + vrf site-1 + address-family ipv4 unicast + nexthop route-map rmap2 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + nexthop=dict( + route_map="rmap1", + trigger_delay=dict(critical_delay=120, non_critical_delay=180), + ), + ), + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + nexthop=dict( + trigger_delay=dict(critical_delay=110, non_critical_delay=170), + ), + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "address-family ipv4 multicast", + "nexthop route-map rmap1", + "nexthop trigger-delay critical 120 non-critical 180", + "vrf site-1", + "address-family ipv4 unicast", + "nexthop trigger-delay critical 110 non-critical 170", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_nexthop_replaced(self): + # test replaced for config->address_family->network + self.get_config.return_value = dedent( + """\ + router bgp 65563 + address-family ipv4 multicast + nexthop route-map rmap1 + nexthop trigger-delay critical 120 non-critical 180 + vrf site-1 + address-family ipv4 unicast + nexthop route-map rmap2 + nexthop trigger-delay critical 110 non-critical 170 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + nexthop=dict(route_map="rmap1"), + ), + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + nexthop=dict( + trigger_delay=dict(critical_delay=110, non_critical_delay=170), + ), + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "address-family ipv4 multicast", + "no nexthop trigger-delay critical 120 non-critical 180", + "vrf site-1", + "address-family ipv4 unicast", + "no nexthop route-map rmap2", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_redistribute_merged(self): + # test merged for config->address_family->redistribute + self.get_config.return_value = dedent( + """\ + router bgp 65563 + vrf site-1 + address-family ipv4 unicast + redistribute eigrp 100 route-map test-17 + """, + ) + set_module_args( + dict( + config=dict( + as_number=65563, + address_family=[ + dict( + afi="ipv4", + safi="multicast", + redistribute=[ + dict( + protocol="eigrp", + id="100", + route_map="test-1", + ), + dict( + protocol="eigrp", + id="101", + route_map="test-2", + ), + dict(protocol="static", route_map="test-4"), + dict(protocol="hmm", route_map="test-5"), + ], + ), + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + redistribute=[ + dict( + protocol="eigrp", + id="100", + route_map="test-18", + ), + dict( + protocol="ospf", + id="101", + route_map="test-2", + ), + ], + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "address-family ipv4 multicast", + "redistribute eigrp 100 route-map test-1", + "redistribute eigrp 101 route-map test-2", + "redistribute static route-map test-4", + "redistribute hmm route-map test-5", + "vrf site-1", + "address-family ipv4 unicast", + "redistribute eigrp 100 route-map test-18", + "redistribute ospf 101 route-map test-2", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_redistribute_replaced(self): + # test replaced for config->address_family->redistribute + self.get_config.return_value = dedent( + """\ + router bgp 65563 + address-family ipv4 multicast + redistribute eigrp 100 route-map test-1 + redistribute eigrp 101 route-map test-2 + redistribute static route-map test-4 + redistribute hmm route-map test-5 + vrf site-1 + address-family ipv4 unicast + redistribute eigrp 100 route-map test-18 + redistribute ospf 101 route-map test-2 + """, + ) + set_module_args( + dict( + config=dict( + as_number=65563, + address_family=[ + dict( + afi="ipv4", + safi="multicast", + redistribute=[ + dict( + protocol="eigrp", + id="100", + route_map="test-1", + ), + dict(protocol="static", route_map="test-5"), + dict(protocol="hmm", route_map="test-5"), + ], + ), + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + redistribute=[ + dict( + protocol="ospf", + id="101", + route_map="test-2", + ), + ], + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "address-family ipv4 multicast", + "no redistribute eigrp 101 route-map test-2", + "redistribute static route-map test-5", + "vrf site-1", + "address-family ipv4 unicast", + "no redistribute eigrp 100 route-map test-18", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_retain_merged(self): + # test merged for config->address_family->retain + self.get_config.return_value = dedent( + """\ + router bgp 65563 + vrf site-1 + address-family ipv4 unicast + retain route-target all + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + retain=dict(route_target=dict(retain_all=True)), + ), + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + retain=dict(route_target=dict(route_map="rmap1")), + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "address-family ipv4 multicast", + "retain route-target all", + "vrf site-1", + "address-family ipv4 unicast", + "retain route-target route-map rmap1", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_retain_replaced(self): + # test replaced for config->address_family->retain + self.get_config.return_value = dedent( + """\ + router bgp 65563 + address-family ipv4 multicast + retain route-target all + vrf site-1 + address-family ipv4 unicast + retain route-target route-map rmap1 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + retain=dict(route_target=dict(retain_all=True)), + ), + dict(vrf="site-1", afi="ipv4", safi="unicast"), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "vrf site-1", + "address-family ipv4 unicast", + "no retain route-target route-map rmap1", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_suppress_inactive_merged(self): + # test merged for config->address_family->suppress_inactive + self.get_config.return_value = dedent( + """\ + router bgp 65563 + vrf site-1 + address-family ipv4 unicast + suppress-inactive + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + suppress_inactive=True, + ), + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + suppress_inactive=False, + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "address-family ipv4 multicast", + "suppress-inactive", + "vrf site-1", + "address-family ipv4 unicast", + "no suppress-inactive", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_suppress_inactive_replaced(self): + # test replaced for config->address_family->suppress_inactive + self.get_config.return_value = dedent( + """\ + router bgp 65563 + address-family ipv4 multicast + suppress-inactive + vrf site-1 + address-family ipv4 unicast + suppress-inactive + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + suppress_inactive=True, + ), + dict(vrf="site-1", afi="ipv4", safi="unicast"), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "vrf site-1", + "address-family ipv4 unicast", + "no suppress-inactive", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_table_map_merged(self): + # test merged for config->address_family->table_map + self.get_config.return_value = dedent( + """\ + router bgp 65563 + vrf site-1 + address-family ipv4 unicast + table-map rmap1 filter + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + table_map=dict(name="rmap2", filter=True), + ), + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + table_map=dict(name="rmap1", filter=True), + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "address-family ipv4 multicast", + "table-map rmap2 filter", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_table_map_replaced(self): + # test replaced for config->address_family->table_map + self.get_config.return_value = dedent( + """\ + router bgp 65563 + vrf site-1 + address-family ipv4 unicast + table-map rmap1 filter + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + table_map=dict(name="rmap2", filter=True), + ), + dict(vrf="site-1", afi="ipv4", safi="unicast"), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "address-family ipv4 multicast", + "table-map rmap2 filter", + "vrf site-1", + "address-family ipv4 unicast", + "no table-map rmap1 filter", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_timers_merged(self): + # test merged for config->address_family->table_map + self.get_config.return_value = dedent( + """\ + router bgp 65563 + vrf site-1 + address-family ipv4 unicast + timers bestpath-defer 100 maximum 350 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + timers=dict( + bestpath_defer=dict(defer_time=120, maximum_defer_time=380), + ), + ), + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + timers=dict( + bestpath_defer=dict(defer_time=110, maximum_defer_time=350), + ), + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "address-family ipv4 multicast", + "timers bestpath-defer 120 maximum 380", + "vrf site-1", + "address-family ipv4 unicast", + "timers bestpath-defer 110 maximum 350", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_timers_replaced(self): + # test replaced for config->address_family->table_map + self.get_config.return_value = dedent( + """\ + router bgp 65563 + address-family ipv4 multicast + timers bestpath-defer 120 maximum 380 + vrf site-1 + address-family ipv4 unicast + timers bestpath-defer 100 maximum 350 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + timers=dict( + bestpath_defer=dict(defer_time=120, maximum_defer_time=380), + ), + ), + dict(vrf="site-1", afi="ipv4", safi="unicast"), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "vrf site-1", + "address-family ipv4 unicast", + "no timers bestpath-defer 100 maximum 350", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_wait_igp_convergence_merged(self): + # test merged for config->address_family->wait_igp_convergence + self.get_config.return_value = dedent( + """\ + router bgp 65563 + vrf site-1 + address-family ipv4 unicast + wait-igp-convergence + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + wait_igp_convergence=True, + ), + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + wait_igp_convergence=False, + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "address-family ipv4 multicast", + "wait-igp-convergence", + "vrf site-1", + "address-family ipv4 unicast", + "no wait-igp-convergence", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_wait_igp_convergence_replaced(self): + # test replaced for config->address_family->wait_igp_convergence + self.get_config.return_value = dedent( + """\ + router bgp 65563 + address-family ipv4 multicast + wait-igp-convergence + vrf site-1 + address-family ipv4 unicast + wait-igp-convergence + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict(afi="ipv4", safi="multicast"), + dict( + afi="ipv4", + safi="unicast", + wait_igp_convergence=True, + ), + dict(vrf="site-1", afi="ipv4", safi="unicast"), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "address-family ipv4 multicast", + "no wait-igp-convergence", + "address-family ipv4 unicast", + "wait-igp-convergence", + "vrf site-1", + "address-family ipv4 unicast", + "no wait-igp-convergence", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_af_parsed(self): + # test parsed + set_module_args( + dict( + running_config=dedent( + """\ + router bgp 65563 + address-family ipv4 multicast + wait-igp-convergence + vrf site-1 + address-family ipv4 unicast + timers bestpath-defer 100 maximum 350 + """, + ), + state="parsed", + ), + ignore_provider_arg, + ) + parsed = dict( + as_number="65563", + address_family=[ + dict(afi="ipv4", safi="multicast", wait_igp_convergence=True), + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + timers=dict(bestpath_defer=dict(defer_time=100, maximum_defer_time=350)), + ), + ], + ) + result = self.execute_module(changed=False) + self.assertEqual(result["parsed"], parsed) + + def test_nxos_bgp_af_gathered(self): + # test gathered + self.get_config.return_value = dedent( + """\ + router bgp 65563 + address-family ipv4 multicast + wait-igp-convergence + neighbor 192.168.1.0 + address-family ipv6 unicast + neighbor 192.168.2.0 + address-family ipv6 multicast + vrf site-1 + address-family ipv4 unicast + timers bestpath-defer 100 maximum 350 + neighbor 192.168.3.0 + address-family ipv6 multicast + """, + ) + + set_module_args(dict(state="gathered"), ignore_provider_arg) + gathered = dict( + as_number="65563", + address_family=[ + dict(afi="ipv4", safi="multicast", wait_igp_convergence=True), + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + timers=dict(bestpath_defer=dict(defer_time=100, maximum_defer_time=350)), + ), + ], + ) + result = self.execute_module(changed=False) + self.assertEqual(result["gathered"], gathered) + + def test_nxos_bgp_af_gathered_empty(self): + # test gathered + self.get_config.return_value = dedent( + """\ + """, + ) + + set_module_args(dict(state="gathered"), ignore_provider_arg) + result = self.execute_module(changed=False) + self.assertEqual(result["gathered"], {}) + + def test_nxos_bgp_af_rendered(self): + # test gathered + self.get_config.return_value = dedent( + """\ + """, + ) + + set_module_args( + dict( + config=dict( + as_number=65563, + address_family=[ + dict( + afi="ipv4", + safi="multicast", + redistribute=[ + dict( + protocol="eigrp", + id="100", + route_map="test-1", + ), + dict(protocol="static", route_map="test-5"), + ], + ), + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + redistribute=[ + dict( + protocol="ospf", + id="101", + route_map="test-2", + ), + ], + ), + ], + ), + state="rendered", + ), + ignore_provider_arg, + ) + rendered = [ + "router bgp 65563", + "address-family ipv4 multicast", + "redistribute eigrp 100 route-map test-1", + "redistribute static route-map test-5", + "vrf site-1", + "address-family ipv4 unicast", + "redistribute ospf 101 route-map test-2", + ] + result = self.execute_module(changed=False) + self.assertEqual(set(result["rendered"]), set(rendered)) + + def test_nxos_bgp_af_delete(self): + # test gathered + self.get_config.return_value = dedent( + """\ + router bgp 65563 + address-family ipv4 multicast + wait-igp-convergence + neighbor 192.168.1.0 + address-family ipv6 unicast + neighbor 192.168.2.0 + address-family ipv6 multicast + vrf site-1 + address-family ipv4 unicast + timers bestpath-defer 100 maximum 350 + address-family ipv6 multicast + neighbor 192.168.3.0 + address-family ipv6 multicast + vrf site-2 + address-family ipv6 unicast + """, + ) + + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict(afi="ipv4", safi="multicast"), + dict(vrf="site-1", afi="ipv4", safi="unicast"), + dict(vrf="site-1", afi="ipv6", safi="multicast"), + dict(vrf="site-2", afi="ipv6", safi="unicast"), + ], + ), + state="deleted", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "no address-family ipv4 multicast", + "vrf site-1", + "no address-family ipv4 unicast", + "no address-family ipv6 multicast", + "exit", + "vrf site-2", + "no address-family ipv6 unicast", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_af_idempotent(self): + # test idempotent + self.get_config.return_value = dedent( + """\ + router bgp 65563 + address-family ipv4 multicast + wait-igp-convergence + """, + ) + + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + wait_igp_convergence=True, + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + self.execute_module(changed=False) + + def test_nxos_bgp_af_overridden(self): + # test gathered + self.get_config.return_value = dedent( + """\ + router bgp 65563 + address-family ipv4 multicast + wait-igp-convergence + neighbor 192.168.1.0 + address-family ipv6 unicast + neighbor 192.168.2.0 + address-family ipv6 multicast + vrf site-1 + address-family ipv4 unicast + timers bestpath-defer 100 maximum 350 + address-family ipv6 multicast + neighbor 192.168.3.0 + address-family ipv6 multicast + vrf site-2 + address-family ipv6 unicast + """, + ) + + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + wait_igp_convergence=False, + ), + ], + ), + state="overridden", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "vrf site-1", + "no address-family ipv4 unicast", + "no address-family ipv6 multicast", + "exit", + "vrf site-2", + "no address-family ipv6 unicast", + "exit", + "address-family ipv4 multicast", + "no wait-igp-convergence", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_af_delete(self): + # test gathered + self.get_config.return_value = dedent( + """\ + router bgp 65563 + address-family ipv4 multicast + wait-igp-convergence + address-family ipv6 unicast + neighbor 192.168.1.0 + address-family ipv6 unicast + neighbor 192.168.2.0 + address-family ipv6 multicast + vrf site-1 + address-family ipv4 unicast + timers bestpath-defer 100 maximum 350 + address-family ipv6 multicast + neighbor 192.168.3.0 + address-family ipv6 multicast + vrf site-2 + address-family ipv6 unicast + """, + ) + + set_module_args(dict(state="deleted"), ignore_provider_arg) + commands = [ + "router bgp 65563", + "no address-family ipv4 multicast", + "no address-family ipv6 unicast", + "vrf site-1", + "no address-family ipv4 unicast", + "no address-family ipv6 multicast", + "exit", + "vrf site-2", + "no address-family ipv6 unicast", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_vrf_af_advertise_l2vpn_evpn(self): + # test merged for config->vrf->address_family->advertise l2vpn evpn + self.get_config.return_value = dedent( + """\ + router bgp 65563 + vrf site-1 + address-family ipv4 unicast + vrf site-2 + address-family ipv4 unicast + advertise l2vpn evpn + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + advertise_l2vpn_evpn=True, + ), + dict( + vrf="site-2", + afi="ipv4", + safi="unicast", + advertise_l2vpn_evpn=False, + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "vrf site-1", + "address-family ipv4 unicast", + "advertise l2vpn evpn", + "vrf site-2", + "address-family ipv4 unicast", + "no advertise l2vpn evpn", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_vrf_af_advertise_l2vpn_evpn_replaced(self): + # test replaced for config->vrf->address_family->advertise l2vpn evpn + self.get_config.return_value = dedent( + """\ + router bgp 65563 + vrf site-1 + address-family ipv4 unicast + vrf site-2 + address-family ipv4 unicast + advertise l2vpn evpn + """, + ) + set_module_args( + dict( + config=dict( + as_number="65563", + address_family=[ + dict( + vrf="site-1", + afi="ipv4", + safi="unicast", + advertise_l2vpn_evpn=True, + ), + dict(vrf="site-2", afi="ipv4", safi="unicast"), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65563", + "vrf site-1", + "address-family ipv4 unicast", + "advertise l2vpn evpn", + "vrf site-2", + "address-family ipv4 unicast", + "no advertise l2vpn evpn", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_bgp_af.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_bgp_af.py new file mode 100644 index 00000000..a72095c8 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_bgp_af.py @@ -0,0 +1,175 @@ +# (c) 2016 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from ansible_collections.cisco.nxos.plugins.modules import nxos_bgp_af +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, load_fixture, set_module_args + + +class TestNxosBgpAfModule(TestNxosModule): + module = nxos_bgp_af + + def setUp(self): + super(TestNxosBgpAfModule, self).setUp() + + self.mock_load_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_bgp_af.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_get_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_bgp_af.get_config", + ) + self.get_config = self.mock_get_config.start() + + def tearDown(self): + super(TestNxosBgpAfModule, self).tearDown() + self.mock_load_config.stop() + self.mock_get_config.stop() + + def load_fixtures(self, commands=None, device=""): + self.get_config.return_value = load_fixture("nxos_bgp", "config.cfg") + self.load_config.return_value = None + + def test_nxos_bgp_af(self): + set_module_args(dict(asn=65535, afi="ipv4", safi="unicast")) + self.execute_module( + changed=True, + sort=False, + commands=["router bgp 65535", "address-family ipv4 unicast"], + ) + + def test_nxos_bgp_af_vrf(self): + set_module_args(dict(asn=65535, vrf="test", afi="ipv4", safi="unicast")) + self.execute_module( + changed=True, + sort=False, + commands=[ + "router bgp 65535", + "vrf test", + "address-family ipv4 unicast", + ], + ) + + def test_nxos_bgp_af_vrf_exists(self): + set_module_args(dict(asn=65535, vrf="test2", afi="ipv4", safi="unicast")) + self.execute_module(changed=False, commands=[]) + + def test_nxos_bgp_af_dampening_routemap(self): + set_module_args( + dict( + asn=65535, + afi="ipv4", + safi="unicast", + dampening_routemap="route-map-a", + ), + ) + self.execute_module( + changed=True, + commands=[ + "router bgp 65535", + "address-family ipv4 unicast", + "dampening route-map route-map-a", + ], + ) + + def test_nxos_bgp_af_dampening_manual(self): + set_module_args( + dict( + asn=65535, + afi="ipv4", + safi="unicast", + dampening_half_time=5, + dampening_suppress_time=2000, + dampening_reuse_time=1900, + dampening_max_suppress_time=10, + ), + ) + self.execute_module( + changed=True, + commands=[ + "router bgp 65535", + "address-family ipv4 unicast", + "dampening 5 1900 2000 10", + ], + ) + + def test_nxos_bgp_af_dampening_mix(self): + set_module_args( + dict( + asn=65535, + afi="ipv4", + safi="unicast", + dampening_routemap="route-map-a", + dampening_half_time=5, + dampening_suppress_time=2000, + dampening_reuse_time=1900, + dampening_max_suppress_time=10, + ), + ) + result = self.execute_module(failed=True) + self.assertEqual( + result["msg"], + "parameters are mutually exclusive: dampening_routemap|dampening_half_time, " + "dampening_routemap|dampening_suppress_time, dampening_routemap|dampening_reuse_time, " + "dampening_routemap|dampening_max_suppress_time", + ) + + def test_nxos_bgp_af_client(self): + set_module_args(dict(asn=65535, afi="ipv4", safi="unicast", client_to_client=False)) + self.execute_module( + changed=True, + commands=[ + "router bgp 65535", + "address-family ipv4 unicast", + "no client-to-client reflection", + ], + ) + + def test_nxos_bgp_af_retain_route_target(self): + set_module_args(dict(asn=65535, afi="l2vpn", safi="evpn", retain_route_target="abc")) + self.execute_module( + changed=True, + commands=[ + "router bgp 65535", + "address-family l2vpn evpn", + "retain route-target route-map abc", + ], + ) + + def test_nxos_bgp_af_retain_route_target_all(self): + set_module_args(dict(asn=65535, afi="l2vpn", safi="evpn", retain_route_target="all")) + self.execute_module( + changed=True, + commands=[ + "router bgp 65535", + "address-family l2vpn evpn", + "retain route-target all", + ], + ) + + def test_nxos_bgp_af_retain_route_target_exists(self): + set_module_args(dict(asn=65535, afi="l2vpn", safi="evpn", retain_route_target="xyz")) + self.execute_module(changed=False, commands=[]) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_bgp_global.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_bgp_global.py new file mode 100644 index 00000000..612c7a1f --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_bgp_global.py @@ -0,0 +1,974 @@ +# (c) 2021 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from textwrap import dedent + +from ansible_collections.cisco.nxos.plugins.modules import nxos_bgp_global +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, set_module_args + + +ignore_provider_arg = True + + +class TestNxosBgpGlobalModule(TestNxosModule): + module = nxos_bgp_global + + def setUp(self): + super(TestNxosBgpGlobalModule, self).setUp() + + self.mock_get_resource_connection = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module_base.get_resource_connection", + ) + self.get_resource_connection = self.mock_get_resource_connection.start() + + self.mock_get_config = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.facts.bgp_global.bgp_global.Bgp_globalFacts.get_config", + ) + self.get_config = self.mock_get_config.start() + + self.mock_cfg_get_config = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.config.bgp_global.bgp_global.Bgp_global._get_config", + ) + self.cfg_get_config = self.mock_cfg_get_config.start() + + def tearDown(self): + super(TestNxosBgpGlobalModule, self).tearDown() + self.get_resource_connection.stop() + self.get_config.stop() + self.cfg_get_config.stop() + + def test_nxos_bgp_global_merged_basic(self): + set_module_args( + dict(config=dict(as_number="65563"), state="merged"), + ignore_provider_arg, + ) + result = self.execute_module(changed=True) + self.assertEqual(result["commands"], ["router bgp 65563"]) + + def test_nxos_bgp_global_merged(self): + set_module_args( + dict( + config=dict( + as_number="65536", + router_id="198.51.100.2", + log_neighbor_changes=True, + maxas_limit=20, + neighbors=[ + dict( + neighbor_address="198.51.100.20", + neighbor_affinity_group=dict(group_id=160), + remote_as="65537", + description="NBR-1", + low_memory=dict(exempt=True), + ), + dict( + neighbor_address="198.51.100.21", + remote_as="65537", + password=dict(encryption=7, key="12090404011C03162E"), + ), + ], + vrfs=[ + dict( + vrf="site-1", + local_as="200", + log_neighbor_changes=True, + neighbors=[ + dict( + neighbor_address="192.0.2.10", + neighbor_affinity_group=dict(group_id=161), + remote_as="65538", + timers=dict(keepalive=5, holdtime=15), + description="site-1-nbr-1", + password=dict( + encryption=3, + key="13D4D3549493D2877B1DC116EE27A6BE", + ), + ), + ], + ), + dict( + vrf="site-2", + local_as="300", + log_neighbor_changes=True, + neighbor_down=dict(fib_accelerate=True), + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65536", + "log-neighbor-changes", + "maxas-limit 20", + "router-id 198.51.100.2", + "neighbor 198.51.100.20", + "remote-as 65537", + "affinity-group 160", + "description NBR-1", + "low-memory exempt", + "neighbor 198.51.100.21", + "remote-as 65537", + "password 7 12090404011C03162E", + "vrf site-1", + "local-as 200", + "log-neighbor-changes", + "neighbor 192.0.2.10", + "affinity-group 161", + "remote-as 65538", + "description site-1-nbr-1", + "password 3 13D4D3549493D2877B1DC116EE27A6BE", + "timers 5 15", + "vrf site-2", + "local-as 300", + "log-neighbor-changes", + "neighbor-down fib-accelerate", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_global_bfd(self): + set_module_args( + dict( + config=dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="198.51.100.20", + bfd=dict( + set=True, + multihop=dict( + interval=dict( + tx_interval=300, + min_rx_interval=258, + multiplier=12, + ), + ), + ), + ), + dict( + neighbor_address="198.51.100.21", + bfd=dict( + multihop=dict( + set=True, + interval=dict( + tx_interval=301, + min_rx_interval=260, + multiplier=15, + ), + ), + ), + ), + dict( + neighbor_address="198.51.100.22", + bfd=dict(singlehop=True), + ), + dict( + neighbor_address="198.51.100.23", + bfd=dict(multihop=dict(set=True)), + ), + dict( + neighbor_address="198.51.100.24", + bfd=dict(set=True), + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65536", + "neighbor 198.51.100.20", + "bfd", + "bfd multihop interval 300 min_rx 258 multiplier 12", + "neighbor 198.51.100.21", + "bfd multihop", + "bfd multihop interval 301 min_rx 260 multiplier 15", + "neighbor 198.51.100.22", + "bfd singlehop", + "neighbor 198.51.100.23", + "bfd multihop", + "neighbor 198.51.100.24", + "bfd", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_global_bfd(self): + run_cfg = dedent( + """\ + router bgp 65536 + neighbor 198.51.100.20 + bfd + bfd multihop interval 300 min_rx 258 multiplier 12 + neighbor 198.51.100.21 + bfd multihop + bfd multihop interval 301 min_rx 260 multiplier 15 + neighbor 198.51.100.22 + bfd singlehop + neighbor 198.51.100.23 + bfd multihop + neighbor 198.51.100.24 + bfd + """, + ) + self.get_config.return_value = run_cfg + self.cfg_get_config.return_value = run_cfg + + set_module_args( + dict( + config=dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="198.51.100.20", + bfd=dict( + set=True, + multihop=dict( + interval=dict( + tx_interval=300, + min_rx_interval=258, + multiplier=12, + ), + ), + ), + ), + dict( + neighbor_address="198.51.100.21", + bfd=dict( + multihop=dict( + set=True, + interval=dict( + tx_interval=301, + min_rx_interval=260, + multiplier=15, + ), + ), + ), + ), + dict( + neighbor_address="198.51.100.22", + bfd=dict(singlehop=True), + ), + dict( + neighbor_address="198.51.100.23", + bfd=dict(multihop=dict(set=True)), + ), + dict( + neighbor_address="198.51.100.24", + bfd=dict(set=True), + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_bgp_global_merged_idempotent(self): + run_cfg = dedent( + """\ + router bgp 65536 + log-neighbor-changes + maxas-limit 20 + router-id 198.51.100.2 + neighbor 198.51.100.20 + remote-as 65537 + affinity-group 160 + description NBR-1 + low-memory exempt + neighbor 198.51.100.21 + remote-as 65537 + password 7 12090404011C03162E + vrf site-1 + local-as 200 + log-neighbor-changes + neighbor 192.0.2.10 + affinity-group 161 + remote-as 65538 + description site-1-nbr-1 + password 3 13D4D3549493D2877B1DC116EE27A6BE + vrf site-2 + local-as 300 + log-neighbor-changes + neighbor-down fib-accelerate + """, + ) + self.get_config.return_value = run_cfg + + set_module_args( + dict( + config=dict( + as_number="65536", + router_id="198.51.100.2", + log_neighbor_changes=True, + maxas_limit=20, + neighbors=[ + dict( + neighbor_address="198.51.100.20", + neighbor_affinity_group=dict(group_id=160), + remote_as="65537", + description="NBR-1", + low_memory=dict(exempt=True), + ), + dict( + neighbor_address="198.51.100.21", + remote_as="65537", + password=dict(encryption=7, key="12090404011C03162E"), + ), + ], + vrfs=[ + dict( + vrf="site-1", + local_as="200", + log_neighbor_changes=True, + neighbors=[ + dict( + neighbor_address="192.0.2.10", + neighbor_affinity_group=dict(group_id=161), + remote_as="65538", + description="site-1-nbr-1", + password=dict( + encryption=3, + key="13D4D3549493D2877B1DC116EE27A6BE", + ), + ), + ], + ), + dict( + vrf="site-2", + local_as="300", + log_neighbor_changes=True, + neighbor_down=dict(fib_accelerate=True), + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_bgp_global_replaced(self): + run_cfg = dedent( + """\ + router bgp 65536 + log-neighbor-changes + maxas-limit 20 + router-id 198.51.100.2 + neighbor 198.51.100.20 + remote-as 65537 + affinity-group 161 + description NBR-1 + shutdown + low-memory exempt + neighbor 198.51.100.21 + remote-as 65537 + password 7 12090404011C03162E + vrf site-1 + local-as 200 + log-neighbor-changes + neighbor 192.0.2.10 + affinity-group 170 + remote-as 65538 + description site-1-nbr-1 + password 3 13D4D3549493D2877B1DC116EE27A6BE + vrf site-2 + local-as 300 + log-neighbor-changes + neighbor-down fib-accelerate + """, + ) + self.get_config.return_value = run_cfg + self.cfg_get_config.return_value = run_cfg + + set_module_args( + dict( + config=dict( + as_number="65536", + router_id="198.51.100.212", + log_neighbor_changes=True, + maxas_limit=20, + neighbors=[ + dict( + neighbor_address="198.51.100.20", + neighbor_affinity_group=dict(group_id=161), + remote_as="65537", + description="NBR-1", + low_memory=dict(exempt=True), + ), + ], + vrfs=[ + dict( + vrf="site-1", + local_as="200", + log_neighbor_changes=True, + neighbors=[ + dict( + neighbor_address="192.0.2.10", + neighbor_affinity_group=dict(group_id=190), + remote_as="65538", + description="site-1-nbr-1", + password=dict( + encryption=3, + key="13D4D3549493D2877B1DC116EE27A6BE", + ), + ), + ], + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65536", + "router-id 198.51.100.212", + "neighbor 198.51.100.20", + "no shutdown", + "no neighbor 198.51.100.21", + "vrf site-1", + "neighbor 192.0.2.10", + "affinity-group 190", + "no vrf site-2", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_global_replaced_idempotent(self): + run_cfg = dedent( + """\ + router bgp 65536 + log-neighbor-changes + maxas-limit 20 + router-id 198.51.100.212 + neighbor 198.51.100.20 + remote-as 65537 + affinity-group 161 + description NBR-1 + low-memory exempt + vrf site-1 + local-as 200 + log-neighbor-changes + neighbor 192.0.2.10 + affinity-group 190 + remote-as 65538 + description site-1-nbr-1 + password 3 13D4D3549493D2877B1DC116EE27A6BE + """, + ) + self.get_config.return_value = run_cfg + self.cfg_get_config.return_value = run_cfg + + set_module_args( + dict( + config=dict( + as_number="65536", + router_id="198.51.100.212", + log_neighbor_changes=True, + maxas_limit=20, + neighbors=[ + dict( + neighbor_address="198.51.100.20", + neighbor_affinity_group=dict(group_id=161), + remote_as="65537", + description="NBR-1", + low_memory=dict(exempt=True), + ), + ], + vrfs=[ + dict( + vrf="site-1", + local_as="200", + log_neighbor_changes=True, + neighbors=[ + dict( + neighbor_address="192.0.2.10", + neighbor_affinity_group=dict(group_id=190), + remote_as="65538", + description="site-1-nbr-1", + password=dict( + encryption=3, + key="13D4D3549493D2877B1DC116EE27A6BE", + ), + ), + ], + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_bgp_global_replaced_failed_1(self): + run_cfg = dedent( + """\ + router bgp 65536 + log-neighbor-changes + maxas-limit 20 + router-id 198.51.100.2 + neighbor 198.51.100.20 + remote-as 65537 + affinity-group 161 + description NBR-1 + low-memory exempt + neighbor 198.51.100.21 + address-family ipv4 unicast + remote-as 65537 + password 7 12090404011C03162E + vrf site-1 + local-as 200 + log-neighbor-changes + neighbor 192.0.2.10 + affinity-group 170 + remote-as 65538 + description site-1-nbr-1 + password 3 13D4D3549493D2877B1DC116EE27A6BE + vrf site-2 + local-as 300 + log-neighbor-changes + neighbor-down fib-accelerate + """, + ) + self.get_config.return_value = run_cfg + self.cfg_get_config.return_value = run_cfg + + set_module_args( + dict( + config=dict( + as_number="65536", + router_id="198.51.100.212", + log_neighbor_changes=True, + maxas_limit=20, + neighbors=[ + dict( + neighbor_address="198.51.100.20", + neighbor_affinity_group=dict(group_id=161), + remote_as="65537", + description="NBR-1", + low_memory=dict(exempt=True), + ), + ], + vrfs=[ + dict( + vrf="site-1", + local_as="200", + log_neighbor_changes=True, + neighbors=[ + dict( + neighbor_address="192.0.2.10", + neighbor_affinity_group=dict(group_id=190), + remote_as="65538", + description="site-1-nbr-1", + password=dict( + encryption=3, + key="13D4D3549493D2877B1DC116EE27A6BE", + ), + ), + ], + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + result = self.execute_module(failed=True) + + def test_nxos_bgp_global_replaced_failed_2(self): + run_cfg = dedent( + """\ + router bgp 65536 + log-neighbor-changes + maxas-limit 20 + router-id 198.51.100.2 + neighbor 198.51.100.20 + remote-as 65537 + affinity-group 161 + description NBR-1 + low-memory exempt + neighbor 198.51.100.21 + remote-as 65537 + password 7 12090404011C03162E + vrf site-1 + address-family ipv4 unicast + local-as 200 + log-neighbor-changes + neighbor 192.0.2.10 + affinity-group 170 + remote-as 65538 + description site-1-nbr-1 + password 3 13D4D3549493D2877B1DC116EE27A6BE + vrf site-2 + local-as 300 + log-neighbor-changes + neighbor-down fib-accelerate + """, + ) + self.get_config.return_value = run_cfg + self.cfg_get_config.return_value = run_cfg + + set_module_args( + dict( + config=dict( + as_number="65536", + router_id="198.51.100.2", + log_neighbor_changes=True, + maxas_limit=20, + neighbors=[ + dict( + neighbor_address="198.51.100.20", + neighbor_affinity_group=dict(group_id=160), + remote_as="65537", + description="NBR-1", + low_memory=dict(exempt=True), + ), + dict( + neighbor_address="198.51.100.21", + remote_as="65537", + password=dict(encryption=7, key="12090404011C03162E"), + ), + ], + vrfs=[ + dict( + vrf="site-2", + local_as="300", + log_neighbor_changes=True, + neighbor_down=dict(fib_accelerate=True), + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + result = self.execute_module(failed=True) + + def test_nxos_bgp_global_replaced_failed_3(self): + run_cfg = dedent( + """\ + router bgp 65536 + log-neighbor-changes + maxas-limit 20 + router-id 198.51.100.2 + neighbor 198.51.100.20 + remote-as 65537 + affinity-group 161 + description NBR-1 + low-memory exempt + neighbor 198.51.100.21 + remote-as 65537 + password 7 12090404011C03162E + vrf site-1 + local-as 200 + log-neighbor-changes + neighbor 192.0.2.10 + address-family ipv4 unicast + affinity-group 170 + remote-as 65538 + description site-1-nbr-1 + password 3 13D4D3549493D2877B1DC116EE27A6BE + vrf site-2 + local-as 300 + log-neighbor-changes + neighbor-down fib-accelerate + """, + ) + self.get_config.return_value = run_cfg + self.cfg_get_config.return_value = run_cfg + + set_module_args( + dict( + config=dict( + as_number="65536", + router_id="198.51.100.2", + log_neighbor_changes=True, + maxas_limit=20, + neighbors=[ + dict( + neighbor_address="198.51.100.20", + neighbor_affinity_group=dict(group_id=160), + remote_as="65537", + description="NBR-1", + low_memory=dict(exempt=True), + ), + dict( + neighbor_address="198.51.100.21", + remote_as="65537", + password=dict(encryption=7, key="12090404011C03162E"), + ), + ], + vrfs=[ + dict( + vrf="site-1", + local_as="200", + log_neighbor_changes=True, + ), + dict( + vrf="site-2", + local_as="300", + log_neighbor_changes=True, + neighbor_down=dict(fib_accelerate=True), + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + result = self.execute_module(failed=True) + + def test_nxos_bgp_global_deleted(self): + run_cfg = dedent( + """\ + router bgp 65536 + log-neighbor-changes + maxas-limit 20 + router-id 198.51.100.2 + neighbor 198.51.100.20 + remote-as 65537 + affinity-group 161 + description NBR-1 + low-memory exempt + neighbor 198.51.100.21 + remote-as 65537 + password 7 12090404011C03162E + vrf site-1 + local-as 200 + log-neighbor-changes + neighbor 192.0.2.10 + affinity-group 170 + remote-as 65538 + description site-1-nbr-1 + password 3 13D4D3549493D2877B1DC116EE27A6BE + vrf site-2 + local-as 300 + log-neighbor-changes + neighbor-down fib-accelerate + """, + ) + self.get_config.return_value = run_cfg + self.cfg_get_config.return_value = run_cfg + + set_module_args(dict(state="deleted"), ignore_provider_arg) + commands = [ + "router bgp 65536", + "no log-neighbor-changes", + "no maxas-limit 20", + "no router-id 198.51.100.2", + "no neighbor 198.51.100.20", + "no neighbor 198.51.100.21", + "no vrf site-1", + "no vrf site-2", + ] + + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_global_deleted_idempotent_1(self): + run_cfg = dedent( + """\ + """, + ) + self.get_config.return_value = run_cfg + self.cfg_get_config.return_value = run_cfg + + set_module_args(dict(state="deleted"), ignore_provider_arg) + + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_bgp_global_deleted_idempotent_2(self): + run_cfg = dedent( + """\ + router bgp 65536 + log-neighbor-changes + maxas-limit 20 + router-id 198.51.100.2 + neighbor 198.51.100.20 + remote-as 65537 + affinity-group 161 + description NBR-1 + low-memory exempt + neighbor 198.51.100.21 + remote-as 65537 + password 7 12090404011C03162E + vrf site-1 + local-as 200 + log-neighbor-changes + neighbor 192.0.2.10 + affinity-group 170 + remote-as 65538 + description site-1-nbr-1 + password 3 13D4D3549493D2877B1DC116EE27A6BE + vrf site-2 + local-as 300 + log-neighbor-changes + neighbor-down fib-accelerate + """, + ) + self.get_config.return_value = run_cfg + self.cfg_get_config.return_value = run_cfg + + set_module_args( + dict(config=dict(as_number="65539"), state="deleted"), + ignore_provider_arg, + ) + + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_bgp_global_deleted_failed(self): + run_cfg = dedent( + """\ + router bgp 65536 + log-neighbor-changes + maxas-limit 20 + router-id 198.51.100.2 + neighbor 198.51.100.20 + remote-as 65537 + affinity-group 161 + description NBR-1 + low-memory exempt + neighbor 198.51.100.21 + address-family ipv4 unicast + remote-as 65537 + password 7 12090404011C03162E + vrf site-1 + local-as 200 + log-neighbor-changes + neighbor 192.0.2.10 + affinity-group 170 + remote-as 65538 + description site-1-nbr-1 + password 3 13D4D3549493D2877B1DC116EE27A6BE + vrf site-2 + local-as 300 + log-neighbor-changes + neighbor-down fib-accelerate + """, + ) + self.get_config.return_value = run_cfg + self.cfg_get_config.return_value = run_cfg + + set_module_args(dict(state="deleted"), ignore_provider_arg) + result = self.execute_module(failed=True) + + def test_nxos_bgp_global_purged(self): + run_cfg = dedent( + """\ + router bgp 65536 + log-neighbor-changes + maxas-limit 20 + router-id 198.51.100.2 + neighbor 198.51.100.20 + remote-as 65537 + affinity-group 161 + description NBR-1 + low-memory exempt + neighbor 198.51.100.21 + remote-as 65537 + password 7 12090404011C03162E + vrf site-1 + local-as 200 + log-neighbor-changes + neighbor 192.0.2.10 + affinity-group 170 + remote-as 65538 + description site-1-nbr-1 + password 3 13D4D3549493D2877B1DC116EE27A6BE + vrf site-2 + local-as 300 + log-neighbor-changes + neighbor-down fib-accelerate + """, + ) + self.get_config.return_value = run_cfg + self.cfg_get_config.return_value = run_cfg + + set_module_args(dict(state="purged"), ignore_provider_arg) + commands = ["no router bgp 65536"] + + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_global_purged_idempotent(self): + run_cfg = dedent( + """\ + """, + ) + self.get_config.return_value = run_cfg + self.cfg_get_config.return_value = run_cfg + + set_module_args(dict(state="purged"), ignore_provider_arg) + + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_bgp_global_purged(self): + run_cfg = dedent( + """\ + router bgp 65001 + """, + ) + self.get_config.return_value = run_cfg + self.cfg_get_config.return_value = run_cfg + + set_module_args( + dict( + config=dict( + as_number="65001", + neighbors=[ + dict( + neighbor_address="10.239.0.13", + peer_type="fabric-external", + remote_as="65002", + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65001", + "neighbor 10.239.0.13", + "remote-as 65002", + "peer-type fabric-external", + ] + + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_bgp_neighbor.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_bgp_neighbor.py new file mode 100644 index 00000000..677e6f7d --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_bgp_neighbor.py @@ -0,0 +1,138 @@ +# (c) 2016 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from ansible_collections.cisco.nxos.plugins.modules import nxos_bgp_neighbor +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, load_fixture, set_module_args + + +class TestNxosBgpNeighborModule(TestNxosModule): + module = nxos_bgp_neighbor + + def setUp(self): + super(TestNxosBgpNeighborModule, self).setUp() + + self.mock_load_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_bgp_neighbor.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_get_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_bgp_neighbor.get_config", + ) + self.get_config = self.mock_get_config.start() + + def tearDown(self): + super(TestNxosBgpNeighborModule, self).tearDown() + self.mock_load_config.stop() + self.mock_get_config.stop() + + def load_fixtures(self, commands=None, device=""): + self.get_config.return_value = load_fixture("nxos_bgp", "config.cfg") + self.load_config.return_value = [] + + def test_nxos_bgp_neighbor_bfd_1(self): + # None (disable) -> enable + set_module_args(dict(asn=65535, neighbor="1.1.1.1", bfd="enable")) + self.execute_module( + changed=True, + commands=["router bgp 65535", "neighbor 1.1.1.1", "bfd"], + ) + + # enable -> enable (idempotence) + set_module_args(dict(asn=65535, neighbor="1.1.1.2", bfd="enable")) + self.execute_module(changed=False) + + def test_nxos_bgp_neighbor_bfd_2(self): + # enable -> None (disable) + set_module_args(dict(asn=65535, neighbor="1.1.1.2", bfd="disable")) + self.execute_module( + changed=True, + commands=["router bgp 65535", "neighbor 1.1.1.2", "no bfd"], + ) + + # None (disable) -> disable (idempotence) + set_module_args(dict(asn=65535, neighbor="1.1.1.1", bfd="disable")) + self.execute_module(changed=False) + + def test_nxos_bgp_neighbor(self): + set_module_args(dict(asn=65535, neighbor="192.0.2.3", description="some words")) + self.execute_module( + changed=True, + commands=[ + "router bgp 65535", + "neighbor 192.0.2.3", + "description some words", + ], + ) + + def test_nxos_bgp_neighbor_absent(self): + set_module_args(dict(asn=65535, neighbor="1.1.1.1", state="absent")) + self.execute_module(changed=True, commands=["router bgp 65535", "no neighbor 1.1.1.1"]) + + def test_nxos_bgp_neighbor_remove_private_as(self): + set_module_args(dict(asn=65535, neighbor="3.3.3.4", remove_private_as="all")) + self.execute_module(changed=False, commands=[]) + + def test_nxos_bgp_neighbor_remove_private_as_changed(self): + set_module_args(dict(asn=65535, neighbor="3.3.3.4", remove_private_as="replace-as")) + self.execute_module( + changed=True, + commands=[ + "router bgp 65535", + "neighbor 3.3.3.4", + "remove-private-as replace-as", + ], + ) + + def test_nxos_bgp_neighbor_peertype_border_leaf(self): + set_module_args(dict(asn=65535, neighbor="192.0.2.3", peer_type="fabric_border_leaf")) + self.execute_module( + changed=True, + commands=[ + "router bgp 65535", + "neighbor 192.0.2.3", + "peer-type fabric-border-leaf", + ], + ) + + def test_nxos_bgp_neighbor_peertype_external(self): + set_module_args(dict(asn=65535, neighbor="192.0.2.3", peer_type="fabric_external")) + self.execute_module( + changed=True, + commands=[ + "router bgp 65535", + "neighbor 192.0.2.3", + "peer-type fabric-external", + ], + ) + + def test_nxos_bgp_neighbor_peertype_border_leaf_exists(self): + set_module_args(dict(asn=65535, neighbor="5.5.5.5", peer_type="fabric_border_leaf")) + self.execute_module(changed=False) + + def test_nxos_bgp_neighbor_peertype_external_exists(self): + set_module_args(dict(asn=65535, neighbor="6.6.6.6", peer_type="fabric_external")) + self.execute_module(changed=False) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_bgp_neighbor_address_family.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_bgp_neighbor_address_family.py new file mode 100644 index 00000000..2b7e1591 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_bgp_neighbor_address_family.py @@ -0,0 +1,2681 @@ +# (c) 2021 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from textwrap import dedent + +from ansible_collections.cisco.nxos.plugins.modules import nxos_bgp_neighbor_address_family +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, set_module_args + + +ignore_provider_arg = True + + +class TestNxosBGPNeighborAddressFamilyModule(TestNxosModule): + # Testing strategy + # ------------------ + # (a) The unit tests cover `merged` and `replaced` for every attribute. + # Since `overridden` is essentially `replaced` but at a larger + # scale, these indirectly cover `overridden` as well. + # (b) For linear attributes replaced is not valid and hence, those tests + # delete the attributes from the config subsection. + # (c) The argspec for VRFs is same as the top-level spec and the config logic + # is re-used. Hence, those attributes are not explictly covered. However, a + # combination of VRF + top-level spec + AF is tested. + + module = nxos_bgp_neighbor_address_family + + def setUp(self): + super(TestNxosBGPNeighborAddressFamilyModule, self).setUp() + + self.mock_get_resource_connection = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module_base.get_resource_connection", + ) + self.get_resource_connection = self.mock_get_resource_connection.start() + + self.mock_get_config = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.facts.bgp_neighbor_address_family." + "bgp_neighbor_address_family.Bgp_neighbor_address_familyFacts.get_config", + ) + self.get_config = self.mock_get_config.start() + + def tearDown(self): + super(TestNxosBGPNeighborAddressFamilyModule, self).tearDown() + self.get_resource_connection.stop() + self.get_config.stop() + + def test_nxos_bgp_nbr_af_advertise_map_merged(self): + # test merged for advertise_map + self.get_config.return_value = dedent( + """\ + router bgp 65536 + vrf site-1 + neighbor 192.168.1.1 + address-family ipv4 unicast + advertise-map rmap2 exist-map rmap3 + address-family ipv4 multicast + advertise-map rmap1 non-exist-map rmap5 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="10.0.0.2", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + advertise_map=dict(route_map="rmap1", exist_map="rmap2"), + ), + ], + ), + ], + vrfs=[ + dict( + vrf="site-1", + neighbors=[ + dict( + neighbor_address="192.168.1.1", + address_family=[ + dict( + afi="ipv4", + safi="unicast", + advertise_map=dict( + route_map="rmap2", + exist_map="rmap3", + ), + ), + dict( + afi="ipv4", + safi="multicast", + advertise_map=dict( + route_map="rmap1", + non_exist_map="rmap7", + ), + ), + ], + ), + ], + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65536", + "neighbor 10.0.0.2", + "address-family ipv4 multicast", + "advertise-map rmap1 exist-map rmap2", + "vrf site-1", + "neighbor 192.168.1.1", + "address-family ipv4 multicast", + "advertise-map rmap1 non-exist-map rmap7", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_nbr_af_advertise_map_replaced(self): + # test replaced for advertise_map + self.get_config.return_value = dedent( + """\ + router bgp 65536 + neighbor 10.0.0.2 + address-family ipv4 multicast + advertise-map rmap1 exist-map rmap2 + vrf site-1 + neighbor 192.168.1.1 + address-family ipv4 unicast + advertise-map rmap2 exist-map rmap3 + address-family ipv4 multicast + advertise-map rmap1 non-exist-map rmap5 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="10.0.0.2", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + advertise_map=dict(route_map="rmap1", exist_map="rmap3"), + ), + ], + ), + ], + vrfs=[ + dict( + vrf="site-1", + neighbors=[ + dict( + neighbor_address="192.168.1.1", + address_family=[ + dict( + afi="ipv4", + safi="unicast", + advertise_map=dict( + route_map="rmap2", + exist_map="rmap3", + ), + ), + dict(afi="ipv4", safi="multicast"), + ], + ), + ], + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65536", + "neighbor 10.0.0.2", + "address-family ipv4 multicast", + "advertise-map rmap1 exist-map rmap3", + "vrf site-1", + "neighbor 192.168.1.1", + "address-family ipv4 multicast", + "no advertise-map rmap1 non-exist-map rmap5", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_nbr_af_advertisement_interval_merged(self): + # test merged for advertisement_interval + self.get_config.return_value = dedent( + """\ + router bgp 65536 + vrf site-1 + neighbor 192.168.1.1 + address-family ipv4 unicast + advertisement-interval 300 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="10.0.0.2", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + advertisement_interval=350, + ), + ], + ), + ], + vrfs=[ + dict( + vrf="site-1", + neighbors=[ + dict( + neighbor_address="192.168.1.1", + address_family=[ + dict( + afi="ipv4", + safi="unicast", + advertisement_interval=300, + ), + dict( + afi="ipv4", + safi="multicast", + advertisement_interval=400, + ), + ], + ), + ], + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65536", + "neighbor 10.0.0.2", + "address-family ipv4 multicast", + "advertisement-interval 350", + "vrf site-1", + "neighbor 192.168.1.1", + "address-family ipv4 multicast", + "advertisement-interval 400", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_nbr_af_advertisement_interval_replaced(self): + # test replaced for advertisement_interval + self.get_config.return_value = dedent( + """\ + router bgp 65536 + neighbor 10.0.0.2 + address-family ipv4 unicast + advertisement-interval 410 + address-family ipv4 multicast + advertisement-interval 350 + vrf site-1 + neighbor 192.168.1.1 + address-family ipv4 unicast + advertisement-interval 300 + address-family ipv4 multicast + advertisement-interval 400 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="10.0.0.2", + address_family=[ + dict(afi="ipv4", safi="unicast"), + dict( + afi="ipv4", + safi="multicast", + advertisement_interval=350, + ), + ], + ), + ], + vrfs=[ + dict( + vrf="site-1", + neighbors=[ + dict( + neighbor_address="192.168.1.1", + address_family=[ + dict( + afi="ipv4", + safi="unicast", + advertisement_interval=300, + ), + dict(afi="ipv4", safi="multicast"), + ], + ), + ], + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65536", + "neighbor 10.0.0.2", + "address-family ipv4 unicast", + "no advertisement-interval 410", + "vrf site-1", + "neighbor 192.168.1.1", + "address-family ipv4 multicast", + "no advertisement-interval 400", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_nbr_af_allowas_in_merged(self): + # test merged for allowas_in + self.get_config.return_value = dedent( + """\ + router bgp 65536 + vrf site-1 + neighbor 192.168.1.1 + address-family ipv4 unicast + allowas-in 3 + address-family ipv4 multicast + allowas-in 3 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="10.0.0.2", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + allowas_in=dict(max_occurences=8), + ), + ], + ), + ], + vrfs=[ + dict( + vrf="site-1", + neighbors=[ + dict( + neighbor_address="192.168.1.1", + address_family=[ + dict( + afi="ipv4", + safi="unicast", + allowas_in=dict(max_occurences=5), + ), + dict( + afi="ipv4", + safi="multicast", + allowas_in=dict(max_occurences=3), + ), + ], + ), + ], + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65536", + "neighbor 10.0.0.2", + "address-family ipv4 multicast", + "allowas-in 8", + "vrf site-1", + "neighbor 192.168.1.1", + "address-family ipv4 unicast", + "allowas-in 5", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_nbr_af_allowas_in_replaced(self): + # test replaced for allowas_in + self.get_config.return_value = dedent( + """\ + router bgp 65536 + neighbor 10.0.0.2 + address-family ipv4 multicast + allowas-in 8 + vrf site-1 + neighbor 192.168.1.1 + address-family ipv4 unicast + allowas-in 5 + address-family ipv4 multicast + allowas-in 3 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="10.0.0.2", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + allowas_in=dict(max_occurences=9), + ), + ], + ), + ], + vrfs=[ + dict( + vrf="site-1", + neighbors=[ + dict( + neighbor_address="192.168.1.1", + address_family=[ + dict( + afi="ipv4", + safi="unicast", + allowas_in=dict(max_occurences=5), + ), + dict(afi="ipv4", safi="multicast"), + ], + ), + ], + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65536", + "neighbor 10.0.0.2", + "address-family ipv4 multicast", + "allowas-in 9", + "vrf site-1", + "neighbor 192.168.1.1", + "address-family ipv4 multicast", + "no allowas-in 3", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_nbr_af_as_override_merged(self): + # test merged for as_override + self.get_config.return_value = dedent( + """\ + router bgp 65536 + neighbor 10.0.0.2 + remote-as 65545 + vrf site-1 + neighbor 192.168.1.1 + remote-as 65545 + address-family ipv4 unicast + as-override + address-family ipv4 multicast + as-override + """, + ) + set_module_args( + dict( + config=dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="10.0.0.2", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + as_override=True, + ), + ], + ), + ], + vrfs=[ + dict( + vrf="site-1", + neighbors=[ + dict( + neighbor_address="192.168.1.1", + address_family=[ + dict( + afi="ipv4", + safi="unicast", + as_override=True, + ), + dict( + afi="ipv4", + safi="multicast", + as_override=False, + ), + ], + ), + ], + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65536", + "neighbor 10.0.0.2", + "address-family ipv4 multicast", + "as-override", + "vrf site-1", + "neighbor 192.168.1.1", + "address-family ipv4 multicast", + "no as-override", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_nbr_af_as_override_replaced(self): + # test replaced for as_override + self.get_config.return_value = dedent( + """\ + router bgp 65536 + neighbor 10.0.0.2 + remote-as 65545 + address-family ipv4 multicast + as-override + vrf site-1 + neighbor 192.168.1.1 + remote-as 65545 + address-family ipv4 unicast + as-override + address-family ipv4 multicast + as-override + """, + ) + set_module_args( + dict( + config=dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="10.0.0.2", + address_family=[dict(afi="ipv4", safi="multicast")], + ), + ], + vrfs=[ + dict( + vrf="site-1", + neighbors=[ + dict( + neighbor_address="192.168.1.1", + address_family=[ + dict( + afi="ipv4", + safi="unicast", + as_override=True, + ), + dict(afi="ipv4", safi="multicast"), + ], + ), + ], + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65536", + "neighbor 10.0.0.2", + "address-family ipv4 multicast", + "no as-override", + "vrf site-1", + "neighbor 192.168.1.1", + "address-family ipv4 multicast", + "no as-override", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_nbr_af_capability_merged(self): + # test merged for capability + self.get_config.return_value = dedent( + """\ + router bgp 65536 + vrf site-1 + neighbor 192.168.1.1 + address-family ipv4 unicast + capability additional-paths receive + capability additional-paths send disable + address-family ipv4 multicast + capability additional-paths receive disable + capability additional-paths send + """, + ) + set_module_args( + dict( + config=dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="10.0.0.2", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + capability=dict( + additional_paths=dict(receive="enable", send="enable"), + ), + ), + ], + ), + ], + vrfs=[ + dict( + vrf="site-1", + neighbors=[ + dict( + neighbor_address="192.168.1.1", + address_family=[ + dict( + afi="ipv4", + safi="unicast", + capability=dict( + additional_paths=dict( + receive="disable", + send="enable", + ), + ), + ), + dict( + afi="ipv4", + safi="multicast", + capability=dict( + additional_paths=dict( + receive="enable", + send="disable", + ), + ), + ), + ], + ), + ], + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65536", + "neighbor 10.0.0.2", + "address-family ipv4 multicast", + "capability additional-paths receive", + "capability additional-paths send", + "vrf site-1", + "neighbor 192.168.1.1", + "address-family ipv4 unicast", + "capability additional-paths receive disable", + "capability additional-paths send", + "address-family ipv4 multicast", + "capability additional-paths receive", + "capability additional-paths send disable", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_nbr_af_capability_replaced(self): + # test replaced for capability + self.get_config.return_value = dedent( + """\ + router bgp 65536 + neighbor 10.0.0.2 + address-family ipv4 multicast + capability additional-paths receive + capability additional-paths send + vrf site-1 + neighbor 192.168.1.1 + address-family ipv4 unicast + capability additional-paths receive disable + capability additional-paths send + address-family ipv4 multicast + capability additional-paths receive + capability additional-paths send disable + """, + ) + set_module_args( + dict( + config=dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="10.0.0.2", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + capability=dict(additional_paths=dict(send="enable")), + ), + ], + ), + ], + vrfs=[ + dict( + vrf="site-1", + neighbors=[ + dict( + neighbor_address="192.168.1.1", + address_family=[ + dict( + afi="ipv4", + safi="unicast", + capability=dict( + additional_paths=dict( + receive="disable", + send="enable", + ), + ), + ), + dict(afi="ipv4", safi="multicast"), + ], + ), + ], + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65536", + "neighbor 10.0.0.2", + "address-family ipv4 multicast", + "no capability additional-paths receive", + "vrf site-1", + "neighbor 192.168.1.1", + "address-family ipv4 multicast", + "no capability additional-paths receive", + "no capability additional-paths send disable", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_nbr_af_originate_peer_as_merged(self): + # test merged for default_originate, disable_peer_as_check + self.get_config.return_value = dedent( + """\ + router bgp 65536 + vrf site-1 + neighbor 192.168.1.1 + address-family ipv4 unicast + default-originate + disable-peer-as-check + address-family ipv4 multicast + default-originate route-map rmap1 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="10.0.0.2", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + default_originate=dict(set=True), + ), + dict( + afi="ipv4", + safi="unicast", + disable_peer_as_check=True, + default_originate=dict(route_map="rmap1"), + ), + ], + ), + ], + vrfs=[ + dict( + vrf="site-1", + neighbors=[ + dict( + neighbor_address="192.168.1.1", + address_family=[ + dict( + afi="ipv4", + safi="unicast", + disable_peer_as_check=True, + default_originate=dict(set=True), + ), + dict( + afi="ipv4", + safi="multicast", + default_originate=dict(route_map="rmap2"), + ), + ], + ), + ], + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65536", + "neighbor 10.0.0.2", + "address-family ipv4 multicast", + "default-originate", + "address-family ipv4 unicast", + "default-originate route-map rmap1", + "disable-peer-as-check", + "vrf site-1", + "neighbor 192.168.1.1", + "address-family ipv4 multicast", + "default-originate route-map rmap2", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_nbr_af_originate_peer_as_merged(self): + # test merged for default_originate, disable_peer_as_check + self.get_config.return_value = dedent( + """\ + router bgp 65536 + neighbor 10.0.0.2 + address-family ipv4 multicast + default-originate + address-family ipv4 unicast + default-originate route-map rmap1 + disable-peer-as-check + vrf site-1 + neighbor 192.168.1.1 + address-family ipv4 unicast + default-originate + disable-peer-as-check + address-family ipv4 multicast + default-originate route-map rmap1 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="10.0.0.2", + address_family=[ + dict(afi="ipv4", safi="multicast"), + dict( + afi="ipv4", + safi="unicast", + default_originate=dict(route_map="rmap1"), + ), + ], + ), + ], + vrfs=[ + dict( + vrf="site-1", + neighbors=[ + dict( + neighbor_address="192.168.1.1", + address_family=[ + dict( + afi="ipv4", + safi="unicast", + disable_peer_as_check=True, + default_originate=dict(set=True), + ), + dict(afi="ipv4", safi="multicast"), + ], + ), + ], + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65536", + "neighbor 10.0.0.2", + "address-family ipv4 multicast", + "no default-originate", + "address-family ipv4 unicast", + "no disable-peer-as-check", + "vrf site-1", + "neighbor 192.168.1.1", + "address-family ipv4 multicast", + "no default-originate route-map rmap1", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_nbr_af_filter_list_inherit_merged(self): + # test merged for filter_list, inherit + self.get_config.return_value = dedent( + """\ + router bgp 65536 + vrf site-1 + neighbor 192.168.1.1 + address-family ipv4 unicast + filter-list rmap1 in + filter-list rmap2 out + inherit peer-policy template-1 100 + address-family ipv4 multicast + filter-list rmap1 out + inherit peer-policy template-1 300 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="10.0.0.2", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + filter_list=dict(inbound="rmap3", outbound="rmap4"), + inherit=dict(template="template-2", sequence=200), + ), + ], + ), + ], + vrfs=[ + dict( + vrf="site-1", + neighbors=[ + dict( + neighbor_address="192.168.1.1", + address_family=[ + dict( + afi="ipv4", + safi="unicast", + filter_list=dict( + inbound="rmap1", + outbound="rmap2", + ), + inherit=dict( + template="template-1", + sequence=100, + ), + ), + dict( + afi="ipv4", + safi="multicast", + filter_list=dict(inbound="rmap2"), + inherit=dict( + template="template-1", + sequence=400, + ), + ), + ], + ), + ], + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65536", + "neighbor 10.0.0.2", + "address-family ipv4 multicast", + "filter-list rmap3 in", + "filter-list rmap4 out", + "inherit peer-policy template-2 200", + "vrf site-1", + "neighbor 192.168.1.1", + "address-family ipv4 multicast", + "filter-list rmap2 in", + "inherit peer-policy template-1 400", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_nbr_af_filter_list_inherit_replaced(self): + # test replaced for filter_list, inherit + self.get_config.return_value = dedent( + """\ + router bgp 65536 + neighbor 10.0.0.2 + address-family ipv4 multicast + filter-list rmap3 in + filter-list rmap4 out + inherit peer-policy template-2 200 + vrf site-1 + neighbor 192.168.1.1 + address-family ipv4 unicast + filter-list rmap1 in + filter-list rmap2 out + inherit peer-policy template-1 100 + address-family ipv4 multicast + filter-list rmap1 out + filter-list rmap2 in + inherit peer-policy template-1 300 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="10.0.0.2", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + filter_list=dict(inbound="rmap3"), + inherit=dict(template="template-2", sequence=200), + ), + ], + ), + ], + vrfs=[ + dict( + vrf="site-1", + neighbors=[ + dict( + neighbor_address="192.168.1.1", + address_family=[ + dict( + afi="ipv4", + safi="unicast", + filter_list=dict( + inbound="rmap1", + outbound="rmap2", + ), + inherit=dict( + template="template-1", + sequence=100, + ), + ), + dict(afi="ipv4", safi="multicast"), + ], + ), + ], + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65536", + "neighbor 10.0.0.2", + "address-family ipv4 multicast", + "no filter-list rmap4 out", + "vrf site-1", + "neighbor 192.168.1.1", + "address-family ipv4 multicast", + "no filter-list rmap2 in", + "no filter-list rmap1 out", + "no inherit peer-policy template-1 300", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_nbr_af_maximum_prefix_merged(self): + # test merged for maximum_prefix + self.get_config.return_value = dedent( + """\ + router bgp 65536 + vrf site-1 + neighbor 192.168.1.1 + address-family ipv4 multicast + maximum-prefix 12 + address-family ipv4 unicast + maximum-prefix 12 80 + address-family ipv6 multicast + maximum-prefix 12 85 warning-only + address-family ipv6 unicast + maximum-prefix 12 85 restart 1200 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="10.0.0.2", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + maximum_prefix=dict(max_prefix_limit=20), + ), + dict( + afi="ipv4", + safi="unicast", + maximum_prefix=dict( + max_prefix_limit=25, + generate_warning_threshold=85, + ), + ), + dict( + afi="ipv6", + safi="multicast", + maximum_prefix=dict( + max_prefix_limit=28, + generate_warning_threshold=90, + warning_only=True, + ), + ), + dict( + afi="ipv6", + safi="unicast", + maximum_prefix=dict( + max_prefix_limit=30, + generate_warning_threshold=95, + restart_interval=1200, + ), + ), + ], + ), + ], + vrfs=[ + dict( + vrf="site-1", + neighbors=[ + dict( + neighbor_address="192.168.1.1", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + maximum_prefix=dict(max_prefix_limit=28), + ), + dict( + afi="ipv4", + safi="unicast", + maximum_prefix=dict( + max_prefix_limit=12, + generate_warning_threshold=80, + ), + ), + dict( + afi="ipv6", + safi="multicast", + maximum_prefix=dict( + max_prefix_limit=12, + generate_warning_threshold=85, + warning_only=True, + ), + ), + dict( + afi="ipv6", + safi="unicast", + maximum_prefix=dict( + max_prefix_limit=12, + generate_warning_threshold=85, + restart_interval=1200, + ), + ), + ], + ), + ], + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65536", + "neighbor 10.0.0.2", + "address-family ipv4 multicast", + "maximum-prefix 20", + "address-family ipv4 unicast", + "maximum-prefix 25 85", + "address-family ipv6 multicast", + "maximum-prefix 28 90 warning-only", + "address-family ipv6 unicast", + "maximum-prefix 30 95 restart 1200", + "vrf site-1", + "neighbor 192.168.1.1", + "address-family ipv4 multicast", + "maximum-prefix 28", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_nbr_af_maximum_prefix_replaced(self): + # test replaced for maximum_prefix + self.get_config.return_value = dedent( + """\ + router bgp 65536 + neighbor 10.0.0.2 + address-family ipv4 multicast + maximum-prefix 20 + address-family ipv4 unicast + maximum-prefix 25 85 + vrf site-1 + neighbor 192.168.1.1 + address-family ipv4 multicast + maximum-prefix 12 + address-family ipv4 unicast + maximum-prefix 12 80 + address-family ipv6 multicast + maximum-prefix 12 85 warning-only + address-family ipv6 unicast + maximum-prefix 12 85 restart 1200 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="10.0.0.2", + address_family=[ + dict(afi="ipv4", safi="unicast"), + dict( + afi="ipv4", + safi="multicast", + maximum_prefix=dict(max_prefix_limit=28), + ), + ], + ), + ], + vrfs=[ + dict( + vrf="site-1", + neighbors=[ + dict( + neighbor_address="192.168.1.1", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + maximum_prefix=dict(max_prefix_limit=28), + ), + dict( + afi="ipv4", + safi="unicast", + maximum_prefix=dict( + max_prefix_limit=12, + generate_warning_threshold=80, + ), + ), + dict(afi="ipv6", safi="multicast"), + dict(afi="ipv6", safi="unicast"), + ], + ), + ], + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65536", + "neighbor 10.0.0.2", + "address-family ipv4 unicast", + "no maximum-prefix 25 85", + "address-family ipv6 multicast", + "maximum-prefix 28", + "vrf site-1", + "neighbor 192.168.1.1", + "address-family ipv4 multicast", + "maximum-prefix 28", + "address-family ipv6 multicast", + "no maximum-prefix 12 85 warning-only", + "address-family ipv6 unicast", + "no maximum-prefix 12 85 restart 1200", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_nbr_af_next_hop_merged(self): + # test merged for next_hop_self, next_hop_third_party + self.get_config.return_value = dedent( + """\ + router bgp 65536 + vrf site-1 + neighbor 192.168.1.1 + address-family ipv4 unicast + next-hop-self + no next-hop-third-party + address-family ipv4 multicast + next-hop-self all + """, + ) + set_module_args( + dict( + config=dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="10.0.0.2", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + next_hop_self=dict(set=True), + ), + dict( + afi="ipv4", + safi="unicast", + next_hop_self=dict(all_routes=True), + ), + ], + ), + ], + vrfs=[ + dict( + vrf="site-1", + neighbors=[ + dict( + neighbor_address="192.168.1.1", + address_family=[ + dict( + afi="ipv4", + safi="unicast", + next_hop_self=dict(set=True), + next_hop_third_party=True, + ), + dict( + afi="ipv4", + safi="multicast", + next_hop_self=dict(all_routes=True), + ), + dict( + afi="ipv6", + safi="multicast", + next_hop_self=dict(all_routes=True), + ), + ], + ), + ], + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65536", + "neighbor 10.0.0.2", + "address-family ipv4 multicast", + "next-hop-self", + "address-family ipv4 unicast", + "next-hop-self all", + "vrf site-1", + "neighbor 192.168.1.1", + "address-family ipv4 unicast", + "next-hop-third-party", + "address-family ipv6 multicast", + "next-hop-self all", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_nbr_af_next_hop_replaced(self): + # test replaced for next_hop_self, next_hop_third_party + self.get_config.return_value = dedent( + """\ + router bgp 65536 + neighbor 10.0.0.2 + address-family ipv4 multicast + next-hop-self + address-family ipv4 unicast + next-hop-self all + vrf site-1 + neighbor 192.168.1.1 + address-family ipv4 unicast + next-hop-self + no next-hop-third-party + address-family ipv4 multicast + next-hop-self all + """, + ) + set_module_args( + dict( + config=dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="10.0.0.2", + address_family=[ + dict(afi="ipv4", safi="multicast"), + dict( + afi="ipv4", + safi="unicast", + next_hop_self=dict(all_routes=True), + ), + ], + ), + ], + vrfs=[ + dict( + vrf="site-1", + neighbors=[ + dict( + neighbor_address="192.168.1.1", + address_family=[ + dict( + afi="ipv4", + safi="unicast", + next_hop_third_party=True, + ), + dict( + afi="ipv4", + safi="multicast", + next_hop_self=dict(all_routes=True), + ), + ], + ), + ], + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65536", + "neighbor 10.0.0.2", + "address-family ipv4 multicast", + "no next-hop-self", + "vrf site-1", + "neighbor 192.168.1.1", + "address-family ipv4 unicast", + "no next-hop-self", + "next-hop-third-party", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_nbr_af_prefix_list_merged(self): + # test merged for prefix_list + self.get_config.return_value = dedent( + """\ + router bgp 65536 + vrf site-1 + neighbor 192.168.1.1 + address-family ipv4 unicast + prefix-list rmap1 in + prefix-list rmap2 out + address-family ipv4 multicast + prefix-list rmap1 out + """, + ) + set_module_args( + dict( + config=dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="10.0.0.2", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + prefix_list=dict(inbound="rmap3", outbound="rmap4"), + ), + ], + ), + ], + vrfs=[ + dict( + vrf="site-1", + neighbors=[ + dict( + neighbor_address="192.168.1.1", + address_family=[ + dict( + afi="ipv4", + safi="unicast", + prefix_list=dict( + inbound="rmap1", + outbound="rmap2", + ), + ), + dict( + afi="ipv4", + safi="multicast", + prefix_list=dict(inbound="rmap2"), + ), + ], + ), + ], + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65536", + "neighbor 10.0.0.2", + "address-family ipv4 multicast", + "prefix-list rmap3 in", + "prefix-list rmap4 out", + "vrf site-1", + "neighbor 192.168.1.1", + "address-family ipv4 multicast", + "prefix-list rmap2 in", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_nbr_af_prefix_list_replaced(self): + # test replaced for prefix_list + self.get_config.return_value = dedent( + """\ + router bgp 65536 + neighbor 10.0.0.2 + address-family ipv4 multicast + prefix-list rmap3 in + prefix-list rmap4 out + vrf site-1 + neighbor 192.168.1.1 + address-family ipv4 unicast + prefix-list rmap1 in + prefix-list rmap2 out + address-family ipv4 multicast + prefix-list rmap1 out + prefix-list rmap2 in + """, + ) + set_module_args( + dict( + config=dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="10.0.0.2", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + prefix_list=dict(inbound="rmap3"), + ), + ], + ), + ], + vrfs=[ + dict( + vrf="site-1", + neighbors=[ + dict( + neighbor_address="192.168.1.1", + address_family=[ + dict( + afi="ipv4", + safi="unicast", + prefix_list=dict( + inbound="rmap1", + outbound="rmap2", + ), + ), + dict(afi="ipv4", safi="multicast"), + ], + ), + ], + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65536", + "neighbor 10.0.0.2", + "address-family ipv4 multicast", + "no prefix-list rmap4 out", + "vrf site-1", + "neighbor 192.168.1.1", + "address-family ipv4 multicast", + "no prefix-list rmap2 in", + "no prefix-list rmap1 out", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_nbr_af_rewrite_evpn_route_map_merged(self): + # test merged for rewrite_evpn_rt_asn, route_map + self.get_config.return_value = dedent( + """\ + router bgp 65536 + vrf site-1 + neighbor 192.168.1.1 + address-family ipv4 unicast + route-map rmap1 in + route-map rmap2 out + rewrite-evpn-rt-asn + address-family ipv4 multicast + route-map rmap1 out + rewrite-evpn-rt-asn + """, + ) + set_module_args( + dict( + config=dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="10.0.0.2", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + route_map=dict(inbound="rmap3", outbound="rmap4"), + rewrite_evpn_rt_asn=True, + ), + ], + ), + ], + vrfs=[ + dict( + vrf="site-1", + neighbors=[ + dict( + neighbor_address="192.168.1.1", + address_family=[ + dict( + afi="ipv4", + safi="unicast", + route_map=dict( + inbound="rmap1", + outbound="rmap2", + ), + rewrite_evpn_rt_asn=True, + ), + dict( + afi="ipv4", + safi="multicast", + route_map=dict(inbound="rmap2"), + rewrite_evpn_rt_asn=True, + ), + ], + ), + ], + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65536", + "neighbor 10.0.0.2", + "address-family ipv4 multicast", + "route-map rmap3 in", + "route-map rmap4 out", + "rewrite-evpn-rt-asn", + "vrf site-1", + "neighbor 192.168.1.1", + "address-family ipv4 multicast", + "route-map rmap2 in", + "rewrite-evpn-rt-asn", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_nbr_af_rewrite_evpn_route_map_replaced(self): + # test replaced for rewrite_evpn_rt_asn, route_map + self.get_config.return_value = dedent( + """\ + router bgp 65536 + neighbor 10.0.0.2 + address-family ipv4 multicast + route-map rmap3 in + route-map rmap4 out + rewrite-evpn-rt-asn + vrf site-1 + neighbor 192.168.1.1 + address-family ipv4 unicast + route-map rmap1 in + route-map rmap2 out + rewrite-evpn-rt-asn + address-family ipv4 multicast + route-map rmap1 out + route-map rmap2 in + rewrite-evpn-rt-asn + """, + ) + set_module_args( + dict( + config=dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="10.0.0.2", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + route_map=dict(inbound="rmap3"), + rewrite_evpn_rt_asn=True, + ), + ], + ), + ], + vrfs=[ + dict( + vrf="site-1", + neighbors=[ + dict( + neighbor_address="192.168.1.1", + address_family=[ + dict( + afi="ipv4", + safi="unicast", + route_map=dict( + inbound="rmap1", + outbound="rmap2", + ), + rewrite_evpn_rt_asn=True, + ), + dict(afi="ipv4", safi="multicast"), + ], + ), + ], + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65536", + "neighbor 10.0.0.2", + "address-family ipv4 multicast", + "no route-map rmap4 out", + "vrf site-1", + "neighbor 192.168.1.1", + "address-family ipv4 multicast", + "no route-map rmap2 in", + "no route-map rmap1 out", + "no rewrite-evpn-rt-asn", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_route_reflector_client_send_community_merged(self): + # test merged for route_reflector_client + self.get_config.return_value = dedent( + """\ + router bgp 65536 + vrf site-1 + neighbor 192.168.1.1 + address-family ipv4 unicast + route-reflector-client + send-community + """, + ) + set_module_args( + dict( + config=dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="10.0.0.2", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + route_reflector_client=True, + send_community=dict(extended=True), + ), + ], + ), + ], + vrfs=[ + dict( + vrf="site-1", + neighbors=[ + dict( + neighbor_address="192.168.1.1", + address_family=[ + dict( + afi="ipv4", + safi="unicast", + route_reflector_client=True, + send_community=dict(set=True), + ), + dict( + afi="ipv4", + safi="multicast", + send_community=dict(set=True), + ), + ], + ), + ], + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65536", + "neighbor 10.0.0.2", + "address-family ipv4 multicast", + "route-reflector-client", + "send-community extended", + "vrf site-1", + "neighbor 192.168.1.1", + "address-family ipv4 multicast", + "send-community", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_route_reflector_client_send_community_replaced(self): + # test replaced for route_reflector_client + self.get_config.return_value = dedent( + """\ + router bgp 65536 + neighbor 10.0.0.2 + address-family ipv4 multicast + route-reflector-client + send-community extended + vrf site-1 + neighbor 192.168.1.1 + address-family ipv4 unicast + route-reflector-client + send-community + address-family ipv4 multicast + send-community + """, + ) + set_module_args( + dict( + config=dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="10.0.0.2", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + send_community=dict(extended=True), + ), + ], + ), + ], + vrfs=[ + dict( + vrf="site-1", + neighbors=[ + dict( + neighbor_address="192.168.1.1", + address_family=[ + dict( + afi="ipv4", + safi="unicast", + route_reflector_client=True, + send_community=dict(set=True), + ), + dict(afi="ipv4", safi="multicast"), + ], + ), + ], + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65536", + "neighbor 10.0.0.2", + "address-family ipv4 multicast", + "no route-reflector-client", + "vrf site-1", + "neighbor 192.168.1.1", + "address-family ipv4 multicast", + "no send-community", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_nbr_af_soft_reconfiguration_soo_merged(self): + # test merged for soft_reconfiguration_inbound, soo + self.get_config.return_value = dedent( + """\ + router bgp 65536 + vrf site-1 + neighbor 192.168.1.1 + address-family ipv4 unicast + soft-reconfiguration inbound always + soo 65:28 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="10.0.0.2", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + soft_reconfiguration_inbound=dict(set=True), + soo="73:43", + ), + ], + ), + ], + vrfs=[ + dict( + vrf="site-1", + neighbors=[ + dict( + neighbor_address="192.168.1.1", + address_family=[ + dict( + afi="ipv4", + safi="unicast", + soft_reconfiguration_inbound=dict(always=True), + soo="65:28", + ), + dict( + afi="ipv4", + safi="multicast", + soft_reconfiguration_inbound=dict(always=True), + ), + ], + ), + ], + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65536", + "neighbor 10.0.0.2", + "address-family ipv4 multicast", + "soft-reconfiguration inbound", + "soo 73:43", + "vrf site-1", + "neighbor 192.168.1.1", + "address-family ipv4 multicast", + "soft-reconfiguration inbound always", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_nbr_af_soft_reconfiguration_soo_replaced(self): + # test replaced for soft_reconfiguration_inbound, soo + self.get_config.return_value = dedent( + """\ + router bgp 65536 + neighbor 10.0.0.2 + address-family ipv4 multicast + soft-reconfiguration inbound + soo 73:43 + vrf site-1 + neighbor 192.168.1.1 + address-family ipv4 unicast + soft-reconfiguration inbound always + soo 65:28 + address-family ipv4 multicast + soft-reconfiguration inbound always + """, + ) + set_module_args( + dict( + config=dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="10.0.0.2", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + soft_reconfiguration_inbound=dict(set=True), + ), + ], + ), + ], + vrfs=[ + dict( + vrf="site-1", + neighbors=[ + dict( + neighbor_address="192.168.1.1", + address_family=[ + dict( + afi="ipv4", + safi="unicast", + soft_reconfiguration_inbound=dict(always=True), + soo="65:28", + ), + dict(afi="ipv4", safi="multicast"), + ], + ), + ], + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65536", + "neighbor 10.0.0.2", + "address-family ipv4 multicast", + "no soo 73:43", + "vrf site-1", + "neighbor 192.168.1.1", + "address-family ipv4 multicast", + "no soft-reconfiguration inbound always", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_nbr_af_suppress_inactive_unsuppress_merged(self): + # test merged for suppress_inactive, unsuppress_map, weight + self.get_config.return_value = dedent( + """\ + router bgp 65536 + vrf site-1 + neighbor 192.168.1.1 + address-family ipv4 unicast + suppress-inactive + unsuppress-map rmap1 + address-family ipv4 multicast + weight 10 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="10.0.0.2", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + suppress_inactive=True, + unsuppress_map="rmap2", + weight=20, + ), + ], + ), + ], + vrfs=[ + dict( + vrf="site-1", + neighbors=[ + dict( + neighbor_address="192.168.1.1", + address_family=[ + dict( + afi="ipv4", + safi="unicast", + suppress_inactive=True, + unsuppress_map="rmap1", + weight=25, + ), + dict( + afi="ipv4", + safi="multicast", + suppress_inactive=True, + unsuppress_map="rmap4", + ), + ], + ), + ], + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65536", + "neighbor 10.0.0.2", + "address-family ipv4 multicast", + "suppress-inactive", + "unsuppress-map rmap2", + "weight 20", + "vrf site-1", + "neighbor 192.168.1.1", + "address-family ipv4 unicast", + "weight 25", + "address-family ipv4 multicast", + "suppress-inactive", + "unsuppress-map rmap4", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_nbr_af_suppress_inactive_unsuppress_replaced(self): + # test replaced for suppress_inactive, unsuppress_map, weight + self.get_config.return_value = dedent( + """\ + router bgp 65536 + neighbor 10.0.0.2 + address-family ipv4 multicast + suppress-inactive + unsuppress-map rmap2 + weight 20 + vrf site-1 + neighbor 192.168.1.1 + address-family ipv4 unicast + suppress-inactive + unsuppress-map rmap1 + weight 25 + address-family ipv4 multicast + suppress-inactive + unsuppress-map rmap4 + weight 10 + """, + ) + set_module_args( + dict( + config=dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="10.0.0.2", + address_family=[dict(afi="ipv4", safi="multicast")], + ), + ], + vrfs=[ + dict( + vrf="site-1", + neighbors=[ + dict( + neighbor_address="192.168.1.1", + address_family=[ + dict( + afi="ipv4", + safi="unicast", + suppress_inactive=True, + unsuppress_map="rmap1", + weight=25, + ), + dict(afi="ipv4", safi="multicast"), + ], + ), + ], + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65536", + "neighbor 10.0.0.2", + "address-family ipv4 multicast", + "no suppress-inactive", + "no unsuppress-map rmap2", + "no weight 20", + "vrf site-1", + "neighbor 192.168.1.1", + "address-family ipv4 multicast", + "no suppress-inactive", + "no unsuppress-map rmap4", + "no weight 10", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_nbr_af_deleted(self): + # test deleted + self.get_config.return_value = dedent( + """\ + router bgp 65536 + neighbor 10.0.0.2 + address-family ipv4 multicast + address-family ipv6 unicast + address-family link-state + neighbor 10.0.0.3 + address-family ipv4 unicast + vrf site-1 + neighbor 192.168.1.1 + address-family ipv4 unicast + address-family ipv4 multicast + address-family ipv6 unicast + """, + ) + set_module_args( + dict( + config=dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="10.0.0.2", + address_family=[ + dict(afi="ipv4", safi="multicast"), + dict(afi="link-state"), + ], + ), + ], + vrfs=[ + dict( + vrf="site-1", + neighbors=[ + dict( + neighbor_address="192.168.1.1", + address_family=[ + dict(afi="ipv4", safi="unicast"), + dict(afi="ipv4", safi="multicast"), + ], + ), + ], + ), + ], + ), + state="deleted", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65536", + "neighbor 10.0.0.2", + "no address-family ipv4 multicast", + "no address-family link-state", + "vrf site-1", + "neighbor 192.168.1.1", + "no address-family ipv4 unicast", + "no address-family ipv4 multicast", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_nbr_af_deleted_all(self): + # test deleted all + self.get_config.return_value = dedent( + """\ + router bgp 65536 + neighbor 10.0.0.2 + address-family ipv4 multicast + address-family ipv6 unicast + address-family link-state + neighbor 10.0.0.3 + address-family ipv4 unicast + vrf site-1 + neighbor 192.168.1.1 + address-family ipv4 unicast + address-family ipv4 multicast + address-family ipv6 unicast + """, + ) + set_module_args(dict(state="deleted"), ignore_provider_arg) + commands = [ + "router bgp 65536", + "neighbor 10.0.0.2", + "no address-family ipv4 unicast", + "no address-family ipv4 multicast", + "no address-family link-state", + "neighbor 10.0.0.3", + "no address-family ipv4 unicast", + "vrf site-1", + "neighbor 192.168.1.1", + "no address-family ipv4 unicast", + "no address-family ipv4 multicast", + "no address-family ipv6 unicast", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_nbr_af_overridden(self): + # test overridden + self.get_config.return_value = dedent( + """\ + router bgp 65536 + neighbor 10.0.0.2 + address-family ipv4 multicast + address-family ipv6 unicast + address-family link-state + neighbor 10.0.0.3 + address-family ipv4 unicast + vrf site-1 + neighbor 192.168.1.1 + address-family ipv4 unicast + address-family ipv4 multicast + address-family ipv6 unicast + """, + ) + set_module_args( + dict( + config=dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="10.0.0.3", + address_family=[ + dict(afi="ipv4", safi="unicast"), + dict( + afi="link-state", + route_reflector_client=True, + ), + ], + ), + ], + vrfs=[ + dict( + vrf="site-1", + neighbors=[ + dict( + neighbor_address="192.168.1.1", + address_family=[dict(afi="ipv4", safi="multicast")], + ), + ], + ), + ], + ), + state="overridden", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65536", + "neighbor 10.0.0.2", + "no address-family ipv4 unicast", + "no address-family ipv4 multicast", + "no address-family link-state", + "neighbor 10.0.0.3", + "address-family link-state", + "route-reflector-client", + "vrf site-1", + "neighbor 192.168.1.1", + "no address-family ipv4 multicast", + "no address-family ipv6 unicast", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_bgp_nbr_af_gathered(self): + # test gathered + self.get_config.return_value = dedent( + """\ + router bgp 65536 + neighbor 10.0.0.3 + address-family ipv4 unicast + address-family link-state + vrf site-1 + neighbor 192.168.1.1 + address-family ipv4 multicast + """, + ) + set_module_args(dict(state="gathered"), ignore_provider_arg) + gathered = dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="10.0.0.3", + address_family=[ + dict(afi="ipv4", safi="unicast"), + dict(afi="link-state"), + ], + ), + ], + vrfs=[ + dict( + vrf="site-1", + neighbors=[ + dict( + neighbor_address="192.168.1.1", + address_family=[dict(afi="ipv4", safi="multicast")], + ), + ], + ), + ], + ) + result = self.execute_module(changed=False) + self.assertEqual(result["gathered"], gathered) + + def test_nxos_bgp_nbr_af_parsed(self): + # test parsed + set_module_args( + dict( + running_config=dedent( + """\ + router bgp 65536 + neighbor 10.0.0.3 + address-family ipv4 unicast + address-family link-state + vrf site-1 + neighbor 192.168.1.1 + address-family ipv4 multicast + """, + ), + state="parsed", + ), + ignore_provider_arg, + ) + parsed = dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="10.0.0.3", + address_family=[ + dict(afi="ipv4", safi="unicast"), + dict(afi="link-state"), + ], + ), + ], + vrfs=[ + dict( + vrf="site-1", + neighbors=[ + dict( + neighbor_address="192.168.1.1", + address_family=[dict(afi="ipv4", safi="multicast")], + ), + ], + ), + ], + ) + result = self.execute_module(changed=False) + self.assertEqual(result["parsed"], parsed) + + def test_nxos_bgp_nbr_af_rendered(self): + # test rendered + set_module_args( + dict( + config=dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="10.0.0.2", + address_family=[ + dict( + afi="ipv4", + safi="multicast", + suppress_inactive=True, + unsuppress_map="rmap2", + weight=20, + ), + ], + ), + ], + vrfs=[ + dict( + vrf="site-1", + neighbors=[ + dict( + neighbor_address="192.168.1.1", + address_family=[ + dict( + afi="ipv4", + safi="unicast", + suppress_inactive=True, + unsuppress_map="rmap1", + weight=25, + ), + dict( + afi="ipv4", + safi="multicast", + suppress_inactive=True, + unsuppress_map="rmap4", + ), + ], + ), + ], + ), + ], + ), + state="rendered", + ), + ignore_provider_arg, + ) + rendered = [ + "router bgp 65536", + "neighbor 10.0.0.2", + "address-family ipv4 multicast", + "suppress-inactive", + "unsuppress-map rmap2", + "weight 20", + "vrf site-1", + "neighbor 192.168.1.1", + "address-family ipv4 unicast", + "suppress-inactive", + "unsuppress-map rmap1", + "weight 25", + "address-family ipv4 multicast", + "suppress-inactive", + "unsuppress-map rmap4", + ] + result = self.execute_module(changed=False) + self.assertEqual(set(result["rendered"]), set(rendered)) + + def test_nxos_bgp_nbr_af_gathered_empty(self): + # test gathered + self.get_config.return_value = dedent( + """\ + """, + ) + set_module_args(dict(state="gathered"), ignore_provider_arg) + gathered = dict() + result = self.execute_module(changed=False) + self.assertEqual(result["gathered"], gathered) + + def test_nxos_bgp_nbr_af_gathered_only_asn(self): + # test gathered + self.get_config.return_value = dedent( + """\ + router bgp 65563 + """, + ) + set_module_args(dict(state="gathered"), ignore_provider_arg) + gathered = dict(as_number="65563") + result = self.execute_module(changed=False) + self.assertEqual(result["gathered"], gathered) + + def test_nxos_bgp_nbr_af_no_cmd(self): + # test merged for rewrite_evpn_rt_asn, route_map + self.get_config.return_value = dedent( + """\ + router bgp 65536 + neighbor 10.0.0.2 + address-family ipv4 multicast + """, + ) + set_module_args( + dict( + config=dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="10.0.0.2", + address_family=[dict(afi="ipv4", safi="multicast")], + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_bgp_af_send_community(self): + # test merged for send_community + self.get_config.return_value = dedent( + """\ + router bgp 65536 + neighbor 10.0.0.2 + address-family l2vpn evpn + neighbor 10.0.0.3 + address-family l2vpn evpn + send-community + send-community extended + """, + ) + set_module_args( + dict( + config=dict( + as_number="65536", + neighbors=[ + dict( + neighbor_address="10.0.0.2", + address_family=[ + dict( + afi="l2vpn", + safi="evpn", + send_community=dict(both=True), + ), + ], + ), + dict( + neighbor_address="10.0.0.3", + address_family=[ + dict( + afi="l2vpn", + safi="evpn", + send_community=dict(both=True), + ), + ], + ), + dict( + neighbor_address="10.0.0.4", + address_family=[ + dict( + afi="l2vpn", + safi="evpn", + send_community=dict(set=True), + ), + ], + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router bgp 65536", + "neighbor 10.0.0.2", + "address-family l2vpn evpn", + "send-community", + "send-community extended", + "neighbor 10.0.0.4", + "address-family l2vpn evpn", + "send-community", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_bgp_neighbor_af.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_bgp_neighbor_af.py new file mode 100644 index 00000000..8b918d0e --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_bgp_neighbor_af.py @@ -0,0 +1,259 @@ +# (c) 2016 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from ansible_collections.cisco.nxos.plugins.modules import nxos_bgp_neighbor_af +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, load_fixture, set_module_args + + +class TestNxosBgpNeighborAfModule(TestNxosModule): + module = nxos_bgp_neighbor_af + + def setUp(self): + super(TestNxosBgpNeighborAfModule, self).setUp() + + self.mock_load_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_bgp_neighbor_af.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_get_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_bgp_neighbor_af.get_config", + ) + self.get_config = self.mock_get_config.start() + + def tearDown(self): + super(TestNxosBgpNeighborAfModule, self).tearDown() + self.mock_load_config.stop() + self.mock_get_config.stop() + + def load_fixtures(self, commands=None, device=""): + self.get_config.return_value = load_fixture("nxos_bgp", "config.cfg") + self.load_config.return_value = [] + + def test_nxos_bgp_neighbor_af(self): + set_module_args( + dict( + asn=65535, + neighbor="192.0.2.3", + afi="ipv4", + safi="unicast", + route_reflector_client=True, + ), + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "router bgp 65535", + "neighbor 192.0.2.3", + "address-family ipv4 unicast", + "route-reflector-client", + ], + ) + + def test_nxos_bgp_neighbor_af_exists(self): + set_module_args(dict(asn=65535, neighbor="3.3.3.5", afi="ipv4", safi="unicast")) + self.execute_module(changed=False, commands=[]) + + def test_nxos_bgp_neighbor_af_absent(self): + set_module_args( + dict( + asn=65535, + neighbor="3.3.3.5", + afi="ipv4", + safi="unicast", + state="absent", + ), + ) + self.execute_module( + changed=True, + sort=False, + commands=[ + "router bgp 65535", + "neighbor 3.3.3.5", + "no address-family ipv4 unicast", + ], + ) + + def test_nxos_bgp_neighbor_af_advertise_map(self): + set_module_args( + dict( + asn=65535, + neighbor="3.3.3.5", + afi="ipv4", + safi="unicast", + advertise_map_exist=["my_advertise_map", "my_exist_map"], + ), + ) + self.execute_module( + changed=True, + sort=False, + commands=[ + "router bgp 65535", + "neighbor 3.3.3.5", + "address-family ipv4 unicast", + "advertise-map my_advertise_map exist-map my_exist_map", + ], + ) + + def test_nxos_bgp_neighbor_af_advertise_map_non_exist(self): + set_module_args( + dict( + asn=65535, + neighbor="3.3.3.5", + afi="ipv4", + safi="unicast", + advertise_map_non_exist=[ + "my_advertise_map", + "my_non_exist_map", + ], + ), + ) + self.execute_module( + changed=True, + sort=False, + commands=[ + "router bgp 65535", + "neighbor 3.3.3.5", + "address-family ipv4 unicast", + "advertise-map my_advertise_map non-exist-map my_non_exist_map", + ], + ) + + def test_nxos_bgp_neighbor_af_max_prefix_limit_default(self): + set_module_args( + dict( + asn=65535, + neighbor="3.3.3.5", + afi="ipv4", + safi="unicast", + max_prefix_limit="default", + ), + ) + self.execute_module( + changed=True, + sort=False, + commands=[ + "router bgp 65535", + "neighbor 3.3.3.5", + "address-family ipv4 unicast", + "no maximum-prefix", + ], + ) + + def test_nxos_bgp_neighbor_af_max_prefix(self): + set_module_args( + dict( + asn=65535, + neighbor="3.3.3.5", + afi="ipv4", + safi="unicast", + max_prefix_threshold=20, + max_prefix_limit=20, + ), + ) + self.execute_module( + changed=True, + sort=False, + commands=[ + "router bgp 65535", + "neighbor 3.3.3.5", + "address-family ipv4 unicast", + "maximum-prefix 20 20", + ], + ) + + def test_nxos_bgp_neighbor_af_disable_peer_as_check(self): + set_module_args( + dict( + asn=65535, + neighbor="3.3.3.5", + afi="ipv4", + safi="unicast", + disable_peer_as_check=True, + ), + ) + self.execute_module( + changed=True, + commands=[ + "router bgp 65535", + "neighbor 3.3.3.5", + "address-family ipv4 unicast", + "disable-peer-as-check", + ], + ) + + def test_nxos_bgp_neighbor_af_rewrite_evpn(self): + set_module_args( + dict( + asn=65535, + neighbor="30.30.30.5", + afi="l2vpn", + safi="evpn", + rewrite_evpn_rt_asn=True, + ), + ) + self.execute_module( + changed=True, + commands=[ + "router bgp 65535", + "neighbor 30.30.30.5", + "address-family l2vpn evpn", + "rewrite-evpn-rt-asn", + ], + ) + + def test_nxos_bgp_neighbor_af_rewrite_evpn_disable(self): + set_module_args( + dict( + asn=65535, + neighbor="30.30.30.5", + afi="l2vpn", + safi="evpn", + rewrite_evpn_rt_asn=False, + ), + ) + self.execute_module( + changed=True, + commands=[ + "router bgp 65535", + "neighbor 30.30.30.5", + "address-family l2vpn evpn", + "no rewrite-evpn-rt-asn", + ], + ) + + def test_nxos_bgp_neighbor_af_rewrite_evpn_exists(self): + set_module_args( + dict( + asn=65535, + neighbor="7.7.7.7", + afi="l2vpn", + safi="evpn", + rewrite_evpn_rt_asn=True, + ), + ) + self.execute_module(changed=False, commands=[]) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_command.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_command.py new file mode 100644 index 00000000..cb7c40ba --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_command.py @@ -0,0 +1,122 @@ +# (c) 2016 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +import json + +from ansible_collections.cisco.nxos.plugins.modules import nxos_command +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, load_fixture, set_module_args + + +class TestNxosCommandModule(TestNxosModule): + module = nxos_command + + def setUp(self): + super(TestNxosCommandModule, self).setUp() + + self.mock_run_commands = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_command.run_commands", + ) + self.run_commands = self.mock_run_commands.start() + + def tearDown(self): + super(TestNxosCommandModule, self).tearDown() + self.mock_run_commands.stop() + + def load_fixtures(self, commands=None, device=""): + def load_from_file(*args, **kwargs): + module, commands = args + output = list() + + for item in commands: + try: + obj = json.loads(item["command"]) + command = obj["command"] + except ValueError: + command = item["command"] + filename = "%s.txt" % str(command).replace(" ", "_") + output.append(load_fixture("nxos_command", filename)) + return output + + self.run_commands.side_effect = load_from_file + + def test_nxos_command_simple(self): + set_module_args(dict(commands=["show version"])) + result = self.execute_module() + self.assertEqual(len(result["stdout"]), 1) + self.assertTrue(result["stdout"][0].startswith("Cisco")) + + def test_nxos_command_multiple(self): + set_module_args(dict(commands=["show version", "show version"])) + result = self.execute_module() + self.assertEqual(len(result["stdout"]), 2) + self.assertTrue(result["stdout"][0].startswith("Cisco")) + + def test_nxos_command_wait_for(self): + wait_for = 'result[0] contains "NX-OS"' + set_module_args(dict(commands=["show version"], wait_for=wait_for)) + self.execute_module() + + def test_nxos_command_wait_for_fails(self): + wait_for = 'result[0] contains "test string"' + set_module_args(dict(commands=["show version"], wait_for=wait_for)) + self.execute_module(failed=True) + self.assertEqual(self.run_commands.call_count, 10) + + def test_nxos_command_retries(self): + wait_for = 'result[0] contains "test string"' + set_module_args(dict(commands=["show version"], wait_for=wait_for, retries=2)) + self.execute_module(failed=True) + self.assertEqual(self.run_commands.call_count, 3) + + def test_nxos_command_retries_0(self): + set_module_args(dict(commands=["show version"], retries=0)) + self.execute_module(failed=False) + self.assertEqual(self.run_commands.call_count, 1) + + def test_nxos_command_match_any(self): + wait_for = [ + 'result[0] contains "Cisco"', + 'result[0] contains "test string"', + ] + set_module_args(dict(commands=["show version"], wait_for=wait_for, match="any")) + self.execute_module() + + def test_nxos_command_match_all(self): + wait_for = [ + 'result[0] contains "Cisco"', + 'result[0] contains "image file"', + ] + set_module_args(dict(commands=["show version"], wait_for=wait_for, match="all")) + self.execute_module() + + def test_nxos_command_match_all_failure(self): + wait_for = [ + 'result[0] contains "Cisco"', + 'result[0] contains "test string"', + ] + commands = ["show version", "show version"] + set_module_args(dict(commands=commands, wait_for=wait_for, match="all")) + self.execute_module(failed=True) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_config.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_config.py new file mode 100644 index 00000000..83e58722 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_config.py @@ -0,0 +1,273 @@ +# (c) 2016 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from ansible_collections.cisco.nxos.plugins.cliconf.nxos import Cliconf +from ansible_collections.cisco.nxos.plugins.modules import nxos_config +from ansible_collections.cisco.nxos.tests.unit.compat.mock import MagicMock, patch + +from .nxos_module import TestNxosModule, load_fixture, set_module_args + + +class TestNxosConfigModule(TestNxosModule): + module = nxos_config + + def setUp(self): + super(TestNxosConfigModule, self).setUp() + + self.mock_get_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_config.get_config", + ) + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_config.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_save_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_config.save_config", + ) + self.save_config = self.mock_save_config.start() + + self.mock_get_connection = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_config.get_connection", + ) + self.get_connection = self.mock_get_connection.start() + + self.conn = self.get_connection() + self.conn.edit_config = MagicMock() + + self.mock_run_commands = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_config.run_commands", + ) + self.run_commands = self.mock_run_commands.start() + + self.cliconf_obj = Cliconf(MagicMock()) + self.running_config = load_fixture("nxos_config", "config.cfg") + + def tearDown(self): + super(TestNxosConfigModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + self.mock_run_commands.stop() + self.mock_get_connection.stop() + + def load_fixtures(self, commands=None, device=""): + self.get_config.return_value = load_fixture("nxos_config", "config.cfg") + self.load_config.return_value = None + + def test_nxos_config_no_change(self): + lines = ["hostname localhost"] + args = dict(lines=lines) + self.conn.get_diff = MagicMock( + return_value=self.cliconf_obj.get_diff("\n".join(lines), self.running_config), + ) + set_module_args(args) + result = self.execute_module() + + def test_nxos_config_src(self): + src = load_fixture("nxos_config", "candidate.cfg") + args = dict(src=src) + self.conn.get_diff = MagicMock( + return_value=self.cliconf_obj.get_diff(src, self.running_config), + ) + set_module_args(args) + + result = self.execute_module(changed=True) + config = [ + "hostname switch01", + "interface Ethernet1", + "description test interface", + "no shutdown", + "ip routing", + ] + + self.assertEqual(sorted(config), sorted(result["commands"]), result["commands"]) + + def test_nxos_config_replace_src(self): + set_module_args(dict(replace_src="bootflash:config", replace="config")) + self.conn.get_diff = MagicMock( + return_value=self.cliconf_obj.get_diff( + self.running_config, + self.running_config, + diff_replace="config", + ), + ) + result = self.execute_module(changed=True) + self.assertEqual(result["commands"], ["config replace bootflash:config"]) + + def test_nxos_config_lines(self): + lines = ["hostname switch01", "ip domain-name eng.ansible.com"] + args = dict(lines=lines) + self.conn.get_diff = MagicMock( + return_value=self.cliconf_obj.get_diff("\n".join(lines), self.running_config), + ) + set_module_args(args) + + result = self.execute_module(changed=True) + config = ["hostname switch01"] + + self.assertEqual(sorted(config), sorted(result["commands"]), result["commands"]) + + def test_nxos_config_before(self): + lines = ["hostname switch01", "ip domain-name eng.ansible.com"] + args = dict(lines=lines, before=["before command"]) + self.conn.get_diff = MagicMock( + return_value=self.cliconf_obj.get_diff("\n".join(lines), self.running_config), + ) + set_module_args(args) + + result = self.execute_module(changed=True) + config = ["before command", "hostname switch01"] + + self.assertEqual(sorted(config), sorted(result["commands"]), result["commands"]) + self.assertEqual("before command", result["commands"][0]) + + def test_nxos_config_after(self): + lines = ["hostname switch01", "ip domain-name eng.ansible.com"] + args = dict(lines=lines, after=["after command"]) + + self.conn.get_diff = MagicMock( + return_value=self.cliconf_obj.get_diff("\n".join(lines), self.running_config), + ) + set_module_args(args) + + result = self.execute_module(changed=True) + config = ["after command", "hostname switch01"] + + self.assertEqual(sorted(config), sorted(result["commands"]), result["commands"]) + self.assertEqual("after command", result["commands"][-1]) + + def test_nxos_config_parents(self): + lines = ["ip address 1.2.3.4/5", "no shutdown"] + parents = ["interface Ethernet10"] + args = dict(lines=lines, parents=parents) + self.conn.get_diff = MagicMock( + return_value=self.cliconf_obj.get_diff( + "\n".join(parents + lines), + self.running_config, + path=parents, + ), + ) + set_module_args(args) + + result = self.execute_module(changed=True) + config = [ + "interface Ethernet10", + "ip address 1.2.3.4/5", + "no shutdown", + ] + + self.assertEqual(config, result["commands"], result["commands"]) + + def test_nxos_config_src_and_lines_fails(self): + args = dict(src="foo", lines="foo") + set_module_args(args) + result = self.execute_module(failed=True) + + def test_nxos_config_src_and_parents_fails(self): + args = dict(src="foo", parents="foo") + set_module_args(args) + result = self.execute_module(failed=True) + + def test_nxos_config_match_exact_requires_lines(self): + args = dict(match="exact") + set_module_args(args) + result = self.execute_module(failed=True) + + def test_nxos_config_match_strict_requires_lines(self): + args = dict(match="strict") + set_module_args(args) + result = self.execute_module(failed=True) + + def test_nxos_config_replace_block_requires_lines(self): + args = dict(replace="block") + set_module_args(args) + result = self.execute_module(failed=True) + + def test_nxos_config_replace_config_requires_src(self): + args = dict(replace="config") + set_module_args(args) + result = self.execute_module(failed=True) + + def test_nxos_config_backup_returns__backup__(self): + args = dict(backup=True) + set_module_args(args) + result = self.execute_module() + self.assertIn("__backup__", result) + + def test_nxos_config_save_always(self): + args = dict(save_when="always") + set_module_args(args) + self.execute_module() + self.assertEqual(self.save_config.call_count, 1) + self.assertEqual(self.get_config.call_count, 0) + self.assertEqual(self.load_config.call_count, 0) + + def test_nxos_config_save_changed_true(self): + args = dict( + save_when="changed", + lines=[ + "hostname foo", + "interface GigabitEthernet0/0", + "no ip address", + ], + ) + set_module_args(args) + self.execute_module(changed=True) + self.assertEqual(self.save_config.call_count, 1) + self.assertEqual(self.get_config.call_count, 1) + self.assertEqual(self.load_config.call_count, 1) + + def test_nxos_config_save_changed_false(self): + args = dict(save_when="changed") + set_module_args(args) + self.execute_module() + self.assertEqual(self.save_config.call_count, 0) + self.assertEqual(self.get_config.call_count, 0) + self.assertEqual(self.load_config.call_count, 0) + + def test_nxos_config_defaults_false(self): + set_module_args(dict(lines=["hostname localhost"], defaults=False)) + result = self.execute_module(changed=True) + self.assertEqual(self.get_config.call_count, 1) + self.assertEqual(self.get_config.call_args[1], dict(flags=[])) + + def test_nxos_config_defaults_true(self): + set_module_args(dict(lines=["hostname localhost"], defaults=True)) + result = self.execute_module(changed=True) + self.assertEqual(self.get_config.call_count, 1) + self.assertEqual(self.get_config.call_args[1], dict(flags=["all"])) + + def test_nxos_config_defaults_false_backup_true(self): + set_module_args(dict(lines=["hostname localhost"], defaults=False, backup=True)) + result = self.execute_module(changed=True) + self.assertEqual(self.get_config.call_count, 1) + self.assertEqual(self.get_config.call_args[1], dict(flags=[])) + + def test_nxos_config_defaults_true_backup_true(self): + set_module_args(dict(lines=["hostname localhost"], defaults=True, backup=True)) + result = self.execute_module(changed=True) + self.assertEqual(self.get_config.call_count, 1) + self.assertEqual(self.get_config.call_args[1], dict(flags=["all"])) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_evpn_global.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_evpn_global.py new file mode 100644 index 00000000..c9fa7911 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_evpn_global.py @@ -0,0 +1,78 @@ +# +# (c) 2016 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from ansible_collections.cisco.nxos.plugins.modules import nxos_evpn_global +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, load_fixture, set_module_args + + +class TestNxosEvpnGlobalModule(TestNxosModule): + module = nxos_evpn_global + + def setUp(self): + super(TestNxosEvpnGlobalModule, self).setUp() + self.mock_get_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_evpn_global.get_config", + ) + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_evpn_global.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_get_capabilities = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_evpn_global.get_capabilities", + ) + self.get_capabilities = self.mock_get_capabilities.start() + self.get_capabilities.return_value = {"network_api": "cliconf"} + + def tearDown(self): + super(TestNxosEvpnGlobalModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + self.mock_get_capabilities.stop() + + def load_fixtures(self, commands=None, device=""): + self.load_config.return_value = None + + def start_configured(self, *args, **kwargs): + self.get_config.return_value = load_fixture("nxos_evpn_global", "configured.cfg") + return self.execute_module(*args, **kwargs) + + def start_unconfigured(self, *args, **kwargs): + self.get_config.return_value = load_fixture("nxos_evpn_global", "unconfigured.cfg") + return self.execute_module(*args, **kwargs) + + def test_nxos_evpn_global_enable(self): + set_module_args(dict(nv_overlay_evpn=True)) + commands = ["nv overlay evpn"] + self.start_unconfigured(changed=True, commands=commands) + + def test_nxos_evpn_global_disable(self): + set_module_args(dict(nv_overlay_evpn=False)) + commands = ["no nv overlay evpn"] + self.start_configured(changed=True, commands=commands) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_evpn_vni.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_evpn_vni.py new file mode 100644 index 00000000..0211a5a3 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_evpn_vni.py @@ -0,0 +1,77 @@ +# (c) 2016 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from ansible_collections.cisco.nxos.plugins.modules import nxos_evpn_vni +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, load_fixture, set_module_args + + +class TestNxosEvpnVniModule(TestNxosModule): + module = nxos_evpn_vni + + def setUp(self): + super(TestNxosEvpnVniModule, self).setUp() + + self.mock_load_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_evpn_vni.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_get_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_evpn_vni.get_config", + ) + self.get_config = self.mock_get_config.start() + + def tearDown(self): + super(TestNxosEvpnVniModule, self).tearDown() + self.mock_load_config.stop() + self.mock_get_config.stop() + + def load_fixtures(self, commands=None, device=""): + self.get_config.return_value = load_fixture("", "nxos_evpn_vni_config.cfg") + self.load_config.return_value = None + + def test_nxos_evpn_vni_present(self): + set_module_args(dict(vni="6000", route_target_import="5000:10", state="present")) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "evpn", + "vni 6000 l2", + "route-target import 5000:10", + "no route-target import auto", + ], + ) + + def test_nxos_evpn_vni_absent_not_existing(self): + set_module_args(dict(vni="12000", state="absent")) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_evpn_vni_absent_existing(self): + set_module_args(dict(vni="6000", state="absent")) + result = self.execute_module(changed=True) + self.assertEqual(result["commands"], ["evpn", "no vni 6000 l2"]) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_feature.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_feature.py new file mode 100644 index 00000000..1c79537f --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_feature.py @@ -0,0 +1,172 @@ +# (c) 2016 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +import json + +from ansible_collections.cisco.nxos.plugins.modules import nxos_feature +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, load_fixture, set_module_args + + +class TestNxosFeatureModule(TestNxosModule): + module = nxos_feature + + def setUp(self): + super(TestNxosFeatureModule, self).setUp() + self.mock_run_commands = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_feature.run_commands", + ) + self.run_commands = self.mock_run_commands.start() + + self.mock_load_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_feature.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_get_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_feature.get_config", + ) + self.get_config = self.mock_get_config.start() + + self.mock_get_capabilities = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_feature.get_capabilities", + ) + self.get_capabilities = self.mock_get_capabilities.start() + self.get_capabilities.return_value = {"network_api": "cliconf"} + + def tearDown(self): + super(TestNxosFeatureModule, self).tearDown() + self.mock_run_commands.stop() + self.mock_load_config.stop() + self.mock_get_config.stop() + self.mock_get_capabilities.stop() + + def load_fixtures(self, commands=None, device=""): + def load_from_file(*args, **kwargs): + module, commands = args + output = list() + + for item in commands: + try: + obj = json.loads(item["command"]) + command = obj["command"] + except ValueError: + command = item["command"] + filename = "%s.txt" % str(command).replace(" ", "_") + output.append(load_fixture("nxos_feature", filename)) + return output + + self.run_commands.side_effect = load_from_file + self.get_config.return_value = "" + self.load_config.return_value = None + + def test_nxos_feature_enable(self): + set_module_args(dict(feature="nve", state="enabled")) + result = self.execute_module(changed=True) + self.assertEqual(result["commands"], ["terminal dont-ask", "feature nv overlay"]) + + def test_nxos_feature_disable(self): + set_module_args(dict(feature="ospf", state="disabled")) + result = self.execute_module(changed=True) + self.assertEqual(result["commands"], ["terminal dont-ask", "no feature ospf"]) + + +class TestNxosFeatureModuleMDS(TestNxosModule): + module = nxos_feature + + def setUp(self): + super(TestNxosFeatureModuleMDS, self).setUp() + self.mock_run_commands = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_feature.run_commands", + ) + self.run_commands = self.mock_run_commands.start() + + self.mock_load_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_feature.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_get_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_feature.get_config", + ) + self.get_config = self.mock_get_config.start() + + self.mock_get_capabilities = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_feature.get_capabilities", + ) + self.get_capabilities = self.mock_get_capabilities.start() + self.get_capabilities.return_value = { + "device_info": { + "network_os_platform": "DS-C9396T-K9", + "network_os_version": "8.4(2)", + }, + "network_api": "cliconf", + } + + def tearDown(self): + super(TestNxosFeatureModuleMDS, self).tearDown() + self.mock_run_commands.stop() + self.mock_load_config.stop() + self.mock_get_config.stop() + self.mock_get_capabilities.stop() + + def load_fixtures(self, commands=None, device=""): + def load_from_file(*args, **kwargs): + module, commands = args + output = list() + + for item in commands: + try: + obj = json.loads(item["command"]) + command = obj["command"] + except ValueError: + command = item["command"] + filename = "%s_mds.txt" % str(command).replace(" ", "_") + output.append(load_fixture("nxos_feature", filename)) + return output + + self.run_commands.side_effect = load_from_file + self.get_config.return_value = "" + self.load_config.return_value = None + + def test_nxos_feature_enable(self): + set_module_args(dict(feature="fcrxbbcredit", state="enabled")) + result = self.execute_module(changed=True) + self.assertEqual(result["commands"], ["terminal dont-ask", "feature fcrxbbcredit"]) + + def test_nxos_feature_disable(self): + set_module_args(dict(feature="port-track", state="disabled")) + result = self.execute_module(changed=True) + self.assertEqual(result["commands"], ["terminal dont-ask", "no feature port-track"]) + + def test_nxos_feature_enable_already_enabled(self): + set_module_args(dict(feature="analytics", state="enabled")) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_feature_disable_already_disabled(self): + set_module_args(dict(feature="sftp-server", state="disabled")) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_hostname.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_hostname.py new file mode 100644 index 00000000..732f59e7 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_hostname.py @@ -0,0 +1,172 @@ +# (c) 2022 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from textwrap import dedent + +from ansible_collections.cisco.nxos.plugins.modules import nxos_hostname +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, set_module_args + + +ignore_provider_arg = True + + +class TestNxosHostnameModule(TestNxosModule): + module = nxos_hostname + + def setUp(self): + super(TestNxosHostnameModule, self).setUp() + + self.mock_get_resource_connection = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module_base.get_resource_connection", + ) + self.get_resource_connection = self.mock_get_resource_connection.start() + + self.mock_get_config = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.facts.hostname.hostname.HostnameFacts.get_config", + ) + self.get_config = self.mock_get_config.start() + + def tearDown(self): + super(TestNxosHostnameModule, self).tearDown() + self.get_resource_connection.stop() + self.get_config.stop() + + def test_nxos_hostname_merged(self): + # test merged for linear attributes + self.get_config.return_value = dedent( + """\ + """, + ) + set_module_args( + dict(config=dict(hostname="NXOSv-9k"), state="merged"), + ignore_provider_arg, + ) + commands = ["hostname NXOSv-9k"] + result = self.execute_module(changed=True) + self.assertEqual(result["commands"], commands) + + def test_nxos_hostname_linear_merged_idempotent(self): + # test merged for linear attributes (idempotent) + self.get_config.return_value = dedent( + """\ + hostname NXOSv-9k + """, + ) + set_module_args( + dict(config=dict(hostname="NXOSv-9k"), state="merged"), + ignore_provider_arg, + ) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_hostname_linear_merged_2(self): + # test merged for linear attributes - 2 + self.get_config.return_value = dedent( + """\ + hostname NXOSv-9k + """, + ) + set_module_args( + dict(config=dict(hostname="NXOSv"), state="merged"), + ignore_provider_arg, + ) + commands = ["hostname NXOSv"] + result = self.execute_module(changed=True) + self.assertEqual(result["commands"], commands) + + def test_nxos_hostname_linear_replaced(self): + # test replaced for linear attributes + self.get_config.return_value = dedent( + """\ + hostname NXOSv-9k + """, + ) + set_module_args( + dict(config=dict(hostname="NXOSv"), state="replaced"), + ignore_provider_arg, + ) + commands = ["hostname NXOSv"] + result = self.execute_module(changed=True) + self.assertEqual(result["commands"], commands) + + def test_nxos_hostname_linear_overridden(self): + # test replaced for linear attributes + self.get_config.return_value = dedent( + """\ + hostname NXOSv-9k + """, + ) + set_module_args( + dict(config=dict(hostname="NXOSv"), state="overridden"), + ignore_provider_arg, + ) + commands = ["hostname NXOSv"] + result = self.execute_module(changed=True) + self.assertEqual(result["commands"], commands) + + def test_nxos_hostname_deleted(self): + self.get_config.return_value = dedent( + """\ + hostname NXOSv-9k + """, + ) + set_module_args(dict(state="deleted"), ignore_provider_arg) + commands = ["no hostname NXOSv-9k"] + result = self.execute_module(changed=True) + self.assertEqual(result["commands"], commands) + + def test_nxos_hostname_rendered(self): + set_module_args( + dict(config=dict(hostname="NXOSv-9k"), state="rendered"), + ignore_provider_arg, + ) + commands = ["hostname NXOSv-9k"] + result = self.execute_module(changed=False) + self.assertEqual(result["rendered"], commands) + + def test_nxos_hostname_parsed(self): + # test parsed + cfg = dedent( + """\ + hostname NXOSv-9k + """, + ) + set_module_args(dict(running_config=cfg, state="parsed"), ignore_provider_arg) + parsed = {"hostname": "NXOSv-9k"} + result = self.execute_module(changed=False) + self.assertEqual(result["parsed"], parsed) + + def test_nxos_hostname_gathered(self): + # test gathered + self.get_config.return_value = dedent( + """\ + hostname NXOSv-9k + """, + ) + set_module_args(dict(state="gathered"), ignore_provider_arg) + gathered = {"hostname": "NXOSv-9k"} + result = self.execute_module(changed=False) + self.assertEqual(result["gathered"], gathered) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_hsrp.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_hsrp.py new file mode 100644 index 00000000..4ffcc43f --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_hsrp.py @@ -0,0 +1,85 @@ +# (c) 2016 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from ansible_collections.cisco.nxos.plugins.modules import nxos_hsrp +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, set_module_args + + +class TestNxosHsrpModule(TestNxosModule): + module = nxos_hsrp + + def setUp(self): + super(TestNxosHsrpModule, self).setUp() + self.mock_run_commands = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_hsrp.run_commands", + ) + self.run_commands = self.mock_run_commands.start() + + self.mock_load_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_hsrp.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_get_capabilities = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_hsrp.get_capabilities", + ) + self.get_capabilities = self.mock_get_capabilities.start() + self.get_capabilities.return_value = {"network_api": "cliconf"} + + def tearDown(self): + super(TestNxosHsrpModule, self).tearDown() + self.mock_run_commands.stop() + self.mock_load_config.stop() + self.mock_get_capabilities.stop() + + def load_fixtures(self, commands=None, device=""): + self.load_config.return_value = None + + def test_nxos_hsrp(self): + set_module_args( + dict( + group="10", + vip="192.0.2.2/8", + priority="150", + interface="Ethernet1/2", + preempt="enabled", + ), + ) + result = self.execute_module(changed=True) + self.assertEqual( + sorted(result["commands"]), + sorted( + [ + "config t", + "interface ethernet1/2", + "hsrp version 1", + "hsrp 10", + "priority 150", + "ip 192.0.2.2/8", + "preempt", + ], + ), + ) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_hsrp_interfaces.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_hsrp_interfaces.py new file mode 100644 index 00000000..e4f21a82 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_hsrp_interfaces.py @@ -0,0 +1,332 @@ +# (c) 2019 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from textwrap import dedent + +from ansible_collections.cisco.nxos.plugins.modules import nxos_hsrp_interfaces +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, set_module_args + + +ignore_provider_arg = True + + +class TestNxosHsrpInterfacesModule(TestNxosModule): + module = nxos_hsrp_interfaces + + def setUp(self): + super(TestNxosHsrpInterfacesModule, self).setUp() + + self.mock_FACT_LEGACY_SUBSETS = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.facts.facts.FACT_LEGACY_SUBSETS", + ) + self.FACT_LEGACY_SUBSETS = self.mock_FACT_LEGACY_SUBSETS.start() + + self.mock_get_resource_connection_config = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base.get_resource_connection", + ) + self.get_resource_connection_config = self.mock_get_resource_connection_config.start() + + self.mock_get_resource_connection_facts = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection", + ) + self.get_resource_connection_facts = self.mock_get_resource_connection_facts.start() + + self.mock_edit_config = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.config.hsrp_interfaces.hsrp_interfaces.Hsrp_interfaces.edit_config", + ) + self.edit_config = self.mock_edit_config.start() + + def tearDown(self): + super(TestNxosHsrpInterfacesModule, self).tearDown() + self.mock_FACT_LEGACY_SUBSETS.stop() + self.mock_get_resource_connection_config.stop() + self.mock_get_resource_connection_facts.stop() + self.mock_edit_config.stop() + + def load_fixtures(self, commands=None, device=""): + self.mock_FACT_LEGACY_SUBSETS.return_value = dict() + self.get_resource_connection_config.return_value = None + self.edit_config.return_value = None + + # --------------------------- + # Hsrp_interfaces Test Cases + # --------------------------- + + # 'state' logic behaviors + # + # - 'merged' : Update existing device state with any differences in the play. + # - 'deleted' : Reset existing device state to default values. Ignores any + # play attrs other than 'name'. Scope is limited to interfaces + # in the play. + # - 'overridden': The play is the source of truth. Similar to replaced but the + # scope includes all interfaces; ie. it will also reset state + # on interfaces not found in the play. + # - 'replaced' : Scope is limited to the interfaces in the play. + + SHOW_CMD = "show running-config | section ^interface" + + def test_1(self): + # Setup: No HSRP BFD configs shown on device interfaces + existing = dedent( + """\ + interface Ethernet1/1 + interface Ethernet1/2 + interface Ethernet1/3 + """, + ) + self.get_resource_connection_facts.return_value = {self.SHOW_CMD: existing} + playbook = dict( + config=[ + dict(name="Ethernet1/1", bfd="enable"), + dict(name="Ethernet1/2", bfd="disable"), + ], + ) + # Expected result commands for each 'state' + merged = ["interface Ethernet1/1", "hsrp bfd"] + deleted = [] + overridden = merged + replaced = merged + + playbook["state"] = "merged" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=merged) + + playbook["state"] = "deleted" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=False, commands=deleted) + + playbook["state"] = "overridden" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=overridden) + + playbook["state"] = "replaced" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=replaced) + + def test_2(self): + # Change existing HSRP configs + existing = dedent( + """\ + interface Ethernet1/1 + hsrp bfd + interface Ethernet1/2 + hsrp bfd + interface Ethernet1/3 + hsrp bfd + """, + ) + self.get_resource_connection_facts.return_value = {self.SHOW_CMD: existing} + playbook = dict( + config=[ + dict(name="Ethernet1/1", bfd="disable"), + dict(name="Ethernet1/2"), + # Eth1/3 not present! Thus overridden should set Eth1/3 to defaults; + # replaced should ignore Eth1/3. + ], + ) + # Expected result commands for each 'state' + merged = ["interface Ethernet1/1", "no hsrp bfd"] + deleted = [ + "interface Ethernet1/1", + "no hsrp bfd", + "interface Ethernet1/2", + "no hsrp bfd", + ] + overridden = [ + "interface Ethernet1/3", + "no hsrp bfd", + "interface Ethernet1/1", + "no hsrp bfd", + "interface Ethernet1/2", + "no hsrp bfd", + ] + replaced = [ + "interface Ethernet1/1", + "no hsrp bfd", + "interface Ethernet1/2", + "no hsrp bfd", + ] + + playbook["state"] = "merged" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=merged) + + playbook["state"] = "deleted" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=deleted) + + playbook["state"] = "overridden" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=overridden) + + playbook["state"] = "replaced" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=replaced) + + def test_3(self): + # Device has hsrp bfd configs, playbook has no values + existing = dedent( + """\ + interface Ethernet1/1 + hsrp bfd + interface Ethernet1/2 + hsrp bfd + interface Ethernet1/3 + hsrp bfd + """, + ) + self.get_resource_connection_facts.return_value = {self.SHOW_CMD: existing} + playbook = dict(config=[dict(name="Ethernet1/1"), dict(name="Ethernet1/2")]) + # Expected result commands for each 'state' + merged = [] + deleted = [ + "interface Ethernet1/1", + "no hsrp bfd", + "interface Ethernet1/2", + "no hsrp bfd", + ] + overridden = [ + "interface Ethernet1/3", + "no hsrp bfd", + "interface Ethernet1/1", + "no hsrp bfd", + "interface Ethernet1/2", + "no hsrp bfd", + ] + replaced = [ + "interface Ethernet1/1", + "no hsrp bfd", + "interface Ethernet1/2", + "no hsrp bfd", + ] + + playbook["state"] = "merged" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=False, commands=merged) + + playbook["state"] = "deleted" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=deleted) + + playbook["state"] = "overridden" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=overridden) + + playbook["state"] = "replaced" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=replaced) + + def test_4(self): + # Test with interface that doesn't exist yet + existing = dedent( + """\ + interface Ethernet1/1 + hsrp bfd + interface Ethernet1/2 + hsrp bfd + """, + ) + self.get_resource_connection_facts.return_value = {self.SHOW_CMD: existing} + playbook = dict(config=[dict(name="Ethernet1/1.42", bfd="enable")]) + # Expected result commands for each 'state' + merged = ["interface Ethernet1/1.42", "hsrp bfd"] + deleted = [] + overridden = [ + "interface Ethernet1/1.42", + "hsrp bfd", + "interface Ethernet1/1", + "no hsrp bfd", + "interface Ethernet1/2", + "no hsrp bfd", + ] + replaced = ["interface Ethernet1/1.42", "hsrp bfd"] + + playbook["state"] = "merged" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=merged) + + playbook["state"] = "deleted" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=False, commands=deleted) + + playbook["state"] = "overridden" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=overridden) + + playbook["state"] = "replaced" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=replaced) + + def test_5(self): + # idempotence + existing = dedent( + """\ + interface Ethernet1/1 + hsrp bfd + interface Ethernet1/2 + """, + ) + self.get_resource_connection_facts.return_value = {self.SHOW_CMD: existing} + playbook = dict( + config=[ + dict(name="Ethernet1/1", bfd="enable"), + dict(name="Ethernet1/2", bfd="disable"), + ], + ) + # Expected result commands for each 'state' + merged = [] + deleted = ["interface Ethernet1/1", "no hsrp bfd"] + overridden = [] + replaced = [] + + playbook["state"] = "merged" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=False, commands=merged) + + playbook["state"] = "deleted" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=deleted) + + playbook["state"] = "overridden" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=False, commands=overridden) + + playbook["state"] = "replaced" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=False, commands=replaced) + + +def build_args(data, type, state=None, check_mode=None): + if state is None: + state = "merged" + if check_mode is None: + check_mode = False + args = { + "state": state, + "_ansible_check_mode": check_mode, + "config": {type: data}, + } + return args diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_interfaces.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_interfaces.py new file mode 100644 index 00000000..055c441a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_interfaces.py @@ -0,0 +1,735 @@ +# (c) 2019 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from textwrap import dedent + +from ansible_collections.cisco.nxos.plugins.modules import nxos_interfaces +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, set_module_args + + +ignore_provider_arg = True + + +class TestNxosInterfacesModule(TestNxosModule): + module = nxos_interfaces + + def setUp(self): + super(TestNxosInterfacesModule, self).setUp() + + self.mock_FACT_LEGACY_SUBSETS = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.facts.facts.FACT_LEGACY_SUBSETS", + ) + self.FACT_LEGACY_SUBSETS = self.mock_FACT_LEGACY_SUBSETS.start() + + self.mock_get_resource_connection_config = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base.get_resource_connection", + ) + self.get_resource_connection_config = self.mock_get_resource_connection_config.start() + + self.mock_get_resource_connection_facts = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection", + ) + self.get_resource_connection_facts = self.mock_get_resource_connection_facts.start() + + self.mock_edit_config = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.config.interfaces.interfaces.Interfaces.edit_config", + ) + self.edit_config = self.mock_edit_config.start() + + self.mock_get_system_defaults = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.config.interfaces.interfaces.Interfaces.get_system_defaults", + ) + self.get_system_defaults = self.mock_get_system_defaults.start() + + self.mock_get_platform = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.config.interfaces.interfaces.Interfaces.get_platform", + ) + self.get_platform = self.mock_get_platform.start() + + def tearDown(self): + super(TestNxosInterfacesModule, self).tearDown() + self.mock_FACT_LEGACY_SUBSETS.stop() + self.mock_get_resource_connection_config.stop() + self.mock_get_resource_connection_facts.stop() + self.mock_edit_config.stop() + self.mock_get_system_defaults.stop() + self.mock_get_platform.stop() + + def load_fixtures(self, commands=None, device=""): + self.mock_FACT_LEGACY_SUBSETS.return_value = dict() + self.get_resource_connection_config.return_value = None + self.edit_config.return_value = None + if device == "legacy": + # call execute_module() with device='legacy' to use this codepath + self.get_platform.return_value = "N3K-Cxxx" + else: + self.get_platform.return_value = "N9K-Cxxx" + + SHOW_RUN_INTF = "show running-config | section ^interface" + + def test_1(self): + # Overall general test for each state: merged, deleted, overridden, replaced + sysdefs = dedent( + """\ + ! + ! Interfaces default to L3 !! + ! + no system default switchport + no system default switchport shutdown + """, + ) + intf = dedent( + """\ + interface mgmt0 + description do not manage mgmt0! + interface Ethernet1/1 + description foo + interface Ethernet1/2 + description bar + speed 1000 + duplex full + mtu 4096 + ip forward + fabric forwarding mode anycast-gateway + interface Ethernet1/3 + interface Ethernet1/4 + interface Ethernet1/5 + interface Ethernet1/6 + no shutdown + interface loopback0 + description test-loopback + """, + ) + self.get_resource_connection_facts.return_value = {self.SHOW_RUN_INTF: intf} + self.get_system_defaults.return_value = sysdefs + + playbook = dict( + config=[ + dict(name="Ethernet1/1", description="ansible", mode="layer3"), + dict( + name="Ethernet1/2", + speed=10000, + duplex="auto", + mtu=1500, + ip_forward=False, + fabric_forwarding_anycast_gateway=False, + ), + dict(name="Ethernet1/3", description="ansible", mode="layer3"), + dict( + name="Ethernet1/3.101", + description="test-sub-intf", + enabled=False, + ), + dict(name="Ethernet1/4", mode="layer2"), + dict(name="Ethernet1/5"), + dict(name="loopback1", description="test-loopback"), + ], + ) + merged = [ + # Update existing device states with any differences in the playbook. + "interface Ethernet1/1", + "description ansible", + "interface Ethernet1/2", + "speed 10000", + "duplex auto", + "mtu 1500", + "no ip forward", + "no fabric forwarding mode anycast-gateway", + "interface Ethernet1/3", + "description ansible", + "interface Ethernet1/3.101", + "description test-sub-intf", + "interface Ethernet1/4", + "switchport", + "interface loopback1", + "description test-loopback", + ] + playbook["state"] = "merged" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=merged) + + deleted = [ + # Reset existing device state to default values. Scope is limited to + # objects in the play. Ignores any play attrs other than 'name'. + "interface Ethernet1/1", + "no description", + "interface Ethernet1/2", + "no description", + "no speed", + "no duplex", + "no mtu", + "no ip forward", + "no fabric forwarding mode anycast-gateway", + ] + playbook["state"] = "deleted" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=deleted) + + replaced = [ + # Scope is limited to objects in the play. The play is the source of + # truth for the objects that are explicitly listed. + "interface Ethernet1/1", + "description ansible", + "interface Ethernet1/2", + "no description", + "no ip forward", + "no fabric forwarding mode anycast-gateway", + "speed 10000", + "duplex auto", + "mtu 1500", + "interface Ethernet1/3", + "description ansible", + "interface Ethernet1/3.101", + "description test-sub-intf", + "interface Ethernet1/4", + "switchport", + "interface loopback1", + "description test-loopback", + ] + playbook["state"] = "replaced" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=replaced) + + overridden = [ + # The play is the source of truth. Similar to replaced but the scope + # includes all objects on the device; i.e. it will also reset state + # on objects not found in the play. + "interface Ethernet1/1", + "description ansible", + "interface Ethernet1/2", + "no description", + "no ip forward", + "no fabric forwarding mode anycast-gateway", + "speed 10000", + "duplex auto", + "mtu 1500", + "interface Ethernet1/6", + "shutdown", + "interface loopback0", + "no description", + "interface Ethernet1/3", + "description ansible", + "interface Ethernet1/4", + "switchport", + "interface Ethernet1/3.101", + "description test-sub-intf", + "interface loopback1", + "description test-loopback", + "interface mgmt0", + "no description", + ] + playbook["state"] = "overridden" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=overridden) + + def test_2(self): + # 'enabled'/shutdown behaviors are tricky: + # - different default states for different interface types for different + # platforms, based on 'system default switchport' settings + # - virtual interfaces may not exist yet + # - idempotence for interfaces with all default states + sysdefs = dedent( + """\ + ! + ! Interfaces default to L3 !! + ! + no system default switchport + no system default switchport shutdown + """, + ) + intf = dedent( + """\ + interface mgmt0 + interface Ethernet1/1 + interface Ethernet1/2 + switchport + shutdown + interface Ethernet1/3 + switchport + interface loopback1 + interface loopback2 + shutdown + interface loopback3 + interface loopback8 + interface loopback9 + shutdown + interface port-channel2 + interface port-channel3 + shutdown + """, + ) + self.get_resource_connection_facts.return_value = {self.SHOW_RUN_INTF: intf} + self.get_system_defaults.return_value = sysdefs + + playbook = dict( + config=[ + # Set non-default states on existing objs + dict(name="Ethernet1/1", mode="layer3", enabled=True), + dict(name="loopback1", enabled=False), + # Set default states on existing objs + dict(name="Ethernet1/2", enabled=True), + dict(name="loopback2", enabled=True), + # Set explicit default state on existing objs (no chg) + dict(name="Ethernet1/3", enabled=True), + dict(name="loopback3", enabled=True), + dict(name="port-channel3", enabled=True), + dict(name="loopback4", enabled=True), + dict(name="port-channel4", enabled=True), + dict(name="Ethernet1/4.101"), + ], + ) + # Testing with newer code version + merged = [ + "interface Ethernet1/1", + "no shutdown", + "interface loopback1", + "shutdown", + "interface Ethernet1/2", + "no shutdown", + "interface loopback2", + "no shutdown", + "interface port-channel3", + "no shutdown", + "interface loopback4", + "no shutdown", + "interface port-channel4", + "no shutdown", + "interface Ethernet1/4.101", + ] + playbook["state"] = "merged" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=merged) + + deleted = [ + # e1/2 becomes L3 so enable default changes to false + "interface Ethernet1/2", + "no switchport", + "interface loopback2", + "no shutdown", + "interface Ethernet1/3", + "no switchport", + "interface port-channel3", + "no shutdown", + ] + playbook["state"] = "deleted" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=deleted) + + replaced = [ + "interface Ethernet1/1", + "no shutdown", + "interface loopback1", + "shutdown", + "interface Ethernet1/2", + "no switchport", + "no shutdown", + "interface loopback2", + "no shutdown", + "interface Ethernet1/3", + "no switchport", + "no shutdown", + "interface port-channel3", + "no shutdown", + "interface loopback4", + "no shutdown", + "interface port-channel4", + "no shutdown", + "interface Ethernet1/4.101", + ] + playbook["state"] = "replaced" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=replaced) + + overridden = [ + "interface Ethernet1/2", + "no switchport", + "no shutdown", + "interface Ethernet1/3", + "no switchport", + "no shutdown", + "interface loopback2", + "no shutdown", + "interface loopback9", + "no shutdown", + "interface port-channel3", + "no shutdown", + "interface Ethernet1/1", + "no shutdown", + "interface loopback1", + "shutdown", + "interface loopback4", + "no shutdown", + "interface port-channel4", + "no shutdown", + "interface Ethernet1/4.101", + ] + playbook["state"] = "overridden" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=overridden) + + def test_3(self): + # Testing 'enabled' with different 'system default' settings. + # This is the same as test_2 with some minor changes. + sysdefs = dedent( + """\ + ! + ! Interfaces default to L2 !! + ! + system default switchport + system default switchport shutdown + """, + ) + intf = dedent( + """\ + interface mgmt0 + interface Ethernet1/1 + interface Ethernet1/2 + no switchport + no shutdown + interface Ethernet1/3 + no switchport + interface loopback1 + interface loopback2 + shutdown + interface loopback3 + interface loopback8 + interface loopback9 + shutdown + interface port-channel2 + interface port-channel3 + shutdown + """, + ) + self.get_resource_connection_facts.return_value = {self.SHOW_RUN_INTF: intf} + self.get_system_defaults.return_value = sysdefs + + playbook = dict( + config=[ + # Set non-default states on existing objs + dict(name="Ethernet1/1", mode="layer3", enabled=True), + dict(name="loopback1", enabled=False), + # Set default states on existing objs + dict(name="Ethernet1/2", enabled=False), + dict(name="loopback2", enabled=True), + # Set explicit default state on existing objs (no chg) + dict(name="Ethernet1/3", enabled=False), + dict(name="loopback3", enabled=True), + dict(name="port-channel3", enabled=True), + # Set default state on non-existent objs; no state changes but need to create intf + dict(name="loopback4", enabled=True), + dict(name="port-channel4", enabled=True), + dict(name="Ethernet1/4.101"), + ], + ) + merged = [ + "interface Ethernet1/1", + "no switchport", + "no shutdown", + "interface loopback1", + "shutdown", + "interface Ethernet1/2", + "shutdown", + "interface loopback2", + "no shutdown", + "interface port-channel3", + "no shutdown", + "interface loopback4", + "no shutdown", + "interface port-channel4", + "no shutdown", + "interface Ethernet1/4.101", + ] + playbook["state"] = "merged" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=merged) + + # Test with an older image version which has different defaults + merged_legacy = [ + "interface Ethernet1/1", + "no switchport", + "interface loopback1", + "shutdown", + "interface Ethernet1/2", + "shutdown", + "interface loopback2", + "no shutdown", + "interface Ethernet1/3", + "shutdown", + "interface port-channel3", + "no shutdown", + "interface loopback4", + "no shutdown", + "interface port-channel4", + "no shutdown", + "interface Ethernet1/4.101", + ] + self.execute_module(changed=True, commands=merged_legacy, device="legacy") + + deleted = [ + "interface Ethernet1/2", + "switchport", + "shutdown", + "interface loopback2", + "no shutdown", + "interface Ethernet1/3", + "switchport", + "interface port-channel3", + "no shutdown", + ] + playbook["state"] = "deleted" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=deleted) + + replaced = [ + "interface Ethernet1/1", + "no switchport", + "no shutdown", + "interface loopback1", + "shutdown", + "interface Ethernet1/2", + "switchport", + "shutdown", + "interface loopback2", + "no shutdown", + "interface Ethernet1/3", + "switchport", + "interface port-channel3", + "no shutdown", + "interface loopback4", + "no shutdown", + "interface port-channel4", + "no shutdown", + "interface Ethernet1/4.101", + ] + playbook["state"] = "replaced" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=replaced) + + playbook = dict( + config=[ + # Set non-default states on existing objs + dict(name="Ethernet1/1", mode="layer3", enabled=True), + dict(name="loopback1", enabled=False), + # Set default states on existing objs + dict(name="Ethernet1/2", enabled=False), + dict(name="loopback2", enabled=True), + # Set explicit default state on existing objs (no chg) + dict(name="Ethernet1/3", enabled=False), + dict(name="loopback3", enabled=True), + dict(name="port-channel3", enabled=True), + # Set default state on non-existent objs; no state changes but need to create intf + dict(name="loopback4", enabled=True), + dict(name="port-channel4", enabled=True), + dict(name="Ethernet1/4.101", enabled=False), + dict(name="Ethernet1/4.102", enabled=True), + ], + ) + + overridden = [ + "interface Ethernet1/2", + "switchport", + "shutdown", + "interface Ethernet1/3", + "switchport", + "interface loopback2", + "no shutdown", + "interface loopback9", + "no shutdown", + "interface port-channel3", + "no shutdown", + "interface Ethernet1/1", + "no switchport", + "no shutdown", + "interface loopback1", + "shutdown", + "interface loopback4", + "no shutdown", + "interface port-channel4", + "no shutdown", + "interface Ethernet1/4.101", + "interface Ethernet1/4.102", + "no shutdown", + ] + playbook["state"] = "overridden" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=overridden) + + def test_4(self): + # Basic idempotence test + sysdefs = dedent( + """\ + ! + ! Interfaces default to L3 !! + ! + no system default switchport + no system default switchport shutdown + """, + ) + intf = dedent( + """\ + interface Ethernet1/1 + interface Ethernet1/2 + switchport + speed 1000 + shutdown + """, + ) + self.get_resource_connection_facts.return_value = {self.SHOW_RUN_INTF: intf} + self.get_system_defaults.return_value = sysdefs + + playbook = dict( + config=[ + dict(name="Ethernet1/1", mode="layer3"), + dict(name="Ethernet1/2", mode="layer2", enabled=False), + ], + ) + merged = [] + playbook["state"] = "merged" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=False, commands=merged) + + def test_5(self): + # 'state: deleted' without 'config'; clean all objects. + sysdefs = dedent( + """\ + ! + ! Interfaces default to L3 !! + ! + no system default switchport + no system default switchport shutdown + """, + ) + intf = dedent( + """\ + interface Ethernet1/1 + switchport + interface Ethernet1/2 + speed 1000 + no shutdown + """, + ) + self.get_resource_connection_facts.return_value = {self.SHOW_RUN_INTF: intf} + self.get_system_defaults.return_value = sysdefs + + playbook = dict() + deleted = [ + "interface Ethernet1/1", + "no switchport", + "interface Ethernet1/2", + "no speed", + "shutdown", + ] + playbook["state"] = "deleted" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=deleted) + + def test_6_gathered(self): + # check for parsing correct contexts + sysdefs = dedent( + """\ + ! + ! Interfaces default to L3 !! + ! + no system default switchport + no system default switchport shutdown + """, + ) + intf = dedent( + """\ + interface nve1 + no shutdown + source-interface loopback1 + interface Ethernet1/1 + switchport + description interface + interface Ethernet1/2 + speed 1000 + no shutdown + interface loopback1 + """, + ) + self.get_resource_connection_facts.return_value = {self.SHOW_RUN_INTF: intf} + self.get_system_defaults.return_value = sysdefs + + playbook = dict() + playbook["state"] = "gathered" + + gathered_facts = [ + {"name": "nve1", "enabled": True}, + { + "name": "Ethernet1/1", + "mode": "layer2", + "description": "interface", + }, + {"name": "Ethernet1/2", "enabled": True, "speed": "1000"}, + {"name": "loopback1"}, + ] + set_module_args(playbook, ignore_provider_arg) + result = self.execute_module(changed=False) + self.assertEqual(result["gathered"], gathered_facts) + + def test_7_purged(self): + # check for parsing correct contexts + sysdefs = dedent( + """\ + no system default switchport + no system default switchport shutdown + """, + ) + intf = dedent( + """\ + interface Vlan1 + interface Vlan42 + mtu 1800 + interface port-channel10 + interface port-channel11 + interface Ethernet1/1 + interface Ethernet1/2 + interface Ethernet1/2.100 + description sub-intf + """, + ) + self.get_resource_connection_facts.return_value = {self.SHOW_RUN_INTF: intf} + self.get_system_defaults.return_value = sysdefs + + playbook = dict( + config=[ + dict(name="Vlan42"), + dict(name="port-channel10"), + dict(name="Ethernet1/2.100"), + ], + ) + playbook["state"] = "purged" + + commands = [ + "no interface port-channel10", + "no interface Ethernet1/2.100", + "no interface Vlan42", + ] + + set_module_args(playbook, ignore_provider_arg) + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_l3_interfaces.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_l3_interfaces.py new file mode 100644 index 00000000..b0ac68f4 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_l3_interfaces.py @@ -0,0 +1,1023 @@ +# (c) 2019 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from textwrap import dedent + +from ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.config.l3_interfaces.l3_interfaces import ( + L3_interfaces, +) +from ansible_collections.cisco.nxos.plugins.modules import nxos_l3_interfaces +from ansible_collections.cisco.nxos.tests.unit.compat.mock import PropertyMock, patch + +from .nxos_module import TestNxosModule, set_module_args + + +ignore_provider_arg = True + + +class TestNxosL3InterfacesModule(TestNxosModule): + module = nxos_l3_interfaces + + def setUp(self): + super(TestNxosL3InterfacesModule, self).setUp() + + self.mock_FACT_LEGACY_SUBSETS = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.facts.facts.FACT_LEGACY_SUBSETS", + ) + self.FACT_LEGACY_SUBSETS = self.mock_FACT_LEGACY_SUBSETS.start() + + self.mock_get_resource_connection_config = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base.get_resource_connection", + ) + self.get_resource_connection_config = self.mock_get_resource_connection_config.start() + + self.mock_get_resource_connection_facts = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection", + ) + self.get_resource_connection_facts = self.mock_get_resource_connection_facts.start() + + self.mock_edit_config = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.config.l3_interfaces.l3_interfaces.L3_interfaces.edit_config", + ) + self.edit_config = self.mock_edit_config.start() + + def tearDown(self): + super(TestNxosL3InterfacesModule, self).tearDown() + self.mock_FACT_LEGACY_SUBSETS.stop() + self.mock_get_resource_connection_config.stop() + self.mock_get_resource_connection_facts.stop() + self.mock_edit_config.stop() + + def load_fixtures(self, commands=None, device="N9K"): + self.mock_FACT_LEGACY_SUBSETS.return_value = dict() + self.get_resource_connection_config.return_value = None + self.edit_config.return_value = None + L3_interfaces.platform = PropertyMock(return_value=device) + + # --------------------------- + # L3_interfaces Test Cases + # --------------------------- + + # 'state' logic behaviors + # + # - 'merged' : Update existing device state with any differences in the play. + # - 'deleted' : Reset existing device state to default values. Ignores any + # play attrs other than 'name'. Scope is limited to interfaces + # in the play. + # - 'overridden': The play is the source of truth. Similar to replaced but the + # scope includes all interfaces; ie. it will also reset state + # on interfaces not found in the play. + # - 'replaced' : Scope is limited to the interfaces in the play. + + SHOW_CMD = "show running-config | section ^interface" + + def test_2(self): + # basic tests + existing = dedent( + """\ + interface mgmt0 + ip address 10.0.0.254/24 + interface Ethernet1/1 + ip address 10.1.1.1/24 + interface Ethernet1/2 + ip address 10.1.2.1/24 + interface Ethernet1/3 + ip address 10.1.3.1/24 + interface port-channel336 + interface port-channel337 + no ipv6 redirects + """, + ) + self.get_resource_connection_facts.return_value = {self.SHOW_CMD: existing} + playbook = dict( + config=[ + dict(name="mgmt0", ipv4=[{"address": "10.0.0.254/24"}]), + dict(name="Ethernet1/1", ipv4=[{"address": "192.168.1.1/24"}]), + dict(name="Ethernet1/2"), + dict(name="port-channel355", ipv6_redirects=False), + dict(name="port-channel336", ipv6_redirects=False, ipv6=[{"address": "10::5/128"}]), + # Eth1/3 not present! Thus overridden should set Eth1/3 to defaults; + # replaced should ignore Eth1/3. + ], + ) + # Expected result commands for each 'state' + merged = [ + "interface Ethernet1/1", + "ip address 192.168.1.1/24", + "interface port-channel355", + "no ipv6 redirects", + "interface port-channel336", + "ipv6 address 10::5/128", + "no ipv6 redirects", + ] + deleted = [ + "interface mgmt0", + "no ip address", + "interface Ethernet1/1", + "no ip address", + "interface Ethernet1/2", + "no ip address", + ] + replaced = [ + "interface Ethernet1/1", + "ip address 192.168.1.1/24", + "interface Ethernet1/2", + "no ip address", + "interface port-channel355", + "no ipv6 redirects", + "interface port-channel336", + "ipv6 address 10::5/128", + "no ipv6 redirects", + ] + overridden = [ + "interface Ethernet1/1", + "ip address 192.168.1.1/24", + "interface Ethernet1/2", + "no ip address", + "interface Ethernet1/3", + "no ip address", + "interface port-channel355", + "no ipv6 redirects", + "interface port-channel336", + "ipv6 address 10::5/128", + "no ipv6 redirects", + "interface port-channel337", + "ipv6 redirects", + ] + + playbook["state"] = "merged" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=merged) + + playbook["state"] = "deleted" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=deleted) + + playbook["state"] = "replaced" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=replaced) + + playbook["state"] = "overridden" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=overridden) + + def test_3(self): + # encap testing + existing = dedent( + """\ + interface mgmt0 + ip address 10.0.0.254/24 + interface Ethernet1/1.41 + encapsulation dot1q 4100 + ip address 10.1.1.1/24 + interface Ethernet1/1.42 + encapsulation dot1q 42 + interface Ethernet1/1.44 + encapsulation dot1q 44 + interface Ethernet1/1.45 + encapsulation dot1q 45 + ip address 10.5.5.5/24 + ipv6 address 10::5/128 + """, + ) + self.get_resource_connection_facts.return_value = {self.SHOW_CMD: existing} + playbook = dict( + config=[ + dict(name="mgmt0", ipv4=[{"address": "10.0.0.254/24"}]), + dict( + name="Ethernet1/1.41", + dot1q=41, + ipv4=[{"address": "10.2.2.2/24"}], + ), + dict(name="Ethernet1/1.42", dot1q=42), + dict( + name="Ethernet1/1.43", + dot1q=43, + ipv6=[{"address": "10::2/128"}], + ), + dict(name="Ethernet1/1.44"), + ], + ) + # Expected result commands for each 'state' + merged = [ + "interface Ethernet1/1.41", + "encapsulation dot1q 41", + "ip address 10.2.2.2/24", + "interface Ethernet1/1.43", + "encapsulation dot1q 43", + "ipv6 address 10::2/128", + ] + deleted = [ + "interface mgmt0", + "no ip address", + "interface Ethernet1/1.41", + "no encapsulation dot1q", + "no ip address", + "interface Ethernet1/1.42", + "no encapsulation dot1q", + "interface Ethernet1/1.44", + "no encapsulation dot1q", + ] + replaced = [ + "interface Ethernet1/1.41", + "encapsulation dot1q 41", + "ip address 10.2.2.2/24", + # 42 no chg + "interface Ethernet1/1.43", + "encapsulation dot1q 43", + "ipv6 address 10::2/128", + "interface Ethernet1/1.44", + "no encapsulation dot1q", + ] + overridden = [ + "interface Ethernet1/1.41", + "encapsulation dot1q 41", + "ip address 10.2.2.2/24", + # 42 no chg + "interface Ethernet1/1.44", + "no encapsulation dot1q", + "interface Ethernet1/1.45", + "no encapsulation dot1q", + "no ip address", + "no ipv6 address", + "interface Ethernet1/1.43", + "encapsulation dot1q 43", + "ipv6 address 10::2/128", + ] + + playbook["state"] = "merged" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=merged) + + playbook["state"] = "deleted" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=deleted) + + playbook["state"] = "replaced" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=replaced) + + playbook["state"] = "overridden" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=overridden) + + def test_4(self): + # IPv4-centric testing + existing = dedent( + """\ + interface mgmt0 + ip address 10.0.0.254/24 + interface Ethernet1/1 + no ip redirects + ip address 10.1.1.1/24 tag 11 + ip address 10.2.2.2/24 secondary tag 12 + ip address 10.3.3.3/24 secondary + ip address 10.4.4.4/24 secondary tag 14 + ip address 10.5.5.5/24 secondary tag 15 + ip address 10.6.6.6/24 secondary tag 16 + interface Ethernet1/2 + ip address 10.12.12.12/24 + interface Ethernet1/3 + ip address 10.13.13.13/24 + interface Ethernet1/5 + no ip redirects + ip address 10.15.15.15/24 + ip address 10.25.25.25/24 secondary + """, + ) + self.get_resource_connection_facts.return_value = {self.SHOW_CMD: existing} + playbook = dict( + config=[ + dict(name="mgmt0", ipv4=[{"address": "10.0.0.254/24"}]), + dict( + name="Ethernet1/1", + ipv4=[ + { + "address": "10.1.1.1/24", + "secondary": True, + }, # prim->sec + { + "address": "10.2.2.2/24", + "secondary": True, + }, # rmv tag + {"address": "10.3.3.3/24", "tag": 3}, # become prim + { + "address": "10.4.4.4/24", + "secondary": True, + "tag": 14, + }, # no chg + { + "address": "10.5.5.5/24", + "secondary": True, + "tag": 55, + }, # chg tag + { + "address": "10.7.7.7/24", + "secondary": True, + "tag": 77, + }, + ], + ), # new ip + dict(name="Ethernet1/2"), + dict( + name="Ethernet1/4", + ipv4=[ + {"address": "10.40.40.40/24"}, + {"address": "10.41.41.41/24", "secondary": True}, + ], + ), + dict(name="Ethernet1/5"), + ], + ) + # Expected result commands for each 'state' + merged = [ + "interface Ethernet1/1", + "no ip address 10.5.5.5/24 secondary", + "no ip address 10.2.2.2/24 secondary", + "no ip address 10.3.3.3/24 secondary", + "ip address 10.3.3.3/24 tag 3", # Changes primary + "ip address 10.1.1.1/24 secondary", + "ip address 10.2.2.2/24 secondary", + "ip address 10.7.7.7/24 secondary tag 77", + "ip address 10.5.5.5/24 secondary tag 55", + "interface Ethernet1/4", + "ip address 10.40.40.40/24", + "ip address 10.41.41.41/24 secondary", + ] + deleted = [ + "interface mgmt0", + "no ip address", + "interface Ethernet1/1", + "no ip address", + "interface Ethernet1/2", + "no ip address", + "interface Ethernet1/5", + "no ip address", + ] + replaced = [ + "interface Ethernet1/1", + "no ip address 10.5.5.5/24 secondary", + "no ip address 10.2.2.2/24 secondary", + "no ip address 10.3.3.3/24 secondary", + "ip address 10.3.3.3/24 tag 3", # Changes primary + "ip address 10.1.1.1/24 secondary", + "ip address 10.2.2.2/24 secondary", + "ip address 10.7.7.7/24 secondary tag 77", + "ip address 10.5.5.5/24 secondary tag 55", + "interface Ethernet1/2", + "no ip address", + "interface Ethernet1/4", + "ip address 10.40.40.40/24", + "ip address 10.41.41.41/24 secondary", + "interface Ethernet1/5", + "no ip address", + ] + overridden = [ + "interface Ethernet1/1", + "no ip address 10.6.6.6/24 secondary", + "no ip address 10.5.5.5/24 secondary", + "no ip address 10.2.2.2/24 secondary", + "no ip address 10.3.3.3/24 secondary", + "ip address 10.3.3.3/24 tag 3", # Changes primary + "ip address 10.1.1.1/24 secondary", + "ip address 10.2.2.2/24 secondary", + "ip address 10.7.7.7/24 secondary tag 77", + "ip address 10.5.5.5/24 secondary tag 55", + "interface Ethernet1/2", + "no ip address", + "interface Ethernet1/3", + "no ip address", + "interface Ethernet1/4", + "ip address 10.40.40.40/24", + "ip address 10.41.41.41/24 secondary", + "interface Ethernet1/5", + "no ip address", + ] + + playbook["state"] = "merged" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=merged) + + playbook["state"] = "deleted" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=deleted) + + playbook["state"] = "replaced" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=replaced) + + playbook["state"] = "overridden" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=overridden) + + def test_5(self): + # IPv6-centric testing + existing = dedent( + """\ + interface Ethernet1/1 + ipv6 address 10::1/128 + ipv6 address 10::2/128 tag 12 + ipv6 address 10::3/128 tag 13 + ipv6 address 10::4/128 tag 14 + interface Ethernet1/2 + ipv6 address 10::12/128 + interface Ethernet1/3 + ipv6 address 10::13/128 + """, + ) + self.get_resource_connection_facts.return_value = {self.SHOW_CMD: existing} + playbook = dict( + config=[ + dict( + name="Ethernet1/1", + ipv6=[ + {"address": "10::1/128"}, # no chg + {"address": "10::3/128"}, # tag rmv + {"address": "10::4/128", "tag": 44}, # tag chg + {"address": "10::5/128"}, # new addr + {"address": "10::6/128", "tag": 66}, + ], + ), # new addr+tag + dict(name="Ethernet1/2"), + ], + ) + # Expected result commands for each 'state' + merged = [ + "interface Ethernet1/1", + "ipv6 address 10::4/128 tag 44", + "ipv6 address 10::5/128", + "ipv6 address 10::6/128 tag 66", + ] + deleted = [ + "interface Ethernet1/1", + "no ipv6 address", + "interface Ethernet1/2", + "no ipv6 address", + ] + replaced = [ + "interface Ethernet1/1", + "no ipv6 address 10::3/128", + "no ipv6 address 10::2/128", + "ipv6 address 10::4/128 tag 44", + "ipv6 address 10::3/128", + "ipv6 address 10::5/128", + "ipv6 address 10::6/128 tag 66", + "interface Ethernet1/2", + "no ipv6 address 10::12/128", + ] + overridden = [ + "interface Ethernet1/1", + "no ipv6 address 10::3/128", + "no ipv6 address 10::2/128", + "ipv6 address 10::4/128 tag 44", + "ipv6 address 10::3/128", + "ipv6 address 10::5/128", + "ipv6 address 10::6/128 tag 66", + "interface Ethernet1/2", + "no ipv6 address 10::12/128", + "interface Ethernet1/3", + "no ipv6 address", + ] + + playbook["state"] = "merged" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=merged) + + playbook["state"] = "deleted" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=deleted) + # + playbook["state"] = "replaced" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=replaced) + # + playbook["state"] = "overridden" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=overridden) + + def test_6(self): + # misc tests + existing = dedent( + """\ + interface Ethernet1/1 + ip address 10.1.1.1/24 + no ip redirects + ip unreachables + interface Ethernet1/2 + interface Ethernet1/3 + interface Ethernet1/4 + interface Ethernet1/5 + no ip redirects + """, + ) + self.get_resource_connection_facts.return_value = {self.SHOW_CMD: existing} + playbook = dict( + config=[ + dict( + name="Ethernet1/1", + redirects=True, + unreachables=False, + ipv4=[{"address": "192.168.1.1/24"}], + ), + dict(name="Ethernet1/2"), + dict(name="Ethernet1/3", redirects=True, unreachables=False), # defaults + dict(name="Ethernet1/4", redirects=False, unreachables=True), + ], + ) + merged = [ + "interface Ethernet1/1", + "ip redirects", + "no ip unreachables", + "ip address 192.168.1.1/24", + "interface Ethernet1/4", + "no ip redirects", + "ip unreachables", + ] + deleted = [ + "interface Ethernet1/1", + "ip redirects", + "no ip unreachables", + "no ip address", + ] + replaced = [ + "interface Ethernet1/1", + "ip redirects", + "no ip unreachables", + "ip address 192.168.1.1/24", + "interface Ethernet1/4", + "no ip redirects", + "ip unreachables", + ] + overridden = [ + "interface Ethernet1/1", + "ip redirects", + "no ip unreachables", + "ip address 192.168.1.1/24", + "interface Ethernet1/5", + "ip redirects", + "interface Ethernet1/4", + "no ip redirects", + "ip unreachables", + ] + + playbook["state"] = "merged" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=merged) + + playbook["state"] = "deleted" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=deleted) + + playbook["state"] = "replaced" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=replaced) + + playbook["state"] = "overridden" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=overridden) + + def test_7(self): + # idempotence + existing = dedent( + """\ + interface Ethernet1/1 + ip address 10.1.1.1/24 + ip address 10.2.2.2/24 secondary tag 2 + ip address 10.3.3.3/24 secondary tag 3 + ip address 10.4.4.4/24 secondary + ipv6 address 10::1/128 + ipv6 address 10::2/128 tag 2 + no ip redirects + ip unreachables + interface Ethernet1/2 + """, + ) + self.get_resource_connection_facts.return_value = {self.SHOW_CMD: existing} + playbook = dict( + config=[ + dict( + name="Ethernet1/1", + redirects=False, + unreachables=True, + ipv4=[ + {"address": "10.1.1.1/24"}, + { + "address": "10.2.2.2/24", + "secondary": True, + "tag": 2, + }, + { + "address": "10.3.3.3/24", + "secondary": True, + "tag": 3, + }, + {"address": "10.4.4.4/24", "secondary": True}, + ], + ipv6=[ + {"address": "10::1/128"}, + {"address": "10::2/128", "tag": 2}, + ], + ), + dict(name="Ethernet1/2"), + ], + ) + playbook["state"] = "merged" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=False) + + playbook["state"] = "replaced" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=False) + + playbook["state"] = "overridden" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=False) + + # Modify output for deleted idempotence test + existing = dedent( + """\ + interface Ethernet1/1 + interface Ethernet1/2 + """, + ) + self.get_resource_connection_facts.return_value = {self.SHOW_CMD: existing} + playbook["state"] = "deleted" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=False) + + def test_8(self): + # no 'config' key in playbook + existing = dedent( + """\ + interface Ethernet1/1 + ip address 10.1.1.1/24 + """, + ) + self.get_resource_connection_facts.return_value = {self.SHOW_CMD: existing} + playbook = dict() + + for i in ["merged", "replaced", "overridden"]: + playbook["state"] = i + set_module_args(playbook, ignore_provider_arg) + self.execute_module(failed=True) + + deleted = ["interface Ethernet1/1", "no ip address"] + playbook["state"] = "deleted" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=deleted) + + def test_9(self): + # Platform specific checks + # 'ip redirects' has platform-specific behaviors + existing = dedent( + """\ + interface Ethernet1/3 + ip address 10.13.13.13/24 + interface Ethernet1/5 + no ip redirects + ip address 10.15.15.15/24 + ip address 10.25.25.25/24 secondary + """, + ) + self.get_resource_connection_facts.return_value = {self.SHOW_CMD: existing} + playbook = dict(config=[dict(name="Ethernet1/3"), dict(name="Ethernet1/5")]) + # Expected result commands for each 'state' + deleted = [ + "interface Ethernet1/3", + "no ip address", + "interface Ethernet1/5", + "no ip address", + "ip redirects", + ] + replaced = [ + "interface Ethernet1/3", + "no ip address", + "interface Ethernet1/5", + "no ip address", + "ip redirects", + ] + overridden = [ + "interface Ethernet1/3", + "no ip address", + "interface Ethernet1/5", + "no ip address", + "ip redirects", + ] + platform = "N3K" + + playbook["state"] = "merged" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=False, device=platform) + + playbook["state"] = "deleted" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=deleted, device=platform) + + playbook["state"] = "replaced" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=replaced, device=platform) + + playbook["state"] = "overridden" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=overridden, device=platform) + + def test_10(self): + # basic tests + existing = dedent( + """\ + interface mgmt0 + ip address 10.0.0.254/24 + interface Ethernet1/1 + ip address 10.1.1.1/24 + interface Ethernet1/2 + ip address 10.1.2.1/24 + evpn multisite fabric-tracking + interface Ethernet1/3 + ip address 10.1.3.1/24 + evpn multisite dci-tracking + """, + ) + self.get_resource_connection_facts.return_value = {self.SHOW_CMD: existing} + playbook = dict( + config=[ + dict(name="mgmt0", ipv4=[{"address": "10.0.0.254/24"}]), + dict(name="Ethernet1/1", ipv4=[{"address": "192.168.1.1/24"}]), + dict(name="Ethernet1/2"), + # Eth1/3 not present! Thus overridden should set Eth1/3 to defaults; + # replaced should ignore Eth1/3. + ], + ) + # Expected result commands for each 'state' + merged = ["interface Ethernet1/1", "ip address 192.168.1.1/24"] + deleted = [ + "interface mgmt0", + "no ip address", + "interface Ethernet1/1", + "no ip address", + "interface Ethernet1/2", + "no ip address", + "no evpn multisite fabric-tracking", + ] + replaced = [ + "interface Ethernet1/1", + "ip address 192.168.1.1/24", + "interface Ethernet1/2", + "no ip address", + "no evpn multisite fabric-tracking", + ] + overridden = [ + "interface Ethernet1/1", + "ip address 192.168.1.1/24", + "interface Ethernet1/2", + "no ip address", + "no evpn multisite fabric-tracking", + "interface Ethernet1/3", + "no ip address", + "no evpn multisite dci-tracking", + ] + + playbook["state"] = "merged" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=merged) + + playbook["state"] = "deleted" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=deleted) + + playbook["state"] = "replaced" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=replaced) + + playbook["state"] = "overridden" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=overridden) + + def test_11(self): + # IPv4-centric testing + existing = dedent( + """\ + interface mgmt0 + ip address 10.0.0.254/24 + interface Ethernet1/1 + no ip redirects + ip address 10.1.1.1/24 tag 11 + ip address 10.2.2.2/24 secondary tag 12 + ip address 10.3.3.3/24 secondary + ip address 10.4.4.4/24 secondary tag 14 + ip address 10.5.5.5/24 secondary tag 15 + ip address 10.6.6.6/24 secondary tag 16 + interface Ethernet1/2 + ip address 10.12.12.12/24 + interface Ethernet1/3 + ip address 10.13.13.13/24 + interface Ethernet1/5 + no ip redirects + ip address 10.15.15.15/24 + ip address 10.25.25.25/24 secondary + evpn multisite fabric-tracking + """, + ) + self.get_resource_connection_facts.return_value = {self.SHOW_CMD: existing} + playbook = dict( + config=[ + dict(name="mgmt0", ipv4=[{"address": "10.0.0.254/24"}]), + dict( + name="Ethernet1/1", + ipv4=[ + { + "address": "10.1.1.1/24", + "secondary": True, + }, # prim->sec + { + "address": "10.2.2.2/24", + "secondary": True, + }, # rmv tag + {"address": "10.3.3.3/24", "tag": 3}, # become prim + { + "address": "10.4.4.4/24", + "secondary": True, + "tag": 14, + }, # no chg + { + "address": "10.5.5.5/24", + "secondary": True, + "tag": 55, + }, # chg tag + { + "address": "10.7.7.7/24", + "secondary": True, + "tag": 77, + }, + ], + ), # new ip + dict(name="Ethernet1/2"), + dict( + name="Ethernet1/4", + ipv4=[ + {"address": "10.40.40.40/24"}, + {"address": "10.41.41.41/24", "secondary": True}, + ], + evpn_multisite_tracking="dci-tracking", + ), + dict(name="Ethernet1/5"), + ], + ) + # Expected result commands for each 'state' + merged = [ + "interface Ethernet1/1", + "no ip address 10.5.5.5/24 secondary", + "no ip address 10.2.2.2/24 secondary", + "no ip address 10.3.3.3/24 secondary", + "ip address 10.3.3.3/24 tag 3", # Changes primary + "ip address 10.1.1.1/24 secondary", + "ip address 10.2.2.2/24 secondary", + "ip address 10.7.7.7/24 secondary tag 77", + "ip address 10.5.5.5/24 secondary tag 55", + "interface Ethernet1/4", + "ip address 10.40.40.40/24", + "ip address 10.41.41.41/24 secondary", + "evpn multisite dci-tracking", + ] + deleted = [ + "interface mgmt0", + "no ip address", + "interface Ethernet1/1", + "no ip address", + "interface Ethernet1/2", + "no ip address", + "interface Ethernet1/5", + "no ip address", + "no evpn multisite fabric-tracking", + ] + replaced = [ + "interface Ethernet1/1", + "no ip address 10.5.5.5/24 secondary", + "no ip address 10.2.2.2/24 secondary", + "no ip address 10.3.3.3/24 secondary", + "ip address 10.3.3.3/24 tag 3", # Changes primary + "ip address 10.1.1.1/24 secondary", + "ip address 10.2.2.2/24 secondary", + "ip address 10.7.7.7/24 secondary tag 77", + "ip address 10.5.5.5/24 secondary tag 55", + "interface Ethernet1/2", + "no ip address", + "interface Ethernet1/4", + "ip address 10.40.40.40/24", + "ip address 10.41.41.41/24 secondary", + "evpn multisite dci-tracking", + "interface Ethernet1/5", + "no ip address", + "no evpn multisite fabric-tracking", + ] + overridden = [ + "interface Ethernet1/1", + "no ip address 10.6.6.6/24 secondary", + "no ip address 10.5.5.5/24 secondary", + "no ip address 10.2.2.2/24 secondary", + "no ip address 10.3.3.3/24 secondary", + "ip address 10.3.3.3/24 tag 3", # Changes primary + "ip address 10.1.1.1/24 secondary", + "ip address 10.2.2.2/24 secondary", + "ip address 10.7.7.7/24 secondary tag 77", + "ip address 10.5.5.5/24 secondary tag 55", + "interface Ethernet1/2", + "no ip address", + "interface Ethernet1/3", + "no ip address", + "interface Ethernet1/4", + "ip address 10.40.40.40/24", + "ip address 10.41.41.41/24 secondary", + "evpn multisite dci-tracking", + "interface Ethernet1/5", + "no ip address", + "no evpn multisite fabric-tracking", + ] + + playbook["state"] = "merged" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=merged) + + playbook["state"] = "deleted" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=deleted) + + playbook["state"] = "replaced" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=replaced) + + playbook["state"] = "overridden" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=overridden) + + def test_12(self): + # Use case specific + existing = dedent( + """\ + interface mgmt0 + ip address 10.0.0.254/24 + interface Vlan99 + no shutdown + ip address 192.168.1.1/24 + """, + ) + self.get_resource_connection_facts.return_value = {self.SHOW_CMD: existing} + playbook = dict( + config=[ + dict( + name="Vlan99", + ipv4=[{"address": "192.168.1.1/24", "tag": 500}], # adding a tag + ), + ], + state="replaced", + ) + cmds = ["interface Vlan99", "ip address 192.168.1.1/24 tag 500"] + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=cmds) + + def test_12_gathered(self): + # check for parsing correct contexts + existing = dedent( + """\ + interface nve1 + no shutdown + source-interface loopback1 + interface Ethernet1/1 + description + ip address 192.168.1.1/24 + interface Ethernet1/2 + ip address 192.168.2.1/24 + interface loopback1 + """, + ) + self.get_resource_connection_facts.return_value = {self.SHOW_CMD: existing} + playbook = dict(state="gathered") + gathered_facts = [ + {"name": "nve1"}, + {"name": "Ethernet1/1", "ipv4": [{"address": "192.168.1.1/24"}]}, + {"name": "Ethernet1/2", "ipv4": [{"address": "192.168.2.1/24"}]}, + {"name": "loopback1"}, + ] + set_module_args(playbook, ignore_provider_arg) + result = self.execute_module(changed=False) + self.assertEqual(result["gathered"], gathered_facts) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_lacp_interfaces.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_lacp_interfaces.py new file mode 100644 index 00000000..e6850278 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_lacp_interfaces.py @@ -0,0 +1,107 @@ +# (c) 2020 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from textwrap import dedent + +from ansible_collections.cisco.nxos.plugins.modules import nxos_lacp_interfaces +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, set_module_args + + +ignore_provider_arg = True + + +class TestNxosLacpInterfacesModule(TestNxosModule): + module = nxos_lacp_interfaces + + def setUp(self): + super(TestNxosLacpInterfacesModule, self).setUp() + + self.mock_FACT_LEGACY_SUBSETS = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.facts.facts.FACT_LEGACY_SUBSETS", + ) + self.FACT_LEGACY_SUBSETS = self.mock_FACT_LEGACY_SUBSETS.start() + + self.mock_get_resource_connection_config = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base.get_resource_connection", + ) + self.get_resource_connection_config = self.mock_get_resource_connection_config.start() + + self.mock_get_resource_connection_facts = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection", + ) + self.get_resource_connection_facts = self.mock_get_resource_connection_facts.start() + + self.mock_edit_config = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.config.l3_interfaces.l3_interfaces.L3_interfaces.edit_config", + ) + self.edit_config = self.mock_edit_config.start() + + def tearDown(self): + super(TestNxosLacpInterfacesModule, self).tearDown() + self.mock_FACT_LEGACY_SUBSETS.stop() + self.mock_get_resource_connection_config.stop() + self.mock_get_resource_connection_facts.stop() + self.mock_edit_config.stop() + + # --------------------------- + # Lacp_interfaces Test Cases + # --------------------------- + + SHOW_CMD = "show running-config | section ^interface" + + def test_lacp_mode_parse(self): + # basic tests + existing = dedent( + """\ + interface port-channel1 + switchport + switchport mode trunk + switchport trunk native vlan 5 + switchport trunk allowed vlan 10 + no lacp graceful-convergence + """, + ) + self.get_resource_connection_facts.return_value = {self.SHOW_CMD: existing} + playbook = dict( + config=[ + dict( + name="port-channel1", + convergence={"graceful": False}, + suspend_individual=True, + mode="delay", + ), + ], + ) + # Expected result commands for each 'state' + merged = [ + "interface port-channel1", + "lacp mode delay", + "lacp suspend-individual", + ] + + playbook["state"] = "merged" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=merged) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_lldp_interfaces.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_lldp_interfaces.py new file mode 100644 index 00000000..c2acfcc4 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_lldp_interfaces.py @@ -0,0 +1,258 @@ +# +# (c) 2019, Ansible by Red Hat, inc +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +# + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from ansible_collections.cisco.nxos.plugins.modules import nxos_lldp_interfaces +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch +from ansible_collections.cisco.nxos.tests.unit.modules.utils import set_module_args + +from .nxos_module import TestNxosModule + + +class TestNxosLldpInterfacesModule(TestNxosModule): + module = nxos_lldp_interfaces + + def setUp(self): + super(TestNxosLldpInterfacesModule, self).setUp() + + self.mock_get_config = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.get_config", + ) + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_get_resource_connection_config = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base.get_resource_connection", + ) + self.get_resource_connection_config = self.mock_get_resource_connection_config.start() + + self.mock_get_resource_connection_facts = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection", + ) + self.get_resource_connection_facts = self.mock_get_resource_connection_facts.start() + + self.mock_edit_config = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.config.lldp_interfaces.lldp_interfaces.Lldp_interfaces.edit_config", + ) + self.edit_config = self.mock_edit_config.start() + + self.mock_execute_show_command = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.facts.lldp_interfaces.lldp_interfaces.Lldp_interfacesFacts.get_device_data", + ) + self.execute_show_command = self.mock_execute_show_command.start() + + def tearDown(self): + super(TestNxosLldpInterfacesModule, self).tearDown() + self.mock_get_resource_connection_config.stop() + self.mock_get_resource_connection_facts.stop() + self.mock_edit_config.stop() + self.mock_get_config.stop() + self.mock_load_config.stop() + self.mock_execute_show_command.stop() + + def load_fixtures(self, commands=None, device=""): + def load_from_file(*args, **kwargs): + output = """interface Ethernet1/1 + lldp receive + no lldp transmit + interface Ethernet1/2 + no lldp receive + lldp tlv-set vlan 12""" + return output + + self.execute_show_command.side_effect = load_from_file + + def test_nxos_lldp_interfaces_merged(self): + set_module_args( + dict( + config=[ + dict( + name="Ethernet1/3", + receive=False, + tlv_set=dict(vlan=123), + ), + ], + state="merged", + ), + ) + commands = [ + "interface Ethernet1/3", + "no lldp receive", + "lldp tlv-set vlan 123", + ] + self.execute_module(changed=True, commands=commands) + + def test_nxos_lldp_interfaces_merged_idempotent(self): + set_module_args( + dict( + config=[ + dict( + name="Ethernet1/2", + receive=False, + tlv_set=dict(vlan=12), + ), + dict(name="Ethernet1/1", receive=True, transmit=False), + ], + state="merged", + ), + ) + self.execute_module(changed=False, commands=[]) + + def test_nxos_lldp_interfaces_replaced(self): + set_module_args( + dict( + config=[ + dict( + name="Ethernet1/2", + receive=True, + transmit=False, + tlv_set=dict(management_address="192.0.2.123"), + ), + ], + state="replaced", + ), + ) + commands = [ + "interface Ethernet1/2", + "lldp receive", + "no lldp transmit", + "no lldp tlv-set vlan 12", + "lldp tlv-set management-address 192.0.2.123", + ] + self.execute_module(changed=True, commands=commands) + + def test_nxos_lldp_interfaces_replaced_idempotent(self): + set_module_args( + dict( + config=[ + dict( + name="Ethernet1/2", + receive=False, + tlv_set=dict(vlan=12), + ), + dict(name="Ethernet1/1", receive=True, transmit=False), + ], + state="replaced", + ), + ) + self.execute_module(changed=False, commands=[]) + + def test_nxos_lldp_interfaces_overridden(self): + set_module_args( + dict( + config=[dict(name="Ethernet1/4", receive=True, transmit=False)], + state="overridden", + ), + ) + commands = [ + "interface Ethernet1/4", + "lldp receive", + "no lldp transmit", + "interface Ethernet1/1", + "lldp receive", + "lldp transmit", + "interface Ethernet1/2", + "lldp receive", + "no lldp tlv-set vlan 12", + ] + self.execute_module(changed=True, commands=commands) + + def test_nxos_lldp_interfaces_overridden_idempotent(self): + set_module_args( + dict( + config=[ + dict( + name="Ethernet1/2", + receive=False, + tlv_set=dict(vlan=12), + ), + dict(name="Ethernet1/1", receive=True, transmit=False), + ], + state="overridden", + ), + ) + self.execute_module(changed=False, commands=[]) + + def test_nxos_lldp_interfaces_deleted_intf(self): + set_module_args(dict(config=[dict(name="Ethernet1/2")], state="deleted")) + commands = [ + "interface Ethernet1/2", + "lldp receive", + "no lldp tlv-set vlan 12", + ] + self.execute_module(changed=True, commands=commands) + + def test_nxos_lldp_interfaces_deleted_all(self): + set_module_args(dict(state="deleted")) + commands = [ + "interface Ethernet1/2", + "lldp receive", + "no lldp tlv-set vlan 12", + "interface Ethernet1/1", + "lldp receive", + "lldp transmit", + ] + self.execute_module(changed=True, commands=commands) + + def test_nxos_lldp_interfaces_rendered(self): + set_module_args( + dict( + config=[ + dict( + name="Ethernet1/2", + receive=False, + tlv_set=dict(vlan=12), + ), + dict(name="Ethernet1/1", receive=True, transmit=False), + ], + state="rendered", + ), + ) + commands = [ + "interface Ethernet1/1", + "lldp receive", + "no lldp transmit", + "interface Ethernet1/2", + "no lldp receive", + "lldp tlv-set vlan 12", + ] + result = self.execute_module(changed=False) + self.assertEqual(sorted(result["rendered"]), sorted(commands), result["rendered"]) + + def test_nxos_lldp_interfaces_parsed(self): + set_module_args( + dict( + running_config="""interface Ethernet1/1 + lldp receive + no lldp transmit + interface Ethernet1/2 + no lldp receive + lldp tlv-set vlan 12""", + state="parsed", + ), + ) + result = self.execute_module(changed=False) + compare_list = [ + {"name": "Ethernet1/1", "receive": True, "transmit": False}, + {"name": "Ethernet1/2", "receive": False, "tlv_set": {"vlan": 12}}, + ] + self.assertEqual(result["parsed"], compare_list, result["parsed"]) + + def test_nxos_lldp_interfaces_gathered(self): + set_module_args(dict(state="gathered")) + result = self.execute_module(changed=False) + compare_list = [ + {"name": "Ethernet1/1", "receive": True, "transmit": False}, + {"name": "Ethernet1/2", "receive": False, "tlv_set": {"vlan": 12}}, + ] + self.assertEqual(result["gathered"], compare_list, result["gathered"]) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_logging_global.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_logging_global.py new file mode 100644 index 00000000..aea13fc9 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_logging_global.py @@ -0,0 +1,759 @@ +# (c) 2021 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from textwrap import dedent + +from ansible_collections.cisco.nxos.plugins.modules import nxos_logging_global +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, set_module_args + + +ignore_provider_arg = True + + +class TestNxosLoggingGlobalModule(TestNxosModule): + module = nxos_logging_global + + def setUp(self): + super(TestNxosLoggingGlobalModule, self).setUp() + + self.mock_get_resource_connection = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module_base.get_resource_connection", + ) + self.get_resource_connection = self.mock_get_resource_connection.start() + + self.mock_get_config = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.facts.logging_global.logging_global.Logging_globalFacts.get_config", + ) + self.get_config = self.mock_get_config.start() + + def tearDown(self): + super(TestNxosLoggingGlobalModule, self).tearDown() + self.get_resource_connection.stop() + self.get_config.stop() + + def test_nxos_logging_global_linear_merged(self): + # test merged for linear attributes + self.get_config.return_value = dedent( + """\ + """, + ) + set_module_args( + dict( + config=dict( + console=dict(severity="alert"), + module=dict(severity="notification"), + monitor=dict(severity="critical"), + history=dict(severity="informational", size=4096), + rate_limit="disabled", + rfc_strict=True, + origin_id=dict(string="nodeA"), + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "logging console 1", + "logging module 5", + "logging monitor 2", + "logging history 6", + "logging history size 4096", + "no logging rate-limit", + "logging rfc-strict 5424", + "logging origin-id string nodeA", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_logging_global_linear_merged_idempotent(self): + # test merged for linear attributes (idempotent) + self.get_config.return_value = dedent( + """\ + logging console 1 + logging module 5 + logging monitor 2 + logging history 6 + logging history size 4096 + no logging rate-limit + logging rfc-strict 5424 + logging origin-id string nodeA + """, + ) + set_module_args( + dict( + config=dict( + console=dict(severity="alert"), + module=dict(severity="notification"), + monitor=dict(severity="critical"), + history=dict(severity="informational", size=4096), + rate_limit="disabled", + rfc_strict=True, + origin_id=dict(string="nodeA"), + ), + state="merged", + ), + ignore_provider_arg, + ) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_logging_global_linear_merged_2(self): + # test merged for linear attributes - 2 + self.get_config.return_value = dedent( + """\ + logging console 1 + no logging module + logging monitor 2 + logging history 6 + logging history size 4096 + no logging rate-limit + """, + ) + set_module_args( + dict( + config=dict( + console=dict(state="disabled"), + module=dict(state="enabled"), + monitor=dict(state="disabled"), + history=dict(severity="informational", size=4096), + rate_limit="enabled", + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "no logging console 1", + "logging module", + "no logging monitor 2", + "logging rate-limit", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_logging_global_linear_replaced(self): + # test replaced for linear attributes + self.get_config.return_value = dedent( + """\ + logging console 1 + logging module 5 + logging monitor 2 + logging history 6 + logging history size 4096 + no logging rate-limit + logging rfc-strict 5424 + logging origin-id string nodeA + """, + ) + set_module_args( + dict( + config=dict( + console=dict(severity="notification"), + monitor=dict(severity="critical"), + history=dict(size=4096), + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "logging console 5", + "logging module", + "no logging history 6", + "logging rate-limit", + "no logging rfc-strict 5424", + "no logging origin-id string nodeA", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_logging_global_linear_replaced(self): + # test replaced for linear attributes + self.get_config.return_value = dedent( + """\ + logging console 1 + logging module 5 + logging monitor 2 + logging history 6 + logging history size 4096 + no logging rate-limit + logging rfc-strict 5424 + """, + ) + set_module_args( + dict( + config=dict( + console=dict(severity="notification"), + monitor=dict(severity="critical"), + history=dict(size=4096), + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "logging console 5", + "logging module", + "no logging history 6", + "logging rate-limit", + "no logging rfc-strict 5424", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_logging_global_linear_merged_3(self): + # test merged for linear attributes - 3 + self.get_config.return_value = dedent( + """\ + """, + ) + set_module_args( + dict( + config=dict( + origin_id=dict(hostname=True), + ip=dict( + access_list=dict( + cache=dict(entries=16384, interval=200, threshold=80), + detailed=True, + include=dict(sgt=True), + ), + ), + source_interface="Ethernet1/100", + timestamp="milliseconds", + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "logging origin-id hostname", + "logging ip access-list cache entries 16384", + "logging ip access-list cache interval 200", + "logging ip access-list cache threshold 80", + "logging ip access-list detailed", + "logging ip access-list include sgt", + "logging source-interface Ethernet1/100", + "logging timestamp milliseconds", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_logging_global_linear_merged_3_idempotent(self): + # test merged for linear attributes - 3 (idempotent) + self.get_config.return_value = dedent( + """\ + logging origin-id hostname + logging ip access-list cache entries 16384 + logging ip access-list cache interval 200 + logging ip access-list cache threshold 80 + logging ip access-list detailed + logging ip access-list include sgt + logging source-interface Ethernet1/100 + logging timestamp milliseconds + """, + ) + set_module_args( + dict( + config=dict( + origin_id=dict(hostname=True), + ip=dict( + access_list=dict( + cache=dict(entries=16384, interval=200, threshold=80), + detailed=True, + include=dict(sgt=True), + ), + ), + source_interface="Ethernet1/100", + timestamp="milliseconds", + ), + state="merged", + ), + ignore_provider_arg, + ) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_logging_global_linear_replaced_3(self): + # test replaced for linear attributes - 3 + self.get_config.return_value = dedent( + """\ + logging origin-id hostname + logging ip access-list cache entries 16384 + logging ip access-list cache interval 200 + logging ip access-list cache threshold 80 + logging ip access-list detailed + logging ip access-list include sgt + logging source-interface Ethernet1/100 + logging timestamp milliseconds + """, + ) + set_module_args( + dict( + config=dict( + origin_id=dict(ip="192.168.1.1"), + ip=dict(access_list=dict(cache=dict(entries=16384, interval=210))), + source_interface="Ethernet1/120", + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "no logging origin-id hostname", + "logging origin-id ip 192.168.1.1", + "logging ip access-list cache interval 210", + "no logging ip access-list cache threshold 80", + "no logging ip access-list detailed", + "no logging ip access-list include sgt", + "logging source-interface Ethernet1/120", + "no logging timestamp milliseconds", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_logging_global_complex_merged(self): + # test merged for complex attributes + self.get_config.return_value = dedent( + """\ + """, + ) + set_module_args( + dict( + config=dict( + logfile=dict( + name="nodeA_log", + size=4096, + severity="critical", + persistent_threshold=80, + ), + facilities=[ + dict(facility="auth", severity="alert"), + dict(facility="ospfv3", severity="critical"), + dict(facility="cron", severity="notification"), + dict(facility="vlan_mgr", severity="notification"), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "logging logfile nodeA_log 2 size 4096 persistent threshold 80", + "logging level cron 5", + "logging level ospfv3 2", + "logging level auth 1", + "logging level vlan_mgr 5", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_logging_global_complex_merged_idempotent(self): + # test merged for complex attributes (idempotent) + self.get_config.return_value = dedent( + """\ + logging logfile nodeA_log 2 size 4096 persistent threshold 80 + logging level cron 5 + logging level ospfv3 2 + logging level auth 1 + logging level vlan_mgr 5 + """, + ) + set_module_args( + dict( + config=dict( + logfile=dict( + name="nodeA_log", + size=4096, + severity="critical", + persistent_threshold=80, + ), + facilities=[ + dict(facility="auth", severity="alert"), + dict(facility="ospfv3", severity="critical"), + dict(facility="cron", severity="notification"), + dict(facility="vlan_mgr", severity="notification"), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_logging_global_complex_replaced(self): + # test replaced for complex attributes + self.get_config.return_value = dedent( + """\ + logging logfile nodeA_log 2 size 4096 persistent threshold 80 + logging level cron 5 + logging level ospfv3 2 + logging level auth 1 + """, + ) + set_module_args( + dict( + config=dict( + facilities=[ + dict(facility="auth", severity="alert"), + dict(facility="ospfv3", severity="critical"), + dict(facility="ospf", severity="notification"), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + + commands = [ + "logging logfile messages 5", + "no logging level cron 5", + "logging level ospf 5", + ] + + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_logging_global_event_merged(self): + # test merged for `event` + self.get_config.return_value = dedent( + """\ + """, + ) + set_module_args( + dict( + config=dict( + event=dict( + link_status=dict(enable=False, default=False), + trunk_status=dict(enable=False, default=True), + ), + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "no logging event link-status enable", + "no logging event link-status default", + "no logging event trunk-status enable", + "logging event trunk-status default", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_logging_global_event_merged(self): + # test merged for `event` + self.get_config.return_value = dedent( + """\ + no logging event link-status enable + no logging event link-status default + no logging event trunk-status enable + logging event trunk-status default + """, + ) + set_module_args( + dict( + config=dict( + event=dict( + link_status=dict(enable=False, default=False), + trunk_status=dict(enable=False, default=True), + ), + ), + state="merged", + ), + ignore_provider_arg, + ) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_logging_global_event_replaced(self): + # test replaced for `event` + self.get_config.return_value = dedent( + """\ + no logging event link-status enable + no logging event link-status default + no logging event trunk-status enable + logging event trunk-status default + """, + ) + set_module_args( + dict( + config=dict( + event=dict( + link_status=dict(default=False), + trunk_status=dict(enable=False), + ), + ), + state="replaced", + ), + ignore_provider_arg, + ) + + commands = [ + "logging event link-status enable", + "no logging event trunk-status default", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_logging_global_gathered_empty(self): + set_module_args(dict(running_config="", state="gathered"), ignore_provider_arg) + result = self.execute_module(changed=False) + self.assertEqual(result["gathered"], {}) + + def test_nxos_logging_global_gathered(self): + # test gathered + self.get_config.return_value = dedent( + """\ + logging console 1 + logging module 5 + logging monitor 2 + logging history 6 + logging level vlan_mgr 5 + logging history size 4096 + no logging rate-limit + logging rfc-strict 5424 + logging origin-id string nodeA + """, + ) + set_module_args(dict(state="gathered"), ignore_provider_arg) + gathered = { + "console": {"severity": "alert"}, + "module": {"severity": "notification"}, + "monitor": {"severity": "critical"}, + "history": {"severity": "informational", "size": 4096}, + "rate_limit": "disabled", + "rfc_strict": True, + "origin_id": {"string": "nodeA"}, + "facilities": [{"facility": "vlan_mgr", "severity": "notification"}], + } + result = self.execute_module(changed=False) + self.assertEqual(result["gathered"], gathered) + + def test_nxos_logging_global_parsed(self): + # test parsed + cfg = dedent( + """\ + logging console 1 + logging module 5 + logging monitor 2 + logging history 6 + logging history size 4096 + no logging rate-limit + logging rfc-strict 5424 + logging origin-id string nodeA + """, + ) + set_module_args(dict(running_config=cfg, state="parsed"), ignore_provider_arg) + parsed = { + "console": {"severity": "alert"}, + "module": {"severity": "notification"}, + "monitor": {"severity": "critical"}, + "history": {"severity": "informational", "size": 4096}, + "rate_limit": "disabled", + "rfc_strict": True, + "origin_id": {"string": "nodeA"}, + } + result = self.execute_module(changed=False) + self.assertEqual(result["parsed"], parsed) + + def test_nxos_logging_global_hosts_merged(self): + # test merged for `hosts` + self.get_config.return_value = dedent( + """\ + """, + ) + set_module_args( + dict( + config=dict( + hosts=[ + dict( + host="192.168.1.1", + severity="alert", + facility="auth", + port=5891, + use_vrf="default", + secure=dict(trustpoint=dict(client_identity="test")), + ), + dict(host="192.168.1.2"), + dict(host="192.168.1.3", severity="critical"), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "logging server 192.168.1.1 1 port 5891 secure trustpoint client-identity test facility auth use-vrf default", + "logging server 192.168.1.2", + "logging server 192.168.1.3 2", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_logging_global_hosts_replaced(self): + # test replaced for `hosts` + self.get_config.return_value = dedent( + """\ + logging server 192.168.1.1 1 port 5891 secure trustpoint client-identity test facility auth use-vrf default + logging server 192.168.1.2 + logging server 192.168.1.3 2 + """, + ) + set_module_args( + dict( + config=dict( + hosts=[ + dict( + host="192.168.1.1", + severity="alert", + facility="auth", + port=5891, + use_vrf="default", + secure=dict(trustpoint=dict(client_identity="test")), + ), + dict( + host="192.168.1.3", + severity="debugging", + use_vrf="management", + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "logging server 192.168.1.1 1 port 5891 secure trustpoint client-identity test facility auth use-vrf default", + "no logging server 192.168.1.2", + "no logging server 192.168.1.3 2", + "logging server 192.168.1.3 7 use-vrf management", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_logging_global_linear_negated_merged(self): + # test merged for negated linear attributes + self.get_config.return_value = dedent( + """\ + no logging console + no logging module + no logging monitor + """, + ) + set_module_args( + dict( + config=dict( + console=dict(severity="notification"), + module=dict(state="enabled"), + monitor=dict(severity="critical"), + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = ["logging console 5", "logging module", "logging monitor 2"] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_logging_global_deleted(self): + # test deleted + self.get_config.return_value = dedent( + """\ + logging console 1 + logging module 5 + logging monitor 2 + logging history 6 + logging history size 4096 + no logging rate-limit + logging rfc-strict 5424 + logging origin-id string nodeA + """, + ) + set_module_args(dict(state="deleted"), ignore_provider_arg) + commands = [ + "logging console", + "logging module", + "logging monitor", + "no logging history 6", + "no logging history size 4096", + "logging rate-limit", + "no logging rfc-strict 5424", + "no logging origin-id string nodeA", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_logging_global_event_replaced_2(self): + # test replaced for `event` - 2 + self.get_config.return_value = dedent( + """\ + no logging event link-status enable + no logging event link-status default + no logging event trunk-status enable + logging event trunk-status default + """, + ) + set_module_args( + dict( + config=dict(event=dict(trunk_status=dict(enable=False, default=True))), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "logging event link-status enable", + "logging event link-status default", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_logging_global_event_replaced_2(self): + # test replaced for `event` - 2 + self.get_config.return_value = dedent( + """\ + no logging event link-status enable + no logging event link-status default + no logging event trunk-status enable + logging event trunk-status default + """, + ) + set_module_args( + dict( + config=dict(console=dict(severity="critical")), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "logging event link-status enable", + "logging event link-status default", + "logging event trunk-status enable", + "no logging event trunk-status default", + "logging console 2", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_ntp_global.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_ntp_global.py new file mode 100644 index 00000000..7c49d866 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_ntp_global.py @@ -0,0 +1,719 @@ +# (c) 2021 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from textwrap import dedent + +from ansible_collections.cisco.nxos.plugins.modules import nxos_ntp_global +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, set_module_args + + +ignore_provider_arg = True + + +class TestNxosNtpGlobalModule(TestNxosModule): + module = nxos_ntp_global + + def setUp(self): + super(TestNxosNtpGlobalModule, self).setUp() + + self.mock_get_resource_connection = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module_base.get_resource_connection", + ) + self.get_resource_connection = self.mock_get_resource_connection.start() + + self.mock_get_config = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.facts.ntp_global.ntp_global.Ntp_globalFacts.get_config", + ) + self.get_config = self.mock_get_config.start() + + def tearDown(self): + super(TestNxosNtpGlobalModule, self).tearDown() + self.get_resource_connection.stop() + self.get_config.stop() + + def test_nxos_ntp_global_linear_merged(self): + # test merged for linear attributes + self.get_config.return_value = dedent( + """\ + """, + ) + set_module_args( + dict( + config=dict( + access_group=dict( + peer=[ + dict(access_list="PeerAcl1"), + dict(access_list="PeerAcl2"), + ], + serve=[ + dict(access_list="ServeAcl1"), + dict(access_list="ServeAcl2"), + ], + query_only=[ + dict(access_list="QueryAcl1"), + dict(access_list="QueryAcl2"), + ], + serve_only=[ + dict(access_list="ServeOnlyAcl1"), + dict(access_list="ServeOnlyAcl2"), + ], + ), + allow=dict(control=dict(rate_limit=400), private=True), + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "ntp access-group peer PeerAcl1", + "ntp access-group peer PeerAcl2", + "ntp access-group serve ServeAcl1", + "ntp access-group serve ServeAcl2", + "ntp access-group query-only QueryAcl1", + "ntp access-group query-only QueryAcl2", + "ntp access-group serve-only ServeOnlyAcl1", + "ntp access-group serve-only ServeOnlyAcl2", + "ntp allow control rate-limit 400", + "ntp allow private", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ntp_global_linear_merged_idempotent(self): + # test merged for linear attributes (idempotent) + self.get_config.return_value = dedent( + """\ + ntp access-group peer PeerAcl1 + ntp access-group peer PeerAcl2 + ntp access-group serve ServeAcl1 + ntp access-group serve ServeAcl2 + ntp access-group query-only QueryAcl1 + ntp access-group query-only QueryAcl2 + ntp access-group serve-only ServeOnlyAcl1 + ntp access-group serve-only ServeOnlyAcl2 + ntp allow control rate-limit 400 + ntp allow private + """, + ) + set_module_args( + dict( + config=dict( + access_group=dict( + peer=[ + dict(access_list="PeerAcl1"), + dict(access_list="PeerAcl2"), + ], + serve=[ + dict(access_list="ServeAcl1"), + dict(access_list="ServeAcl2"), + ], + query_only=[ + dict(access_list="QueryAcl1"), + dict(access_list="QueryAcl2"), + ], + serve_only=[ + dict(access_list="ServeOnlyAcl1"), + dict(access_list="ServeOnlyAcl2"), + ], + ), + allow=dict(control=dict(rate_limit=400), private=True), + ), + state="merged", + ), + ignore_provider_arg, + ) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_ntp_global_linear_replaced_idempotent(self): + # test merged for linear attributes (idempotent) + self.get_config.return_value = dedent( + """\ + ntp access-group peer PeerAcl1 + ntp access-group peer PeerAcl2 + ntp access-group serve ServeAcl1 + ntp access-group serve ServeAcl2 + ntp access-group query-only QueryAcl1 + ntp access-group query-only QueryAcl2 + ntp access-group serve-only ServeOnlyAcl1 + ntp access-group serve-only ServeOnlyAcl2 + ntp allow control rate-limit 400 + ntp allow private + """, + ) + set_module_args( + dict( + config=dict( + access_group=dict( + peer=[dict(access_list="PeerAcl1")], + serve=[ + dict(access_list="ServeAcl1"), + dict(access_list="ServeAcl2"), + dict(access_list="ServeAcl3"), + ], + query_only=[ + dict(access_list="QueryAcl1"), + dict(access_list="QueryAcl2"), + ], + ), + allow=dict(control=dict(rate_limit=400)), + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "no ntp allow private", + "no ntp access-group peer PeerAcl2", + "ntp access-group serve ServeAcl3", + "no ntp access-group serve-only ServeOnlyAcl1", + "no ntp access-group serve-only ServeOnlyAcl2", + ] + result = self.execute_module(changed=True) + print(result["commands"]) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ntp_global_complex_merged(self): + # test merged for complex attributes + self.get_config.return_value = dedent( + """\ + """, + ) + set_module_args( + dict( + config=dict( + authenticate=True, + authentication_keys=[ + dict(id=1, key="testPass", encryption=0), + dict(id=2, key="vagwwtKfkv", encryption=7), + dict(id=3, key="secretPass", encryption=0), + ], + logging=True, + master=dict(stratum=2), + passive=True, + source="192.168.1.1", + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "ntp authenticate", + "ntp authentication-key 1 md5 testPass 0", + "ntp authentication-key 2 md5 vagwwtKfkv 7", + "ntp authentication-key 3 md5 secretPass 0", + "ntp logging", + "ntp master 2", + "ntp passive", + "ntp source 192.168.1.1", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ntp_global_complex_merged_idempotent(self): + # test merged for complex attributes + self.get_config.return_value = dedent( + """\ + ntp authenticate + ntp authentication-key 1 md5 testPass 0 + ntp authentication-key 2 md5 vagwwtKfkv 7 + ntp authentication-key 3 md5 secretPass 0 + ntp logging + ntp master 2 + ntp passive + ntp source 192.168.1.1 + """, + ) + set_module_args( + dict( + config=dict( + authenticate=True, + authentication_keys=[ + dict(id=1, key="testPass", encryption=0), + dict(id=2, key="vagwwtKfkv", encryption=7), + dict(id=3, key="secretPass", encryption=0), + ], + logging=True, + master=dict(stratum=2), + passive=True, + source="192.168.1.1", + ), + state="merged", + ), + ignore_provider_arg, + ) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_ntp_global_complex_merged_idempotent(self): + # test merged for complex attributes + self.get_config.return_value = dedent( + """\ + ntp authenticate + ntp authentication-key 1 md5 testPass 0 + ntp authentication-key 2 md5 vagwwtKfkv 7 + ntp authentication-key 3 md5 secretPass 0 + ntp logging + ntp master 2 + ntp passive + ntp source 192.168.1.1 + """, + ) + set_module_args( + dict( + config=dict( + authentication_keys=[ + dict(id=1, key="testPass", encryption=0), + dict(id=2, key="vagwwtKfkvb", encryption=7), + ], + logging=True, + master=dict(stratum=3), + source="192.168.1.1", + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "ntp authentication-key 2 md5 vagwwtKfkvb 7", + "no ntp authentication-key 3 md5 secretPass 0", + "ntp master 3", + "no ntp authenticate", + "no ntp passive", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ntp_global_complex_2_merged(self): + # test merged for complex attributes - 2 + self.get_config.return_value = dedent( + """\ + """, + ) + set_module_args( + dict( + config=dict( + peers=[ + dict( + peer="192.168.1.1", + key_id=2, + minpoll=5, + maxpoll=15, + use_vrf="siteA", + prefer=True, + ), + dict(peer="192.168.1.2", key_id=3, use_vrf="siteB"), + dict(peer="192.168.1.3", maxpoll=10, use_vrf="default"), + ], + servers=[ + dict( + server="203.0.113.1", + key_id=2, + minpoll=5, + maxpoll=15, + use_vrf="siteA", + prefer=True, + ), + dict(server="203.0.113.2", key_id=3, use_vrf="siteB"), + dict(server="203.0.113.3", maxpoll=10, use_vrf="default"), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "ntp peer 192.168.1.1 prefer use-vrf siteA key 2 minpoll 5 maxpoll 15", + "ntp peer 192.168.1.2 use-vrf siteB key 3", + "ntp peer 192.168.1.3 use-vrf default maxpoll 10", + "ntp server 203.0.113.1 prefer use-vrf siteA key 2 minpoll 5 maxpoll 15", + "ntp server 203.0.113.2 use-vrf siteB key 3", + "ntp server 203.0.113.3 use-vrf default maxpoll 10", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ntp_global_complex_2_merged_idempotent(self): + # test merged for complex attributes - 2 (idempotent) + self.get_config.return_value = dedent( + """\ + ntp peer 192.168.1.1 prefer use-vrf siteA key 2 minpoll 5 maxpoll 15 + ntp peer 192.168.1.2 use-vrf siteB key 3 + ntp peer 192.168.1.3 use-vrf default maxpoll 10 + ntp server 203.0.113.1 prefer use-vrf siteA key 2 minpoll 5 maxpoll 15 + ntp server 203.0.113.2 use-vrf siteB key 3 + ntp server 203.0.113.3 use-vrf default maxpoll 10 + """, + ) + set_module_args( + dict( + config=dict( + peers=[ + dict( + peer="192.168.1.1", + key_id=2, + minpoll=5, + maxpoll=15, + vrf="siteA", + prefer=True, + ), + dict(peer="192.168.1.2", key_id=3, vrf="siteB"), + dict(peer="192.168.1.3", maxpoll=10, vrf="default"), + ], + servers=[ + dict( + server="203.0.113.1", + key_id=2, + minpoll=5, + maxpoll=15, + vrf="siteA", + prefer=True, + ), + dict(server="203.0.113.2", key_id=3, vrf="siteB"), + dict(server="203.0.113.3", maxpoll=10, vrf="default"), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_ntp_global_complex_2_replaced(self): + # test replaced for complex attributes - 2 + self.get_config.return_value = dedent( + """\ + ntp peer 192.168.1.1 prefer use-vrf siteA key 2 minpoll 5 maxpoll 15 + ntp peer 192.168.1.2 use-vrf siteB key 3 + ntp peer 192.168.1.3 use-vrf default maxpoll 10 + ntp server 203.0.113.1 prefer use-vrf siteA key 2 minpoll 5 maxpoll 15 + ntp server 203.0.113.2 use-vrf siteB key 3 + ntp server 203.0.113.3 use-vrf default maxpoll 10 + """, + ) + set_module_args( + dict( + config=dict( + peers=[ + dict( + peer="192.168.1.1", + key_id=2, + minpoll=5, + maxpoll=15, + vrf="siteA", + prefer=True, + ), + dict(peer="192.168.1.2", vrf="siteB"), + ], + servers=[ + dict( + server="203.0.113.1", + key_id=2, + minpoll=5, + maxpoll=15, + vrf="siteA", + prefer=True, + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "no ntp peer 192.168.1.2 use-vrf siteB key 3", + "ntp peer 192.168.1.2 use-vrf siteB", + "no ntp peer 192.168.1.3 use-vrf default maxpoll 10", + "no ntp server 203.0.113.2 use-vrf siteB key 3", + "no ntp server 203.0.113.3 use-vrf default maxpoll 10", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ntp_global_complex_3_merged(self): + # test merged for complex attributes - 3 + self.get_config.return_value = dedent( + """\ + """, + ) + set_module_args( + dict( + config=dict( + trusted_keys=[ + dict(key_id=1001), + dict(key_id=1002), + dict(key_id=1003), + ], + source_interface="Ethernet1/1", + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "ntp trusted-key 1001", + "ntp trusted-key 1002", + "ntp trusted-key 1003", + "ntp source-interface Ethernet1/1", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ntp_global_complex_3_merged_idempotent(self): + # test merged for complex attributes - 3 (idempotent) + self.get_config.return_value = dedent( + """\ + ntp trusted-key 1001 + ntp trusted-key 1002 + ntp trusted-key 1003 + ntp source-interface Ethernet1/1 + """, + ) + set_module_args( + dict( + config=dict( + trusted_keys=[ + dict(key_id=1001), + dict(key_id=1002), + dict(key_id=1003), + ], + source_interface="Ethernet1/1", + ), + state="merged", + ), + ignore_provider_arg, + ) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_ntp_global_source_interface_merged_idempotent(self): + # test merged for complex attributes - 3 (idempotent) + self.get_config.return_value = dedent( + """\ + ntp trusted-key 1001 + ntp trusted-key 1002 + ntp trusted-key 1003 + ntp source-interface Ethernet1/1 + """, + ) + set_module_args( + dict(config=dict(source_interface="Ethernet1/1"), state="merged"), + ignore_provider_arg, + ) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_ntp_global_complex_3_replaced(self): + # test replaced for complex attributes - 3 + self.get_config.return_value = dedent( + """\ + ntp trusted-key 1001 + ntp trusted-key 1002 + ntp trusted-key 1003 + ntp source-interface 192.168.1.100 + """, + ) + set_module_args( + dict( + config=dict( + trusted_keys=[ + dict(key_id=1001), + dict(key_id=1002), + dict(key_id=1004), + ], + source_interface="192.168.1.101", + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "no ntp trusted-key 1003", + "ntp trusted-key 1004", + "ntp source-interface 192.168.1.101", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ntp_global_gathered_empty(self): + set_module_args(dict(running_config="", state="gathered"), ignore_provider_arg) + result = self.execute_module(changed=False) + self.assertEqual(result["gathered"], {}) + + def test_nxos_ntp_global_gathered(self): + self.get_config.return_value = dedent( + """\ + ntp trusted-key 1001 + ntp trusted-key 1002 + ntp trusted-key 1003 + ntp source-interface 192.168.1.100 + """, + ) + set_module_args(dict(state="gathered"), ignore_provider_arg) + gathered = { + "trusted_keys": [ + {"key_id": 1001}, + {"key_id": 1002}, + {"key_id": 1003}, + ], + "source_interface": "192.168.1.100", + } + result = self.execute_module(changed=False) + self.assertEqual(result["gathered"], gathered) + + def test_nxos_ntp_global_parsed(self): + cfg = dedent( + """\ + ntp trusted-key 1001 + ntp trusted-key 1002 + ntp trusted-key 1003 + ntp source-interface 192.168.1.100 + """, + ) + set_module_args(dict(running_config=cfg, state="parsed"), ignore_provider_arg) + parsed = { + "trusted_keys": [ + {"key_id": 1001}, + {"key_id": 1002}, + {"key_id": 1003}, + ], + "source_interface": "192.168.1.100", + } + result = self.execute_module(changed=False) + self.assertEqual(result["parsed"], parsed) + + def test_nxos_ntp_global_linear_deleted(self): + self.get_config.return_value = dedent( + """\ + ntp access-group peer PeerAcl1 + ntp access-group peer PeerAcl2 + ntp access-group serve ServeAcl1 + ntp access-group serve ServeAcl2 + ntp access-group query-only QueryAcl1 + ntp access-group query-only QueryAcl2 + ntp access-group serve-only ServeOnlyAcl1 + ntp access-group serve-only ServeOnlyAcl2 + ntp allow control rate-limit 400 + ntp allow private + """, + ) + set_module_args(dict(state="deleted"), ignore_provider_arg) + commands = [ + "no ntp access-group peer PeerAcl1", + "no ntp access-group peer PeerAcl2", + "no ntp access-group serve ServeAcl1", + "no ntp access-group serve ServeAcl2", + "no ntp access-group query-only QueryAcl1", + "no ntp access-group query-only QueryAcl2", + "no ntp access-group serve-only ServeOnlyAcl1", + "no ntp access-group serve-only ServeOnlyAcl2", + "no ntp allow control rate-limit 400", + "no ntp allow private", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ntp_global_alias(self): + self.get_config.return_value = dedent( + """\ + """, + ) + set_module_args( + dict( + config=dict( + servers=[ + dict( + server="1.1.1.1", + vrf="management", + ), + dict( + server="1.1.1.3", + use_vrf="v200", + ), + ], + peers=[ + dict( + peer="192.168.1.1", + vrf="default", + ), + dict( + peer="192.168.1.2", + use_vrf="v200", + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "ntp server 1.1.1.1 use-vrf management", + "ntp server 1.1.1.3 use-vrf v200", + "ntp peer 192.168.1.1 use-vrf default", + "ntp peer 192.168.1.2 use-vrf v200", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ntp_global_alias_idempotent(self): + self.get_config.return_value = dedent( + """\ + ntp server 1.1.1.1 use-vrf management + ntp server 1.1.1.3 use-vrf v200 + ntp peer 192.168.1.1 use-vrf default + ntp peer 192.168.1.2 use-vrf v200 + """, + ) + set_module_args( + dict( + config=dict( + servers=[ + dict( + server="1.1.1.1", + vrf="management", + ), + dict( + server="1.1.1.3", + use_vrf="v200", + ), + ], + peers=[ + dict( + peer="192.168.1.1", + vrf="default", + ), + dict( + peer="192.168.1.2", + use_vrf="v200", + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + self.execute_module(changed=False) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_nxapi.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_nxapi.py new file mode 100644 index 00000000..7eb12a21 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_nxapi.py @@ -0,0 +1,100 @@ +# (c) 2016 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from ansible_collections.cisco.nxos.plugins.modules import nxos_nxapi +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, load_fixture, set_module_args + + +class TestNxosNxapiModule(TestNxosModule): + module = nxos_nxapi + + def setUp(self): + super(TestNxosNxapiModule, self).setUp() + + self.mock_run_commands = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_nxapi.run_commands", + ) + self.run_commands = self.mock_run_commands.start() + + self.mock_load_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_nxapi.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_get_capabilities = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_nxapi.get_capabilities", + ) + self.get_capabilities = self.mock_get_capabilities.start() + self.get_capabilities.return_value = { + "device_info": { + "network_os_platform": "N7K-C7018", + "network_os_version": "8.3(1)", + }, + "network_api": "cliconf", + } + + def tearDown(self): + super(TestNxosNxapiModule, self).tearDown() + self.mock_run_commands.stop() + self.mock_load_config.stop() + self.mock_get_capabilities.stop() + + def load_fixtures(self, commands=None, device=""): + def load_from_file(*args, **kwargs): + module, commands = args + module_name = self.module.__name__.rsplit(".", 1)[1] + + output = list() + for command in commands: + filename = str(command).split(" | ", 1)[0].replace(" ", "_") + output.append(load_fixture(module_name, filename, device)) + return output + + self.run_commands.side_effect = load_from_file + self.load_config.return_value = None + + def test_nxos_nxapi_no_change(self): + set_module_args( + dict( + http=True, + https=False, + http_port=80, + https_port=443, + sandbox=False, + ), + ) + self.execute_module_devices(changed=False, commands=[]) + + def test_nxos_nxapi_disable(self): + set_module_args(dict(state="absent")) + self.execute_module_devices(changed=True, commands=["no feature nxapi"]) + + def test_nxos_nxapi_no_http(self): + set_module_args(dict(https=True, http=False, https_port=8443)) + self.execute_module_devices( + changed=True, + commands=["no nxapi http", "nxapi https port 8443"], + ) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_ospf_interfaces.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_ospf_interfaces.py new file mode 100644 index 00000000..f2288957 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_ospf_interfaces.py @@ -0,0 +1,1570 @@ +# (c) 2020 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from textwrap import dedent + +from ansible_collections.cisco.nxos.plugins.modules import nxos_ospf_interfaces +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, set_module_args + + +ignore_provider_arg = True + + +class TestNxosOspfInterfacesModule(TestNxosModule): + # Testing strategy + # ------------------ + # (a) The unit tests cover `merged` and `replaced` for every attribute. + # Since `overridden` is essentially `replaced` but at a larger + # scale, these indirectly cover `overridden` as well. + # (b) For linear attributes replaced is not valid and hence, those tests + # delete the attributes from the config subsection. + + module = nxos_ospf_interfaces + + def setUp(self): + super(TestNxosOspfInterfacesModule, self).setUp() + + self.mock_get_resource_connection = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module_base.get_resource_connection", + ) + self.get_resource_connection = self.mock_get_resource_connection.start() + + self.mock_get_config = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.facts.ospf_interfaces.ospf_interfaces.Ospf_interfacesFacts.get_config", + ) + self.get_config = self.mock_get_config.start() + + def tearDown(self): + super(TestNxosOspfInterfacesModule, self).tearDown() + self.get_resource_connection.stop() + self.get_config.stop() + + def test_nxos_ospf_interfaces_af_process_area_merged(self): + # test merged for config->af->processes->area + self.get_config.return_value = dedent( + """\ + interface Ethernet1/1 + no switchport + ip router ospf 100 area 1.1.1.1 secondaries none + interface Ethernet1/2 + no switchport + ip router ospf 101 area 2.2.2.2 + ipv6 router ospfv3 100 area 4.4.4.4 + interface Ethernet1/3 + no switchport + interface Ethernet1/4 + no switchport + """, + ) + set_module_args( + dict( + config=[ + dict( + name="Ethernet1/1", + address_family=[ + dict( + afi="ipv4", + processes=[ + dict( + process_id="102", + area=dict(area_id="1.1.1.2"), + ), + ], + ), + dict( + afi="ipv6", + processes=[ + dict( + process_id="200", + area=dict(area_id="2.2.2.8"), + ), + ], + ), + ], + ), + dict( + name="Ethernet1/2", + address_family=[ + dict( + afi="ipv4", + processes=[ + dict( + process_id="101", + area=dict(area_id="2.2.2.3"), + ), + ], + ), + ], + ), + dict( + name="Ethernet1/3", + address_family=[ + dict( + afi="ipv6", + processes=[ + dict( + process_id="300", + area=dict( + area_id="2.2.2.3", + secondaries="False", + ), + ), + ], + ), + ], + ), + ], + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "interface Ethernet1/1", + "ip router ospf 102 area 1.1.1.2", + "ipv6 router ospfv3 200 area 2.2.2.8", + "interface Ethernet1/2", + "ip router ospf 101 area 2.2.2.3", + "interface Ethernet1/3", + "ipv6 router ospfv3 300 area 2.2.2.3 secondaries none", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospf_interfaces_af_process_area_replaced(self): + # test replaced for config->af->processes->area + self.get_config.return_value = dedent( + """\ + interface Ethernet1/1 + no switchport + ip router ospf 100 area 1.1.1.1 secondaries none + interface Ethernet1/2 + no switchport + ip router ospf 101 area 2.2.2.2 + ipv6 router ospfv3 100 area 4.4.4.4 + interface Ethernet1/3 + no switchport + interface Ethernet1/4 + no switchport + """, + ) + set_module_args( + dict( + config=[ + dict( + name="Ethernet1/1", + address_family=[ + dict( + afi="ipv6", + processes=[ + dict( + process_id="200", + area=dict(area_id="2.2.2.8"), + ), + ], + ), + ], + ), + dict( + name="Ethernet1/2", + address_family=[ + dict( + afi="ipv4", + processes=[ + dict( + process_id="102", + area=dict(area_id="1.1.1.2"), + ), + ], + ), + ], + ), + ], + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "interface Ethernet1/1", + "no ip router ospf 100 area 1.1.1.1 secondaries none", + "ipv6 router ospfv3 200 area 2.2.2.8", + "interface Ethernet1/2", + "no ip router ospf 101 area 2.2.2.2", + "ip router ospf 102 area 1.1.1.2", + "no ipv6 router ospfv3 100 area 4.4.4.4", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospf_interfaces_af_process_multiareas_merged(self): + # test merged for config->af->processes->multiareas + # processes->multiareas is only valid for IPv6 + self.get_config.return_value = dedent( + """\ + interface Ethernet1/1 + no switchport + ipv6 router ospfv3 100 multi-area 1.1.1.1 + ipv6 router ospfv3 100 multi-area 1.1.1.2 + ipv6 router ospfv3 102 multi-area 2.2.2.1 + ipv6 router ospfv3 102 multi-area 2.2.2.2 + interface Ethernet1/2 + no switchport + interface Ethernet1/3 + no switchport + interface Ethernet1/4 + no switchport + """, + ) + set_module_args( + dict( + config=[ + dict( + name="Ethernet1/1", + address_family=[ + dict( + afi="ipv6", + processes=[ + dict( + process_id="100", + multi_areas=["1.1.1.3"], + ), + dict( + process_id="200", + multi_areas=["3.3.3.3", "4.4.4.4"], + ), + ], + ), + ], + ), + dict( + name="Ethernet1/2", + address_family=[ + dict( + afi="ipv6", + processes=[ + dict( + process_id="109", + multi_areas=["5.5.5.5", "5.5.5.6"], + ), + ], + ), + ], + ), + ], + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "interface Ethernet1/1", + "ipv6 router ospfv3 100 multi-area 1.1.1.3", + "ipv6 router ospfv3 200 multi-area 3.3.3.3", + "ipv6 router ospfv3 200 multi-area 4.4.4.4", + "interface Ethernet1/2", + "ipv6 router ospfv3 109 multi-area 5.5.5.5", + "ipv6 router ospfv3 109 multi-area 5.5.5.6", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospf_interfaces_af_process_multiareas_replaced(self): + # test replaced for config->af->processes->multiareas + # processes->multiareas is only valid for IPv6 + self.get_config.return_value = dedent( + """\ + interface Ethernet1/1 + no switchport + ipv6 router ospfv3 100 multi-area 1.1.1.1 + ipv6 router ospfv3 100 multi-area 1.1.1.2 + ipv6 router ospfv3 102 multi-area 2.2.2.1 + ipv6 router ospfv3 102 multi-area 2.2.2.2 + interface Ethernet1/2 + no switchport + ipv6 router ospfv3 109 multi-area 5.5.5.5 + ipv6 router ospfv3 200 multi-area 4.2.2.1 + ipv6 router ospfv3 200 multi-area 4.2.2.2 + interface Ethernet1/3 + no switchport + interface Ethernet1/4 + no switchport + """, + ) + set_module_args( + dict( + config=[ + dict( + name="Ethernet1/1", + address_family=[ + dict( + afi="ipv6", + processes=[ + dict( + process_id="100", + multi_areas=["1.1.1.3"], + ), + dict( + process_id="102", + multi_areas=["2.2.2.2"], + ), + dict( + process_id="200", + multi_areas=["3.3.3.3", "4.4.4.4"], + ), + ], + ), + ], + ), + dict( + name="Ethernet1/2", + address_family=[ + dict( + afi="ipv6", + processes=[ + dict( + process_id="109", + multi_areas=["5.5.5.6"], + ), + ], + ), + ], + ), + ], + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "interface Ethernet1/1", + "no ipv6 router ospfv3 100 multi-area 1.1.1.1", + "no ipv6 router ospfv3 100 multi-area 1.1.1.2", + "no ipv6 router ospfv3 102 multi-area 2.2.2.1", + "ipv6 router ospfv3 100 multi-area 1.1.1.3", + "ipv6 router ospfv3 200 multi-area 3.3.3.3", + "ipv6 router ospfv3 200 multi-area 4.4.4.4", + "interface Ethernet1/2", + "no ipv6 router ospfv3 109 multi-area 5.5.5.5", + "no ipv6 router ospfv3 200 multi-area 4.2.2.1", + "no ipv6 router ospfv3 200 multi-area 4.2.2.2", + "ipv6 router ospfv3 109 multi-area 5.5.5.6", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospf_interfaces_af_multiareas_merged(self): + # test merged for config->af->multiareas + self.get_config.return_value = dedent( + """\ + interface Ethernet1/1 + no switchport + ip router ospf multi-area 1.1.1.1 + ip router ospf multi-area 1.1.1.2 + ipv6 router ospfv3 multi-area 2.2.2.1 + ipv6 router ospfv3 multi-area 2.2.2.2 + interface Ethernet1/2 + no switchport + ipv6 router ospfv3 multi-area 5.5.5.5 + interface Ethernet1/3 + no switchport + interface Ethernet1/4 + no switchport + """, + ) + set_module_args( + dict( + config=[ + dict( + name="Ethernet1/1", + address_family=[ + dict(afi="ipv4", multi_areas=["1.1.1.1", "1.1.1.3"]), + dict(afi="ipv6", multi_areas=["3.3.3.3", "4.4.4.4"]), + ], + ), + dict( + name="Ethernet1/2", + address_family=[dict(afi="ipv6", multi_areas=["5.5.5.6"])], + ), + ], + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "interface Ethernet1/1", + "ip router ospf multi-area 1.1.1.3", + "ipv6 router ospfv3 multi-area 3.3.3.3", + "ipv6 router ospfv3 multi-area 4.4.4.4", + "interface Ethernet1/2", + "ipv6 router ospfv3 multi-area 5.5.5.6", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospf_interfaces_af_multiareas_replaced(self): + # test replaced for config->af->multiareas + self.get_config.return_value = dedent( + """\ + interface Ethernet1/1 + no switchport + ip router ospf multi-area 1.1.1.1 + ip router ospf multi-area 1.1.1.2 + ipv6 router ospfv3 multi-area 2.2.2.1 + ipv6 router ospfv3 multi-area 2.2.2.2 + interface Ethernet1/2 + no switchport + ipv6 router ospfv3 multi-area 5.5.5.5 + interface Ethernet1/3 + no switchport + interface Ethernet1/4 + no switchport + """, + ) + set_module_args( + dict( + config=[ + dict( + name="Ethernet1/1", + address_family=[ + dict(afi="ipv4", multi_areas=["1.1.1.1", "1.1.1.3"]), + dict(afi="ipv6", multi_areas=["3.3.3.3", "4.4.4.4"]), + ], + ), + dict(name="Ethernet1/2"), + ], + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "interface Ethernet1/1", + "no ip router ospf multi-area 1.1.1.2", + "no ipv6 router ospfv3 multi-area 2.2.2.1", + "no ipv6 router ospfv3 multi-area 2.2.2.2", + "ip router ospf multi-area 1.1.1.3", + "ipv6 router ospfv3 multi-area 3.3.3.3", + "ipv6 router ospfv3 multi-area 4.4.4.4", + "interface Ethernet1/2", + "no ipv6 router ospfv3 multi-area 5.5.5.5", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospf_interfaces_authentication_merged(self): + # test merged for config->af->authentication + # only valid for IPv4 + self.get_config.return_value = dedent( + """\ + interface Ethernet1/1 + no switchport + ip ospf authentication + interface Ethernet1/2 + no switchport + interface Ethernet1/3 + no switchport + interface Ethernet1/4 + no switchport + ip ospf authentication + """, + ) + set_module_args( + dict( + config=[ + dict( + name="Ethernet1/1", + address_family=[ + dict( + afi="ipv4", + authentication=dict(key_chain="test-1", message_digest=True), + ), + ], + ), + dict( + name="Ethernet1/2", + address_family=[dict(afi="ipv4", authentication=dict(null_auth=True))], + ), + dict( + name="Ethernet1/3", + address_family=[dict(afi="ipv4", authentication=dict(enable=True))], + ), + dict( + name="Ethernet1/4", + address_family=[dict(afi="ipv4", authentication=dict(enable=False))], + ), + ], + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "interface Ethernet1/1", + "ip ospf authentication message-digest", + "ip ospf authentication key-chain test-1", + "interface Ethernet1/2", + "ip ospf authentication null", + "interface Ethernet1/3", + "ip ospf authentication", + "interface Ethernet1/4", + "no ip ospf authentication", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospf_interfaces_authentication_replaced(self): + # test merged for config->af->authentication + # only valid for IPv4 + self.get_config.return_value = dedent( + """\ + interface Ethernet1/1 + no switchport + ip ospf authentication message-digest + ip ospf authentication key-chain test-1 + interface Ethernet1/2 + no switchport + interface Ethernet1/3 + no switchport + interface Ethernet1/4 + no switchport + """, + ) + set_module_args( + dict( + config=[ + dict(name="Ethernet1/1"), + dict( + name="Ethernet1/2", + address_family=[dict(afi="ipv4", authentication=dict(null_auth=True))], + ), + dict( + name="Ethernet1/3", + address_family=[dict(afi="ipv4", authentication=dict(enable=True))], + ), + ], + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "interface Ethernet1/1", + "no ip ospf authentication message-digest", + "no ip ospf authentication key-chain test-1", + "interface Ethernet1/2", + "ip ospf authentication null", + "interface Ethernet1/3", + "ip ospf authentication", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospf_interfaces_authentication_key_merged(self): + # test merged for config->af->authentication_key + # only valid for IPv4 + self.get_config.return_value = dedent( + """\ + interface Ethernet1/1 + no switchport + ip ospf authentication-key 3 abc01d272be25d29 + interface Ethernet1/2 + no switchport + interface Ethernet1/3 + no switchport + interface Ethernet1/4 + no switchport + """, + ) + set_module_args( + dict( + config=[ + dict( + name="Ethernet1/1", + address_family=[ + dict( + afi="ipv4", + authentication_key=dict(encryption=3, key="77840f9d4d882176"), + ), + ], + ), + dict( + name="Ethernet1/2", + address_family=[ + dict( + afi="ipv4", + authentication_key=dict(encryption=0, key="password"), + ), + ], + ), + dict( + name="Ethernet1/3", + address_family=[ + dict( + afi="ipv4", + authentication_key=dict(encryption=7, key="712090404011C031628"), + ), + ], + ), + ], + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "interface Ethernet1/1", + "ip ospf authentication-key 3 77840f9d4d882176", + "interface Ethernet1/2", + "ip ospf authentication-key 0 password", + "interface Ethernet1/3", + "ip ospf authentication-key 7 712090404011C031628", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospf_interfaces_authentication_key_replaced(self): + # test replaced for config->af->authentication_key + # only valid for IPv4 + self.get_config.return_value = dedent( + """\ + interface Ethernet1/1 + no switchport + ip ospf authentication-key 3 abc01d272be25d29 + interface Ethernet1/2 + no switchport + interface Ethernet1/3 + no switchport + ip ospf authentication-key 7 712090404011C031628 + interface Ethernet1/4 + no switchport + """, + ) + set_module_args( + dict( + config=[ + dict(name="Ethernet1/1"), + dict( + name="Ethernet1/2", + address_family=[ + dict( + afi="ipv4", + authentication_key=dict(encryption=0, key="password"), + ), + ], + ), + ], + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "interface Ethernet1/1", + "no ip ospf authentication-key 3 abc01d272be25d29", + "interface Ethernet1/2", + "ip ospf authentication-key 0 password", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospf_interfaces_message_digest_key_merged(self): + # test merged for config->af->message_digest_key + # only valid for IPv4 + self.get_config.return_value = dedent( + """\ + interface Ethernet1/1 + no switchport + ip ospf message-digest-key 101 md5 3 109a86e9d947cc5d + interface Ethernet1/2 + no switchport + interface Ethernet1/3 + no switchport + interface Ethernet1/4 + no switchport + """, + ) + set_module_args( + dict( + config=[ + dict( + name="Ethernet1/1", + address_family=[ + dict( + afi="ipv4", + message_digest_key=dict( + key_id=101, + encryption=3, + key="abc01d272be25d29", + ), + ), + ], + ), + dict( + name="Ethernet1/2", + address_family=[ + dict( + afi="ipv4", + message_digest_key=dict(key_id=1, encryption=0, key="password"), + ), + ], + ), + dict( + name="Ethernet1/3", + address_family=[ + dict( + afi="ipv4", + message_digest_key=dict( + key_id=2, + encryption=7, + key="712090404011C031628", + ), + ), + ], + ), + ], + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "interface Ethernet1/1", + "ip ospf message-digest-key 101 md5 3 abc01d272be25d29", + "interface Ethernet1/2", + "ip ospf message-digest-key 1 md5 0 password", + "interface Ethernet1/3", + "ip ospf message-digest-key 2 md5 7 712090404011C031628", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospf_interfaces_message_digest_key_replaced(self): + # test replaced for config->af->message_digest_key + # only valid for IPv4 + self.get_config.return_value = dedent( + """\ + interface Ethernet1/1 + no switchport + ip ospf message-digest-key 101 md5 3 109a86e9d947cc5d + interface Ethernet1/2 + no switchport + ip ospf message-digest-key 1 md5 0 password + interface Ethernet1/3 + no switchport + interface Ethernet1/4 + no switchport + """, + ) + set_module_args( + dict( + config=[ + dict(name="Ethernet1/1"), + dict( + name="Ethernet1/2", + address_family=[ + dict( + afi="ipv4", + message_digest_key=dict(key_id=1, encryption=0, key="password1"), + ), + ], + ), + ], + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "interface Ethernet1/1", + "no ip ospf message-digest-key 101 md5 3 109a86e9d947cc5d", + "interface Ethernet1/2", + "ip ospf message-digest-key 1 md5 0 password1", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospf_interfaces_linear_args_1_merged(self): + # test merged for config->af->cost, dead_interval, hello_interval + self.get_config.return_value = dedent( + """\ + interface Ethernet1/1 + no switchport + ip ospf cost 100 + ospfv3 cost 120 + ip ospf dead-interval 2400 + ospfv3 dead-interval 1200 + ip ospf hello-interval 9000 + interface Ethernet1/2 + no switchport + ip ospf cost 110 + ip ospf dead-interval 3000 + ospfv3 hello-interval 8000 + interface Ethernet1/3 + no switchport + interface Ethernet1/4 + no switchport + """, + ) + set_module_args( + dict( + config=[ + dict( + name="Ethernet1/1", + address_family=[ + dict(afi="ipv4", cost=200), + dict( + afi="ipv6", + dead_interval=5000, + hello_interval=9000, + ), + ], + ), + dict( + name="Ethernet1/2", + address_family=[ + dict( + afi="ipv4", + cost=120, + dead_interval=3400, + hello_interval=8100, + ), + dict(afi="ipv6", cost=180, dead_interval=3000), + ], + ), + ], + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "interface Ethernet1/1", + "ip ospf cost 200", + "ospfv3 dead-interval 5000", + "ospfv3 hello-interval 9000", + "interface Ethernet1/2", + "ip ospf cost 120", + "ip ospf dead-interval 3400", + "ospfv3 cost 180", + "ospfv3 dead-interval 3000", + "ip ospf hello-interval 8100", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospf_interfaces_linear_args_1_replaced(self): + # test replaced for config->af->cost, dead_interval, hello_interval + self.get_config.return_value = dedent( + """\ + interface Ethernet1/1 + no switchport + ip ospf cost 100 + ospfv3 cost 120 + ip ospf dead-interval 2400 + ospfv3 dead-interval 1200 + ip ospf hello-interval 9000 + interface Ethernet1/2 + no switchport + ip ospf cost 110 + ip ospf dead-interval 3000 + ospfv3 hello-interval 8000 + interface Ethernet1/3 + no switchport + interface Ethernet1/4 + no switchport + """, + ) + set_module_args( + dict( + config=[ + dict( + name="Ethernet1/1", + address_family=[dict(afi="ipv4", cost=200, hello_interval=9000)], + ), + dict( + name="Ethernet1/2", + address_family=[dict(afi="ipv6", cost=180, dead_interval=3000)], + ), + ], + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "interface Ethernet1/1", + "ip ospf cost 200", + "no ospfv3 cost 120", + "no ip ospf dead-interval 2400", + "no ospfv3 dead-interval 1200", + "interface Ethernet1/2", + "no ip ospf cost 110", + "no ip ospf dead-interval 3000", + "no ospfv3 hello-interval 8000", + "ospfv3 cost 180", + "ospfv3 dead-interval 3000", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospf_interfaces_linear_args_2_merged(self): + # test merged for config->af->instance, mtu_ignore, network + # `instance` is only valid for IPv6 + self.get_config.return_value = dedent( + """\ + interface Ethernet1/1 + no switchport + ospfv3 instance 200 + interface Ethernet1/2 + no switchport + ip ospf mtu-ignore + ip ospf network broadcast + ospfv3 network point-to-point + interface Ethernet1/3 + no switchport + interface Ethernet1/4 + no switchport + """, + ) + set_module_args( + dict( + config=[ + dict( + name="Ethernet1/1", + address_family=[ + dict( + afi="ipv4", + mtu_ignore=True, + network="point-to-point", + ), + dict(afi="ipv6", instance=210), + ], + ), + dict( + name="Ethernet1/2", + address_family=[ + dict(afi="ipv4", mtu_ignore=False), + dict(afi="ipv6", network="broadcast"), + ], + ), + ], + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "interface Ethernet1/1", + "ip ospf mtu-ignore", + "ip ospf network point-to-point", + "ospfv3 instance 210", + "interface Ethernet1/2", + "no ip ospf mtu-ignore", + "ospfv3 network broadcast", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospf_interfaces_linear_args_2_replaced(self): + # test replaced for config->af->instance, mtu_ignore, network + # `instance` is only valid for IPv6 + self.get_config.return_value = dedent( + """\ + interface Ethernet1/1 + no switchport + ip ospf mtu-ignore + ospfv3 instance 200 + interface Ethernet1/2 + no switchport + ip ospf mtu-ignore + ip ospf network broadcast + ospfv3 network point-to-point + interface Ethernet1/3 + no switchport + interface Ethernet1/4 + no switchport + """, + ) + set_module_args( + dict( + config=[ + dict( + name="Ethernet1/1", + address_family=[ + dict( + afi="ipv4", + mtu_ignore=False, + network="point-to-point", + ), + dict(afi="ipv6", instance=200), + ], + ), + dict(name="Ethernet1/2"), + ], + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "interface Ethernet1/1", + "no ip ospf mtu-ignore", + "ip ospf network point-to-point", + "interface Ethernet1/2", + "no ip ospf mtu-ignore", + "no ip ospf network broadcast", + "no ospfv3 network point-to-point", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospf_interfaces_linear_args_3_merged(self): + # test merged for config->af->passive_interface, priority, retransmit_interval + self.get_config.return_value = dedent( + """\ + interface Ethernet1/1 + no switchport + ip ospf passive-interface + ip ospf priority 120 + ospfv3 retransmit-interval 4800 + interface Ethernet1/2 + no switchport + ip ospf retransmit-interval 5000 + ospfv3 passive-interface + ospfv3 priority 140 + interface Ethernet1/3 + no switchport + interface Ethernet1/4 + no switchport + """, + ) + set_module_args( + dict( + config=[ + dict( + name="Ethernet1/1", + address_family=[ + dict( + afi="ipv4", + passive_interface=False, + retransmit_interval=8000, + ), + dict(afi="ipv6", passive_interface=True), + ], + ), + dict( + name="Ethernet1/2", + address_family=[ + dict( + afi="ipv4", + passive_interface=True, + retransmit_interval=5000, + ), + ], + ), + dict( + name="Ethernet1/3", + address_family=[ + dict( + afi="ipv4", + passive_interface=True, + priority=200, + ), + dict(afi="ipv6", retransmit_interval=5100), + ], + ), + ], + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "interface Ethernet1/1", + "no ip ospf passive-interface", + "ospfv3 passive-interface", + "ip ospf retransmit-interval 8000", + "interface Ethernet1/2", + "ip ospf passive-interface", + "interface Ethernet1/3", + "ip ospf passive-interface", + "ip ospf priority 200", + "ospfv3 retransmit-interval 5100", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospf_interfaces_linear_args_3_replaced(self): + # test merged for config->af->passive_interface, priority, retransmit_interval + self.get_config.return_value = dedent( + """\ + interface Ethernet1/1 + no switchport + ip ospf passive-interface + ip ospf priority 120 + ospfv3 retransmit-interval 4800 + interface Ethernet1/2 + no switchport + ip ospf retransmit-interval 5000 + ospfv3 passive-interface + ospfv3 priority 140 + interface Ethernet1/3 + no switchport + ip ospf passive-interface + ip ospf priority 200 + ospfv3 retransmit-interval 5100 + interface Ethernet1/4 + no switchport + """, + ) + set_module_args( + dict( + config=[ + dict(name="Ethernet1/1"), + dict( + name="Ethernet1/2", + address_family=[ + dict(afi="ipv4", retransmit_interval=5100), + dict( + afi="ipv6", + passive_interface=True, + priority=140, + ), + ], + ), + ], + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "interface Ethernet1/1", + "no ip ospf passive-interface", + "no ip ospf priority 120", + "no ospfv3 retransmit-interval 4800", + "interface Ethernet1/2", + "ip ospf retransmit-interval 5100", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospf_interfaces_linear_args_4_merged(self): + # test merged for config->af->shutdown, transmit_delay + self.get_config.return_value = dedent( + """\ + interface Ethernet1/1 + no switchport + ip ospf shutdown + ospfv3 transmit-delay 200 + interface Ethernet1/2 + no switchport + ip ospf transmit-delay 210 + ospfv3 shutdown + interface Ethernet1/3 + no switchport + interface Ethernet1/4 + no switchport + """, + ) + set_module_args( + dict( + config=[ + dict( + name="Ethernet1/1", + address_family=[ + dict(afi="ipv4", shutdown=False, transmit_delay=210), + dict(afi="ipv6", shutdown=True), + ], + ), + dict( + name="Ethernet1/2", + address_family=[ + dict(afi="ipv4", shutdown=True), + dict(afi="ipv6", transmit_delay=300), + ], + ), + dict( + name="Ethernet1/3", + address_family=[ + dict(afi="ipv4", shutdown=True, transmit_delay=430), + dict(afi="ipv6", shutdown=True, transmit_delay=120), + ], + ), + ], + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "interface Ethernet1/1", + "no ip ospf shutdown", + "ip ospf transmit-delay 210", + "ospfv3 shutdown", + "interface Ethernet1/2", + "ip ospf shutdown", + "ospfv3 transmit-delay 300", + "interface Ethernet1/3", + "ip ospf shutdown", + "ip ospf transmit-delay 430", + "ospfv3 shutdown", + "ospfv3 transmit-delay 120", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospf_interfaces_linear_args_4_replaced(self): + # test replaced for config->af->shutdown, transmit_delay + self.get_config.return_value = dedent( + """\ + interface Ethernet1/1 + no switchport + ip ospf shutdown + ospfv3 transmit-delay 200 + interface Ethernet1/2 + no switchport + ip ospf transmit-delay 210 + ospfv3 shutdown + interface Ethernet1/3 + no switchport + ip ospf shutdown + ip ospf transmit-delay 430 + interface Ethernet1/4 + no switchport + """, + ) + set_module_args( + dict( + config=[ + dict(name="Ethernet1/1"), + dict( + name="Ethernet1/2", + address_family=[dict(afi="ipv6", transmit_delay=300)], + ), + ], + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "interface Ethernet1/1", + "no ip ospf shutdown", + "no ospfv3 transmit-delay 200", + "interface Ethernet1/2", + "no ospfv3 shutdown", + "no ip ospf transmit-delay 210", + "ospfv3 transmit-delay 300", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospf_interfaces_parsed(self): + # test parsed + set_module_args( + dict( + running_config=dedent( + """\ + interface Ethernet1/1 + no switchport + ip router ospf 102 area 1.1.1.2 secondaries none + ipv6 router ospfv3 200 area 2.2.2.8 + interface Ethernet1/2 + no switchport + ipv6 router ospfv3 210 multi-area 3.3.3.3 + interface Ethernet1/3 + no switchport + interface Ethernet1/4 + no switchport + """, + ), + state="parsed", + ), + ignore_provider_arg, + ) + parsed = [ + { + "name": "Ethernet1/1", + "address_family": [ + { + "afi": "ipv4", + "processes": [ + { + "process_id": "102", + "area": { + "area_id": "1.1.1.2", + "secondaries": False, + }, + }, + ], + }, + { + "afi": "ipv6", + "processes": [ + { + "process_id": "200", + "area": {"area_id": "2.2.2.8"}, + }, + ], + }, + ], + }, + { + "name": "Ethernet1/2", + "address_family": [ + { + "afi": "ipv6", + "processes": [{"process_id": "210", "multi_areas": ["3.3.3.3"]}], + }, + ], + }, + {"name": "Ethernet1/3"}, + {"name": "Ethernet1/4"}, + ] + result = self.execute_module(changed=False) + self.assertEqual(result["parsed"], parsed) + + def test_nxos_ospf_interfaces_gathered(self): + # test gathered + self.get_config.return_value = dedent( + """\ + interface Ethernet1/1 + no switchport + ip router ospf 102 area 1.1.1.2 secondaries none + ipv6 router ospfv3 200 area 2.2.2.8 + interface Ethernet1/2 + no switchport + ipv6 router ospfv3 210 multi-area 3.3.3.3 + interface Ethernet1/3 + no switchport + interface Ethernet1/4 + no switchport + """, + ) + set_module_args(dict(state="gathered"), ignore_provider_arg) + gathered = [ + { + "name": "Ethernet1/1", + "address_family": [ + { + "afi": "ipv4", + "processes": [ + { + "process_id": "102", + "area": { + "area_id": "1.1.1.2", + "secondaries": False, + }, + }, + ], + }, + { + "afi": "ipv6", + "processes": [ + { + "process_id": "200", + "area": {"area_id": "2.2.2.8"}, + }, + ], + }, + ], + }, + { + "name": "Ethernet1/2", + "address_family": [ + { + "afi": "ipv6", + "processes": [{"process_id": "210", "multi_areas": ["3.3.3.3"]}], + }, + ], + }, + {"name": "Ethernet1/3"}, + {"name": "Ethernet1/4"}, + ] + result = self.execute_module(changed=False) + self.assertEqual(result["gathered"], gathered) + + def test_nxos_ospf_interfaces_sanity(self): + # test gathered + self.get_config.return_value = dedent( + """ + """, + ) + set_module_args(dict(state="gathered"), ignore_provider_arg) + gathered = [] + result = self.execute_module(changed=False) + self.assertEqual(result["gathered"], gathered) + + def test_nxos_ospf_interfaces_overridden(self): + # test overriden + self.get_config.return_value = dedent( + """\ + interface Ethernet1/1 + no switchport + ip ospf shutdown + ospfv3 transmit-delay 200 + interface Ethernet1/2 + no switchport + ip ospf transmit-delay 210 + ospfv3 shutdown + interface Ethernet1/3 + no switchport + ip ospf message-digest-key 101 md5 3 109a86e9d947cc5d + interface Ethernet1/4 + no switchport + """, + ) + set_module_args( + dict( + config=[ + dict( + name="Ethernet1/1", + address_family=[ + dict(afi="ipv4", shutdown=False, transmit_delay=300), + dict(afi="ipv6", shutdown=True), + ], + ), + ], + state="overridden", + ), + ignore_provider_arg, + ) + commands = [ + "interface Ethernet1/1", + "ip ospf transmit-delay 300", + "no ip ospf shutdown", + "no ospfv3 transmit-delay 200", + "ospfv3 shutdown", + "interface Ethernet1/2", + "no ip ospf transmit-delay 210", + "no ospfv3 shutdown", + "interface Ethernet1/3", + "no ip ospf message-digest-key 101 md5 3 109a86e9d947cc5d", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospf_interfaces_deleted(self): + # test deleted + self.get_config.return_value = dedent( + """\ + interface Ethernet1/1 + no switchport + ip ospf shutdown + ospfv3 transmit-delay 200 + interface Ethernet1/2 + no switchport + ip ospf transmit-delay 210 + ospfv3 shutdown + interface Ethernet1/3 + no switchport + ip ospf message-digest-key 101 md5 3 109a86e9d947cc5d + interface Ethernet1/4 + no switchport + """, + ) + set_module_args( + dict(config=[dict(name="Ethernet1/1")], state="deleted"), + ignore_provider_arg, + ) + commands = [ + "interface Ethernet1/1", + "no ip ospf shutdown", + "no ospfv3 transmit-delay 200", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospf_interfaces_deleted_all(self): + # test deleted + self.get_config.return_value = dedent( + """\ + interface Ethernet1/1 + no switchport + ip ospf shutdown + ospfv3 transmit-delay 200 + interface Ethernet1/2 + no switchport + ip ospf transmit-delay 210 + ospfv3 shutdown + interface Ethernet1/3 + no switchport + ip ospf message-digest-key 101 md5 3 109a86e9d947cc5d + interface Ethernet1/4 + no switchport + """, + ) + set_module_args(dict(state="deleted"), ignore_provider_arg) + commands = [ + "interface Ethernet1/1", + "no ip ospf shutdown", + "no ospfv3 transmit-delay 200", + "interface Ethernet1/2", + "no ip ospf transmit-delay 210", + "no ospfv3 shutdown", + "interface Ethernet1/3", + "no ip ospf message-digest-key 101 md5 3 109a86e9d947cc5d", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospf_interfaces_passive_intf(self): + # test edge cases for passive_interface + self.get_config.return_value = dedent( + """\ + interface Ethernet1/1 + no switchport + interface Ethernet1/2 + no switchport + ip ospf passive-interface + interface Ethernet1/3 + no switchport + no ospfv3 passive-interface + interface Ethernet1/4 + no switchport + """, + ) + set_module_args( + dict( + config=[ + dict( + name="Ethernet1/1", + address_family=[ + dict(afi="ipv4", passive_interface=False), + dict(afi="ipv6", passive_interface=False), + ], + ), + dict( + name="Ethernet1/2", + address_family=[dict(afi="ipv4", default_passive_interface=True)], + ), + dict( + name="Ethernet1/3", + address_family=[dict(afi="ipv6", default_passive_interface=True)], + ), + dict( + name="Ethernet1/4", + address_family=[dict(afi="ipv4", default_passive_interface=True)], + ), + ], + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "interface Ethernet1/1", + "no ip ospf passive-interface", + "no ospfv3 passive-interface", + "interface Ethernet1/2", + "default ip ospf passive-interface", + "interface Ethernet1/3", + "default ospfv3 passive-interface", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_ospfv2.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_ospfv2.py new file mode 100644 index 00000000..17557049 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_ospfv2.py @@ -0,0 +1,561 @@ +# (c) 2019 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from textwrap import dedent + +from ansible_collections.cisco.nxos.plugins.modules import nxos_ospfv2 +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, set_module_args + + +ignore_provider_arg = True + + +class TestNxosOspfv2Module(TestNxosModule): + module = nxos_ospfv2 + + def setUp(self): + super(TestNxosOspfv2Module, self).setUp() + + self.mock_get_resource_connection = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module_base.get_resource_connection", + ) + self.get_resource_connection = self.mock_get_resource_connection.start() + + self.mock_get_config = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.facts.ospfv2.ospfv2.Ospfv2Facts.get_config", + ) + self.get_config = self.mock_get_config.start() + + def tearDown(self): + super(TestNxosOspfv2Module, self).tearDown() + self.get_resource_connection.stop() + self.get_config.stop() + + def test_nxos_ospfv2_merged(self): + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + router_id="203.0.113.20", + redistribute=[ + dict( + protocol="eigrp", + id="100", + route_map="rmap_1", + ), + dict( + protocol="direct", + route_map="direct-connect", + ), + ], + log_adjacency_changes=dict(detail=True), + ), + dict( + process_id="200", + router_id="198.51.100.1", + areas=[ + dict( + area_id="0.0.0.100", + filter_list=[ + dict(route_map="rmap_1", direction="in"), + dict(route_map="rmap_2", direction="out"), + ], + ranges=[ + dict(prefix="198.51.100.64/27"), + dict(prefix="198.51.100.96/27"), + ], + ), + dict( + area_id="0.0.0.101", + authentication=dict(message_digest=True), + ), + ], + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router ospf 100", + "router-id 203.0.113.20", + "redistribute eigrp 100 route-map rmap_1", + "redistribute direct route-map direct-connect", + "log-adjacency-changes detail", + "router ospf 200", + "router-id 198.51.100.1", + "area 0.0.0.100 filter-list route-map rmap_1 in", + "area 0.0.0.100 filter-list route-map rmap_2 out", + "area 0.0.0.100 range 198.51.100.64/27", + "area 0.0.0.100 range 198.51.100.96/27", + "area 0.0.0.101 authentication message-digest", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv2_merged_idempotent(self): + self.get_config.return_value = dedent( + """\ + router ospf 100 + router-id 203.0.113.20 + redistribute eigrp 100 route-map rmap_1 + redistribute direct route-map direct-connect + router ospf 200 + router-id 198.51.100.1 + area 0.0.0.100 filter-list route-map rmap_1 in + area 0.0.0.100 filter-list route-map rmap_2 out + area 0.0.0.100 range 198.51.100.64/27 + area 0.0.0.100 range 198.51.100.96/27 + area 0.0.0.101 authentication message-digest + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + router_id="203.0.113.20", + redistribute=[ + dict( + protocol="eigrp", + id="100", + route_map="rmap_1", + ), + dict( + protocol="direct", + route_map="direct-connect", + ), + ], + ), + dict( + process_id="200", + router_id="198.51.100.1", + areas=[ + dict( + area_id="0.0.0.100", + filter_list=[ + dict(route_map="rmap_1", direction="in"), + dict(route_map="rmap_2", direction="out"), + ], + ranges=[ + dict(prefix="198.51.100.64/27"), + dict(prefix="198.51.100.96/27"), + ], + ), + dict( + area_id="0.0.0.101", + authentication=dict(message_digest=True), + ), + ], + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_ospfv2_merged_update(self): + self.get_config.return_value = dedent( + """\ + router ospf 100 + router-id 203.0.113.20 + redistribute eigrp 100 route-map rmap_1 + redistribute direct route-map direct-connect + router ospf 200 + router-id 198.51.100.1 + area 0.0.0.100 filter-list route-map rmap_1 in + area 0.0.0.100 filter-list route-map rmap_2 out + area 0.0.0.100 range 198.51.100.64/27 + area 0.0.0.100 range 198.51.100.96/27 + area 0.0.0.101 authentication message-digest + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + router_id="203.0.113.20", + redistribute=[ + dict( + protocol="eigrp", + id="100", + route_map="rmap_2", + ), + ], + areas=[ + dict( + area_id="0.0.0.101", + stub=dict(no_summary=True), + ), + ], + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + + commands = [ + "router ospf 100", + "redistribute eigrp 100 route-map rmap_2", + "area 0.0.0.101 stub no-summary", + ] + + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv2_replaced(self): + self.get_config.return_value = dedent( + """\ + router ospf 100 + router-id 203.0.113.20 + redistribute eigrp 100 route-map rmap_1 + redistribute direct route-map direct-connect + router ospf 200 + router-id 198.51.100.1 + area 0.0.0.100 filter-list route-map rmap_1 in + area 0.0.0.100 filter-list route-map rmap_2 out + area 0.0.0.100 range 198.51.100.64/27 + area 0.0.0.100 range 198.51.100.96/27 + area 0.0.0.101 authentication message-digest + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + router_id="203.0.113.20", + areas=[ + dict( + area_id="0.0.0.101", + stub=dict(no_summary=True), + ), + ], + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router ospf 100", + "no redistribute eigrp 100 route-map rmap_1", + "no redistribute direct route-map direct-connect", + "area 0.0.0.101 stub no-summary", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv2_replaced_idempotent(self): + self.get_config.return_value = dedent( + """\ + router ospf 100 + router-id 203.0.113.20 + redistribute eigrp 100 route-map rmap_1 + redistribute direct route-map direct-connect + router ospf 200 + router-id 198.51.100.1 + area 0.0.0.100 filter-list route-map rmap_1 in + area 0.0.0.100 filter-list route-map rmap_2 out + area 0.0.0.100 range 198.51.100.64/27 + area 0.0.0.100 range 198.51.100.96/27 + area 0.0.0.101 authentication message-digest + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + router_id="203.0.113.20", + redistribute=[ + dict( + protocol="eigrp", + id="100", + route_map="rmap_1", + ), + dict( + protocol="direct", + route_map="direct-connect", + ), + ], + ), + dict( + process_id="200", + router_id="198.51.100.1", + areas=[ + dict( + area_id="0.0.0.100", + filter_list=[ + dict(route_map="rmap_1", direction="in"), + dict(route_map="rmap_2", direction="out"), + ], + ranges=[ + dict(prefix="198.51.100.64/27"), + dict(prefix="198.51.100.96/27"), + ], + ), + dict( + area_id="0.0.0.101", + authentication=dict(message_digest=True), + ), + ], + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_ospfv2_overridden(self): + self.get_config.return_value = dedent( + """\ + router ospf 100 + router-id 203.0.113.20 + redistribute eigrp 100 route-map rmap_1 + redistribute direct route-map direct-connect + router ospf 200 + router-id 198.51.100.1 + area 0.0.0.100 filter-list route-map rmap_1 in + area 0.0.0.100 filter-list route-map rmap_2 out + area 0.0.0.100 range 198.51.100.64/27 + area 0.0.0.100 range 198.51.100.96/27 + area 0.0.0.101 authentication message-digest + """, + ) + set_module_args( + dict( + config=dict(processes=[dict(process_id="300", router_id="203.0.113.20")]), + state="overridden", + ), + ignore_provider_arg, + ) + commands = [ + "no router ospf 100", + "no router ospf 200", + "router ospf 300", + "router-id 203.0.113.20", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv2_overridden_idempotent(self): + self.get_config.return_value = dedent( + """\ + router ospf 100 + router-id 203.0.113.20 + redistribute eigrp 100 route-map rmap_1 + redistribute direct route-map direct-connect + router ospf 200 + router-id 198.51.100.1 + area 0.0.0.100 filter-list route-map rmap_1 in + area 0.0.0.100 filter-list route-map rmap_2 out + area 0.0.0.100 range 198.51.100.64/27 + area 0.0.0.100 range 198.51.100.96/27 + area 0.0.0.101 authentication message-digest + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + router_id="203.0.113.20", + redistribute=[ + dict( + protocol="eigrp", + id="100", + route_map="rmap_1", + ), + dict( + protocol="direct", + route_map="direct-connect", + ), + ], + ), + dict( + process_id="200", + router_id="198.51.100.1", + areas=[ + dict( + area_id="0.0.0.100", + filter_list=[ + dict(route_map="rmap_1", direction="in"), + dict(route_map="rmap_2", direction="out"), + ], + ranges=[ + dict(prefix="198.51.100.64/27"), + dict(prefix="198.51.100.96/27"), + ], + ), + dict( + area_id="0.0.0.101", + authentication=dict(message_digest=True), + ), + ], + ), + ], + ), + state="overridden", + ), + ignore_provider_arg, + ) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_ospfv2_deleted(self): + self.get_config.return_value = dedent( + """\ + router ospf 100 + router-id 203.0.113.20 + redistribute eigrp 100 route-map rmap_1 + redistribute direct route-map direct-connect + router ospf 200 + router-id 198.51.100.1 + area 0.0.0.100 filter-list route-map rmap_1 in + area 0.0.0.100 filter-list route-map rmap_2 out + area 0.0.0.100 range 198.51.100.64/27 + area 0.0.0.100 range 198.51.100.96/27 + area 0.0.0.101 authentication message-digest + router ospf 300 + router-id 192.0.168.102 + """, + ) + set_module_args( + dict( + config=dict(processes=[dict(process_id="100"), dict(process_id="300")]), + state="deleted", + ), + ignore_provider_arg, + ) + commands = ["no router ospf 100", "no router ospf 300"] + + result = self.execute_module(changed=True) + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_nxos_ospfv2_deleted_idempotent(self): + self.get_config.return_value = dedent( + """\ + router ospf 100 + router-id 203.0.113.20 + redistribute eigrp 100 route-map rmap_1 + redistribute direct route-map direct-connect + router ospf 200 + router-id 198.51.100.1 + area 0.0.0.100 filter-list route-map rmap_1 in + area 0.0.0.100 filter-list route-map rmap_2 out + area 0.0.0.100 range 198.51.100.64/27 + area 0.0.0.100 range 198.51.100.96/27 + area 0.0.0.101 authentication message-digest + router ospf 300 + router-id 192.0.168.102 + """, + ) + set_module_args( + dict( + config=dict(processes=[dict(process_id="400"), dict(process_id="500")]), + state="deleted", + ), + ignore_provider_arg, + ) + + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_ospfv2_deleted_all(self): + self.get_config.return_value = dedent( + """\ + router ospf 100 + router-id 203.0.113.20 + redistribute eigrp 100 route-map rmap_1 + redistribute direct route-map direct-connect + router ospf 200 + router-id 198.51.100.1 + area 0.0.0.100 filter-list route-map rmap_1 in + area 0.0.0.100 filter-list route-map rmap_2 out + area 0.0.0.100 range 198.51.100.64/27 + area 0.0.0.100 range 198.51.100.96/27 + area 0.0.0.101 authentication message-digest + router ospf 300 + router-id 192.0.168.102 + """, + ) + set_module_args(dict(state="deleted"), ignore_provider_arg) + + commands = [ + "no router ospf 100", + "no router ospf 200", + "no router ospf 300", + ] + + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv2_process_id_word(self): + self.get_config.return_value = dedent( + """\ + router ospf 100 + router-id 203.0.113.20 + router ospf TEST-1 + router-id 198.51.100.1 + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict(process_id="100", router_id="203.0.113.20"), + dict(process_id="TEST-1", router_id="198.51.100.1"), + dict(process_id="TEST-2", router_id="198.52.200.1"), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + + commands = ["router ospf TEST-2", "router-id 198.52.200.1"] + + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_ospfv3.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_ospfv3.py new file mode 100644 index 00000000..70a2ae47 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_ospfv3.py @@ -0,0 +1,2213 @@ +# (c) 2020 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from textwrap import dedent + +from ansible_collections.cisco.nxos.plugins.modules import nxos_ospfv3 +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, set_module_args + + +ignore_provider_arg = True + + +class TestNxosOspfv3Module(TestNxosModule): + # Testing strategy + # ------------------ + # (a) The unit tests cover `merged` and `replaced` for every attribute. + # Since `overridden` is essentially `replaced` but at a larger + # scale, these indirectly cover `overridden` as well. + # (b) For linear attributes replaced is not valid and hence, those tests + # delete the attributes from the config subsection. + # (c) The argspec for VRFs is same as the top-level spec and the config logic + # is re-used. Hence, those attributes are not explictly covered. However, a + # combination of VRF + top-level spec + AF is tested. + + module = nxos_ospfv3 + + def setUp(self): + super(TestNxosOspfv3Module, self).setUp() + + self.mock_get_resource_connection = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module_base.get_resource_connection", + ) + self.get_resource_connection = self.mock_get_resource_connection.start() + + self.mock_get_config = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.facts.ospfv3.ospfv3.Ospfv3Facts.get_config", + ) + self.get_config = self.mock_get_config.start() + + def tearDown(self): + super(TestNxosOspfv3Module, self).tearDown() + self.get_resource_connection.stop() + self.get_config.stop() + + def test_nxos_ospfv3_af_areas_filter_list_merged(self): + # test merged for config->processes->af->areas->filter_list + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + address-family ipv6 unicast + area 1.1.1.1 default-cost 100 + area 1.1.1.1 filter-list route-map test-11 in + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + address_family=dict( + afi="ipv6", + safi="unicast", + areas=[ + dict( + area_id="1.1.1.1", + filter_list=[ + dict( + route_map="test-1", + direction="in", + ), + dict( + route_map="test-2", + direction="out", + ), + ], + ), + dict( + area_id="1.1.1.2", + filter_list=[ + dict( + route_map="test-3", + direction="in", + ), + dict( + route_map="test-4", + direction="out", + ), + ], + ), + ], + ), + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "address-family ipv6 unicast", + "area 1.1.1.1 filter-list route-map test-1 in", + "area 1.1.1.1 filter-list route-map test-2 out", + "area 1.1.1.2 filter-list route-map test-3 in", + "area 1.1.1.2 filter-list route-map test-4 out", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_af_areas_filter_list_replaced(self): + # test replaced for config->processes->af->areas->filter_list + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + address-family ipv6 unicast + area 1.1.1.4 filter-list route-map test-11 out + area 1.1.1.4 filter-list route-map test-12 in + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + address_family=dict( + afi="ipv6", + safi="unicast", + areas=[ + dict( + area_id="1.1.1.1", + filter_list=[ + dict( + route_map="test-1", + direction="in", + ), + dict( + route_map="test-2", + direction="out", + ), + ], + ), + dict( + area_id="1.1.1.2", + filter_list=[ + dict( + route_map="test-3", + direction="in", + ), + dict( + route_map="test-4", + direction="out", + ), + ], + ), + ], + ), + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "address-family ipv6 unicast", + "no area 1.1.1.4 filter-list route-map test-11 out", + "no area 1.1.1.4 filter-list route-map test-12 in", + "area 1.1.1.1 filter-list route-map test-1 in", + "area 1.1.1.1 filter-list route-map test-2 out", + "area 1.1.1.2 filter-list route-map test-3 in", + "area 1.1.1.2 filter-list route-map test-4 out", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_af_areas_ranges_merged(self): + # test merged for config->processes->af->areas->rang + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + address-family ipv6 unicast + area 1.1.1.1 range 2001:db2::/32 + area 1.1.1.1 range 2001:db3::/32 cost 10 + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + address_family=dict( + afi="ipv6", + safi="unicast", + areas=[ + dict( + area_id="1.1.1.1", + ranges=[ + dict( + prefix="2001:db3::/32", + cost="20", + ), + ], + ), + dict( + area_id="1.1.1.2", + ranges=[ + dict(prefix="2001:db4::/32", cost=11), + dict( + prefix="2001:db5::/32", + not_advertise=True, + ), + dict( + prefix="2001:db7::/32", + not_advertise=True, + cost=18, + ), + ], + ), + ], + ), + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "address-family ipv6 unicast", + "area 1.1.1.1 range 2001:db3::/32 cost 20", + "area 1.1.1.2 range 2001:db4::/32 cost 11", + "area 1.1.1.2 range 2001:db5::/32 not-advertise", + "area 1.1.1.2 range 2001:db7::/32 not-advertise cost 18", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_af_areas_ranges_replaced(self): + # test replaced for config->processes->af->areas->ranges + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + address-family ipv6 unicast + area 1.1.1.1 range 2001:db2::/32 + area 1.1.1.1 range 2001:db3::/32 cost 10 + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + address_family=dict( + afi="ipv6", + safi="unicast", + areas=[ + dict( + area_id="1.1.1.2", + ranges=[ + dict(prefix="2001:db4::/32", cost=11), + dict( + prefix="2001:db5::/32", + not_advertise=True, + ), + dict( + prefix="2001:db7::/32", + not_advertise=True, + cost=18, + ), + ], + ), + ], + ), + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "address-family ipv6 unicast", + "no area 1.1.1.1 range 2001:db2::/32", + "no area 1.1.1.1 range 2001:db3::/32", + "area 1.1.1.2 range 2001:db4::/32 cost 11", + "area 1.1.1.2 range 2001:db5::/32 not-advertise", + "area 1.1.1.2 range 2001:db7::/32 not-advertise cost 18", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_af_areas_default_cost_merged(self): + # test merged for config->processes->af->areas->default_cost + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + address-family ipv6 unicast + area 1.1.1.1 default-cost 10 + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + address_family=dict( + afi="ipv6", + safi="unicast", + areas=[ + dict(area_id="1.1.1.1", default_cost=12), + dict(area_id="1.1.1.2", default_cost=200), + ], + ), + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "address-family ipv6 unicast", + "area 1.1.1.1 default-cost 12", + "area 1.1.1.2 default-cost 200", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_af_areas_default_cost_replaced(self): + # test merged for config->processes->af->areas->default_cost + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + address-family ipv6 unicast + area 1.1.1.1 default-cost 10 + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + address_family=dict( + afi="ipv6", + safi="unicast", + areas=[dict(area_id="1.1.1.2", default_cost=200)], + ), + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "address-family ipv6 unicast", + "no area 1.1.1.1 default-cost 10", + "area 1.1.1.2 default-cost 200", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_af_default_information_merged(self): + # test merged for config->processes->af->default_information + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + address-family ipv6 unicast + default-information originate + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + address_family=dict( + afi="ipv6", + safi="unicast", + default_information=dict( + originate=dict(always=True, route_map="test-2"), + ), + ), + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "address-family ipv6 unicast", + "default-information originate always route-map test-2", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_af_default_information_merged_2(self): + # test merged for config->processes->af->default_information->set + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + address-family ipv6 unicast + default-information originate always route-map test-2 + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + address_family=dict( + afi="ipv6", + safi="unicast", + default_information=dict(originate=dict(set=False)), + ), + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "address-family ipv6 unicast", + "no default-information originate", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_af_default_information_replaced(self): + # test replaced for config->processes->af->default_information + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + address-family ipv6 unicast + default-information originate always test-2 + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + address_family=dict( + afi="ipv6", + safi="unicast", + default_information=dict(originate=dict(set=True)), + ), + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "address-family ipv6 unicast", + "default-information originate", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_af_distance_merged(self): + # test merged for config->processes->af->distance + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + address-family ipv6 unicast + distance 20 + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + address_family=dict(afi="ipv6", safi="unicast", distance=35), + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "address-family ipv6 unicast", + "distance 35", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_af_distance_replaced(self): + # test replaced for config->processes->af->distance + # `distance` is a linear attribute so replaced test + # can only be removal of this attribute + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + address-family ipv6 unicast + distance 20 + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + address_family=dict(afi="ipv6", safi="unicast"), + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "address-family ipv6 unicast", + "no distance 20", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_af_maximum_paths_merged(self): + # test merged for config->processes->af->maximum_paths + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + address-family ipv6 unicast + maximum-paths 18 + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + address_family=dict(afi="ipv6", safi="unicast", maximum_paths=27), + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "address-family ipv6 unicast", + "maximum-paths 27", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_af_maximum_paths_replaced(self): + # test replaced for config->processes->af->maximum_paths + # `maximum_paths` is a linear attribute so replaced test + # can only be removal of this attribute + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + address-family ipv6 unicast + maximum-paths 18 + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + address_family=dict(afi="ipv6", safi="unicast"), + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "address-family ipv6 unicast", + "no maximum-paths 18", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_af_redistribute_merged(self): + # test merged for config->processes->af->redistribute + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + address-family ipv6 unicast + redistribute eigrp 100 route-map test-17 + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + address_family=dict( + afi="ipv6", + safi="unicast", + redistribute=[ + dict( + protocol="eigrp", + id="100", + route_map="test-1", + ), + dict( + protocol="eigrp", + id="101", + route_map="test-2", + ), + dict( + protocol="bgp", + id="65563", + route_map="test-3", + ), + dict(protocol="static", route_map="test-4"), + ], + ), + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "address-family ipv6 unicast", + "redistribute eigrp 100 route-map test-1", + "redistribute eigrp 101 route-map test-2", + "redistribute bgp 65563 route-map test-3", + "redistribute static route-map test-4", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_af_redistribute_replaced(self): + # test replaced for config->processes->af->redistribute + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + address-family ipv6 unicast + redistribute eigrp 100 route-map test-1 + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + address_family=dict( + afi="ipv6", + safi="unicast", + redistribute=[ + dict( + protocol="eigrp", + id="101", + route_map="test-2", + ), + dict( + protocol="bgp", + id="65563", + route_map="test-3", + ), + dict(protocol="static", route_map="test-4"), + ], + ), + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "address-family ipv6 unicast", + "no redistribute eigrp 100 route-map test-1", + "redistribute eigrp 101 route-map test-2", + "redistribute bgp 65563 route-map test-3", + "redistribute static route-map test-4", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_af_summary_address_merged(self): + # test merged for config->processes->af->summary_address + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + address-family ipv6 unicast + summary-address 2001:db2::/32 + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + address_family=dict( + afi="ipv6", + safi="unicast", + summary_address=[ + dict(prefix="2001:db2::/32", tag=19), + dict( + prefix="2001:db3::/32", + not_advertise=True, + ), + dict(prefix="2001:db4::/32"), + ], + ), + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "address-family ipv6 unicast", + "summary-address 2001:db2::/32 tag 19", + "summary-address 2001:db3::/32 not-advertise", + "summary-address 2001:db4::/32", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_af_summary_address_replaced(self): + # test replaced for config->processes->af->summary_address + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + address-family ipv6 unicast + summary-address 2001:db2::/32 tag 19 + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + address_family=dict( + afi="ipv6", + safi="unicast", + summary_address=[ + dict( + prefix="2001:db3::/32", + not_advertise=True, + ), + ], + ), + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "address-family ipv6 unicast", + "no summary-address 2001:db2::/32 tag 19", + "summary-address 2001:db3::/32 not-advertise", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_af_table_map_merged(self): + # test merged for config->processes->af->table_map + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + address-family ipv6 unicast + summary-address 2001:db2::/32 tag 19 + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + address_family=dict( + afi="ipv6", + safi="unicast", + table_map=dict(name="test-1", filter=True), + ), + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "address-family ipv6 unicast", + "table-map test-1 filter", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_af_table_map_replaced(self): + # test replaced for config->processes->af->table_map + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + address-family ipv6 unicast + table-map test-1 filter + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + address_family=dict( + afi="ipv6", + safi="unicast", + table_map=dict(name="test-2"), + ), + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "address-family ipv6 unicast", + "table-map test-2", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_af_timers_merged(self): + # test merged for config->processes->af->timers + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + address-family ipv6 unicast + timers throttle spf 1000 20 2800 + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + address_family=dict( + afi="ipv6", + safi="unicast", + timers=dict( + throttle=dict( + spf=dict( + initial_spf_delay=1100, + max_wait_time=2805, + ), + ), + ), + ), + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "address-family ipv6 unicast", + "timers throttle spf 1100 20 2805", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_af_timers_replaced(self): + # test replaced for config->processes->af->timers + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + address-family ipv6 unicast + timers throttle spf 1000 20 2800 + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + address_family=dict(afi="ipv6", safi="unicast"), + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "address-family ipv6 unicast", + "no timers throttle spf 1000 20 2800", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_areas_nssa_merged(self): + # test merged for config->processes->areas->nssa + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + area 1.1.1.1 nssa no-redistribution default-information-originate + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + areas=[ + dict( + area_id="1.1.1.1", + nssa=dict(no_summary=True), + ), + dict(area_id="1.1.1.2", nssa=dict(set=True)), + dict( + area_id="1.1.1.3", + nssa=dict( + default_information_originate=True, + no_summary=True, + no_redistribution=True, + route_map="test-1", + translate=dict(type7=dict(always=True, supress_fa=True)), + ), + ), + ], + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "area 1.1.1.1 nssa no-summary no-redistribution default-information-originate", + "area 1.1.1.2 nssa", + "area 1.1.1.3 nssa translate type7 always supress-fa", + "area 1.1.1.3 nssa no-summary no-redistribution default-information-originate route-map test-1", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_areas_nssa_merged_2(self): + # test merged for config->processes->areas->nssa->set + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + area 1.1.1.1 nssa no-summary + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + areas=[dict(area_id="1.1.1.1", nssa=dict(set=False))], + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = ["router ospfv3 100", "no area 1.1.1.1 nssa"] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_areas_nssa_replaced(self): + # test replaced for config->processes->areas->nssa + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + area 1.1.1.1 nssa no-summary no-redistribution default-information-originate + area 1.1.1.3 nssa translate type7 always supress-fa + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + areas=[ + dict( + area_id="1.1.1.3", + nssa=dict( + default_information_originate=True, + no_summary=True, + no_redistribution=True, + route_map="test-1", + ), + ), + ], + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "no area 1.1.1.1 nssa", + "no area 1.1.1.3 nssa translate type7 always supress-fa", + "area 1.1.1.3 nssa no-summary no-redistribution default-information-originate route-map test-1", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_areas_stub_merged(self): + # test merged for config->processes->areas->stub + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + area 1.1.1.3 stub + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + areas=[ + dict( + area_id="1.1.1.3", + stub=dict(no_summary=True), + ), + ], + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = ["router ospfv3 100", "area 1.1.1.3 stub no-summary"] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_areas_stub_merged_2(self): + # test merged for config->processes->areas->stub->set + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + area 1.1.1.3 stub + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + areas=[ + dict(area_id="1.1.1.3", stub=dict(set=False)), + dict( + area_id="1.1.1.4", + stub=dict(no_summary=True), + ), + ], + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "no area 1.1.1.3 stub", + "area 1.1.1.4 stub no-summary", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_areas_stub_replaced(self): + # test replaced for config->processes->areas->stub + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + area 1.1.1.3 stub no-summary + """, + ) + set_module_args( + dict( + config=dict(processes=[dict(process_id="100", areas=[dict(area_id="1.1.1.3")])]), + state="replaced", + ), + ignore_provider_arg, + ) + commands = ["router ospfv3 100", "no area 1.1.1.3 stub"] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_autocost_flush_route_isolate_merged(self): + # test merged for config->processes->autocost,flush_routes, isolate + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + auto-cost reference-bandwidth 300 Mbps + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + auto_cost=dict(reference_bandwidth=100, unit="Gbps"), + flush_routes=True, + isolate=True, + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "auto-cost reference-bandwidth 100 Gbps", + "flush-routes", + "isolate", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_autocost_flush_route_isolate_replaced(self): + # test merged for config->processes->autocost,flush_routes, isolate + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + auto-cost reference-bandwidth 300 Mbps + flush-routes + """, + ) + set_module_args( + dict( + config=dict(processes=[dict(process_id="100", isolate=True)]), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "no auto-cost reference-bandwidth 300 Mbps", + "no flush-routes", + "isolate", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_log_adjacency_changes_name_lookup_passive_interface_merged( + self, + ): + # test merged for config->processes->log_adjacency_changes, name_lookup, passive_interface + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + log-adjacency-changes + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + log_adjacency_changes=dict(detail=True), + name_lookup=True, + passive_interface=dict(default=True), + ), + dict( + process_id="102", + log_adjacency_changes=dict(log=True), + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "log-adjacency-changes detail", + "name-lookup", + "passive-interface default", + "router ospfv3 102", + "log-adjacency-changes", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_log_adjacency_changes_name_lookup_passive_interface_replaced( + self, + ): + # test replaced for config->processes->log_adjacency_changes, name_lookup, passive_interface + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + log-adjacency-changes detail + name-lookup + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + passive_interface=dict(default=True), + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "no log-adjacency-changes detail", + "no name-lookup", + "passive-interface default", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_max_lsa_router_id_merged(self): + # test merged for config->processes->max_lsa, router_id + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + router-id 192.168.1.100 + max-lsa 4200 85 ignore-count 10 reset-time 120 + router ospfv3 102 + max-lsa 4200 85 ignore-time 120 ignore-count 12 reset-time 300 + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + router_id="192.168.1.100", + max_lsa=dict( + max_non_self_generated_lsa=4200, + threshold=85, + ignore_count=100, + reset_time=138, + ), + ), + dict( + process_id="102", + router_id="192.168.2.102", + max_lsa=dict( + max_non_self_generated_lsa=4200, + threshold=85, + ignore_time=200, + ignore_count=20, + reset_time=120, + ), + ), + dict( + process_id="103", + max_lsa=dict( + max_non_self_generated_lsa=4200, + warning_only=True, + ), + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "max-lsa 4200 85 ignore-count 100 reset-time 138", + "router ospfv3 102", + "router-id 192.168.2.102", + "max-lsa 4200 85 ignore-time 200 ignore-count 20 reset-time 120", + "router ospfv3 103", + "max-lsa 4200 warning-only", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_max_lsa_router_id_replaced(self): + # test replaced for config->processes->max_lsa, router_id + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + router-id 192.168.1.100 + max-lsa 4200 85 ignore-count 10 reset-time 120 + router ospfv3 102 + max-lsa 4200 85 ignore-time 120 ignore-count 12 reset-time 300 + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + max_lsa=dict( + max_non_self_generated_lsa=4200, + threshold=85, + warning_only=True, + ), + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "no router-id 192.168.1.100", + "max-lsa 4200 85 warning-only", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_graceful_restart_merged(self): + # test merged for config->processes->graceful_restart + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + no graceful-restart + router ospfv3 102 + no graceful-restart planned-only + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + graceful_restart=dict(grace_period=50, helper_disable=True), + ), + dict( + process_id="102", + graceful_restart=dict(planned_only=True), + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "graceful-restart grace-period 50", + "graceful-restart helper-disable", + "router ospfv3 102", + "graceful-restart planned-only", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_graceful_restart_replaced(self): + # test replaced for config->processes->graceful_restart + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + graceful-restart grace-period 50 + graceful-restart helper-disable + router ospfv3 102 + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + graceful_restart=dict(grace_period=10), + ), + dict( + process_id="102", + graceful_restart=dict(helper_disable=True), + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "graceful-restart grace-period 10", + "no graceful-restart helper-disable", + "router ospfv3 102", + "graceful-restart helper-disable", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_max_metric_merged(self): + # test merged for config->processes->max_metric + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + max-metric router-lsa external-lsa 1900 + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + max_metric=dict( + router_lsa=dict( + external_lsa=dict(max_metric_value=2000), + stub_prefix_lsa=True, + on_startup=dict(set=True), + ), + ), + ), + dict( + process_id="102", + max_metric=dict( + router_lsa=dict(inter_area_prefix_lsa=dict(max_metric_value=1800)), + ), + ), + dict( + process_id="103", + max_metric=dict( + router_lsa=dict( + on_startup=dict( + wait_period=1200, + wait_for_bgp_asn=65563, + ), + inter_area_prefix_lsa=dict(set=True), + ), + ), + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "max-metric router-lsa external-lsa 2000 stub-prefix-lsa on-startup", + "router ospfv3 102", + "max-metric router-lsa inter-area-prefix-lsa 1800", + "router ospfv3 103", + "max-metric router-lsa on-startup 1200 wait-for bgp 65563 inter-area-prefix-lsa", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_max_metric_merged_2(self): + # test merged for config->processes->max_metric->set + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + max-metric router-lsa inter-area-prefix-lsa 1800 + router ospfv3 103 + max-metric router-lsa on-startup 1200 wait-for bgp 65563 inter-area-prefix-lsa + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + max_metric=dict(router_lsa=dict(set=False)), + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = ["router ospfv3 100", "no max-metric router-lsa"] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_max_metric_replaced(self): + # test replaced for config->processes->max_metric + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + router ospfv3 102 + max-metric router-lsa inter-area-prefix-lsa 1800 + router ospfv3 103 + max-metric router-lsa on-startup 1200 wait-for bgp 65563 inter-area-prefix-lsa + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + max_metric=dict( + router_lsa=dict( + external_lsa=dict(max_metric_value=2000), + stub_prefix_lsa=True, + on_startup=dict(set=True), + ), + ), + ), + dict(process_id="102"), + dict(process_id="103"), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "max-metric router-lsa external-lsa 2000 stub-prefix-lsa on-startup", + "router ospfv3 102", + "no max-metric router-lsa", + "router ospfv3 103", + "no max-metric router-lsa", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_timers_shutdown_merged(self): + # test merged for config->processes->timers, shutdown + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + timers lsa-group-pacing 190 + shutdown + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + timers=dict( + lsa_arrival=1200, + lsa_group_pacing=210, + throttle=dict( + lsa=dict( + start_interval=100, + hold_interval=70, + max_interval=1500, + ), + ), + ), + shutdown=False, + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "timers lsa-arrival 1200", + "timers lsa-group-pacing 210", + "timers throttle lsa 100 70 1500", + "no shutdown", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_timers_shutdown_replaced(self): + # test replaced for config->processes->timers, shutdown + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + timers lsa-arrival 800 + timers lsa-group-pacing 210 + timers throttle lsa 100 70 1500 + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + timers=dict(lsa_arrival=1200), + shutdown=True, + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "timers lsa-arrival 1200", + "no timers lsa-group-pacing 210", + "no timers throttle lsa 100 70 1500", + "shutdown", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_vrf_merged(self): + # test merged for config->processes->vrf + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + vrf blue + area 1.1.1.1 nssa + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + vrfs=[ + dict( + vrf="blue", + areas=[ + dict( + area_id="1.1.1.1", + nssa=dict(no_summary=True), + ), + dict( + area_id="1.1.1.2", + nssa=dict(set=True), + ), + ], + ), + dict( + vrf="red", + areas=[ + dict( + area_id="1.1.1.3", + nssa=dict( + default_information_originate=True, + no_summary=True, + no_redistribution=True, + route_map="test-1", + translate=dict( + type7=dict( + always=True, + supress_fa=True, + ), + ), + ), + ), + ], + ), + ], + ), + dict( + process_id="103", + vrfs=[ + dict( + vrf="red", + max_metric=dict( + router_lsa=dict( + on_startup=dict( + wait_period=1200, + wait_for_bgp_asn=65563, + ), + inter_area_prefix_lsa=dict(set=True), + ), + ), + ), + ], + ), + dict( + process_id="104", + vrfs=[ + dict( + vrf="red", + timers=dict( + lsa_arrival=1200, + lsa_group_pacing=210, + throttle=dict( + lsa=dict( + start_interval=100, + hold_interval=70, + max_interval=1500, + ), + ), + ), + shutdown=True, + ), + ], + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "vrf blue", + "area 1.1.1.1 nssa no-summary", + "area 1.1.1.2 nssa", + "vrf red", + "area 1.1.1.3 nssa translate type7 always supress-fa", + "area 1.1.1.3 nssa no-summary no-redistribution default-information-originate route-map test-1", + "router ospfv3 103", + "vrf red", + "max-metric router-lsa on-startup 1200 wait-for bgp 65563 inter-area-prefix-lsa", + "router ospfv3 104", + "vrf red", + "timers lsa-arrival 1200", + "timers lsa-group-pacing 210", + "timers throttle lsa 100 70 1500", + "shutdown", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_vrf_replaced(self): + # test replaced for config->processes->vrf + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + vrf blue + area 1.1.1.1 nssa no-summary + area 1.1.1.2 nssa + vrf red + area 1.1.1.3 nssa translate type7 always supress-fa + area 1.1.1.3 nssa no-summary no-redistribution default-information-originate route-map test-1 + router ospfv3 103 + vrf red + max-metric router-lsa on-startup 1200 wait-for bgp 65563 inter-area-prefix-lsa + router ospfv3 104 + vrf red + timers lsa-arrival 1200 + timers lsa-group-pacing 210 + timers throttle lsa 100 70 1500 + shutdown + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + vrfs=[ + dict( + vrf="blue", + areas=[ + dict( + area_id="1.1.1.1", + nssa=dict( + no_summary=True, + translate=dict( + type7=dict( + always=True, + supress_fa=True, + ), + ), + ), + ), + ], + ), + ], + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "vrf blue", + "area 1.1.1.1 nssa no-summary", + "no area 1.1.1.2 nssa", + "area 1.1.1.1 nssa translate type7 always supress-fa", + "no vrf red", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_top_spec_af_vrf_merged(self): + # test merged for every nested level + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + address-family ipv6 unicast + table-map map1 filter + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + address_family=dict( + afi="ipv6", + safi="unicast", + redistribute=[ + dict( + protocol="eigrp", + id="100", + route_map="rmap1", + ), + ], + ), + vrfs=[ + dict(vrf="blue", router_id="10.0.0.2"), + dict( + vrf="red", + areas=[ + dict( + area_id="1.1.1.1", + nssa=dict(set=True), + ), + ], + ), + ], + ), + dict( + process_id="103", + vrfs=[dict(vrf="red", shutdown=True)], + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "address-family ipv6 unicast", + "redistribute eigrp 100 route-map rmap1", + "vrf blue", + "router-id 10.0.0.2", + "vrf red", + "area 1.1.1.1 nssa", + "router ospfv3 103", + "vrf red", + "shutdown", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_top_spec_af_vrf_replaced(self): + # test replaced for every nested level + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + address-family ipv6 unicast + table-map map1 filter + redistribute eigrp 100 route-map rmap1 + vrf blue + router-id 10.0.0.2 + vrf red + area 1.1.1.1 nssa + router ospfv3 103 + vrf red + shutdown + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + address_family=dict( + afi="ipv6", + safi="unicast", + redistribute=[ + dict( + protocol="eigrp", + id="100", + route_map="rmap1", + ), + ], + ), + ), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "address-family ipv6 unicast", + "no table-map map1 filter", + "no vrf blue", + "no vrf red", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_top_spec_af_vrf_overridden(self): + # test overridden for every nested level + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + address-family ipv6 unicast + table-map map1 filter + redistribute eigrp 100 route-map rmap1 + vrf blue + router-id 10.0.0.2 + vrf red + area 1.1.1.1 nssa + router ospfv3 103 + vrf red + shutdown + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict( + process_id="100", + address_family=dict( + afi="ipv6", + safi="unicast", + redistribute=[ + dict( + protocol="eigrp", + id="100", + route_map="rmap2", + ), + ], + ), + ), + ], + ), + state="overridden", + ), + ignore_provider_arg, + ) + commands = [ + "router ospfv3 100", + "address-family ipv6 unicast", + "no table-map map1 filter", + "redistribute eigrp 100 route-map rmap2", + "no vrf blue", + "no vrf red", + "no router ospfv3 103", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_top_spec_af_vrf_deleted(self): + # test overridden for every nested level + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + address-family ipv6 unicast + table-map map1 filter + redistribute eigrp 100 route-map rmap1 + vrf blue + router-id 10.0.0.2 + vrf red + area 1.1.1.1 nssa + router ospfv3 103 + vrf red + shutdown + """, + ) + set_module_args( + dict( + config=dict(processes=[dict(process_id="100")]), + state="deleted", + ), + ignore_provider_arg, + ) + commands = ["no router ospfv3 100"] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_top_spec_af_vrf_deleted_all(self): + # test overridden for every nested level + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + address-family ipv6 unicast + table-map map1 filter + redistribute eigrp 100 route-map rmap1 + vrf blue + router-id 10.0.0.2 + vrf red + area 1.1.1.1 nssa + router ospfv3 103 + vrf red + shutdown + """, + ) + set_module_args(dict(state="deleted"), ignore_provider_arg) + commands = ["no router ospfv3 100", "no router ospfv3 103"] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_ospfv3_parsed(self): + # test parsed + set_module_args( + dict( + running_config=dedent( + """\ + router ospfv3 100 + address-family ipv6 unicast + table-map map1 filter + redistribute eigrp 100 route-map rmap1 + vrf blue + router-id 10.0.0.2 + vrf red + area 1.1.1.1 nssa + router ospfv3 103 + vrf red + shutdown + """, + ), + state="parsed", + ), + ignore_provider_arg, + ) + parsed = { + "processes": [ + { + "process_id": "100", + "address_family": { + "table_map": {"name": "map1", "filter": True}, + "redistribute": [ + { + "protocol": "eigrp", + "id": "100", + "route_map": "rmap1", + }, + ], + "afi": "ipv6", + "safi": "unicast", + }, + "vrfs": [ + {"vrf": "blue", "router_id": "10.0.0.2"}, + { + "vrf": "red", + "areas": [{"area_id": "1.1.1.1", "nssa": {"set": True}}], + }, + ], + }, + { + "process_id": "103", + "vrfs": [{"vrf": "red", "shutdown": True}], + }, + ], + } + result = self.execute_module(changed=False) + self.assertEqual(set(result["parsed"]), set(parsed)) + + def test_nxos_ospfv3_gathered(self): + # test gathered + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + address-family ipv6 unicast + table-map map1 filter + redistribute eigrp 100 route-map rmap1 + vrf blue + router-id 10.0.0.2 + vrf red + area 1.1.1.1 nssa + router ospfv3 103 + vrf red + shutdown + """, + ) + set_module_args(dict(state="gathered"), ignore_provider_arg) + gathered = { + "processes": [ + { + "process_id": "100", + "address_family": { + "table_map": {"name": "map1", "filter": True}, + "redistribute": [ + { + "protocol": "eigrp", + "id": "100", + "route_map": "rmap1", + }, + ], + "afi": "ipv6", + "safi": "unicast", + }, + "vrfs": [ + {"vrf": "blue", "router_id": "10.0.0.2"}, + { + "vrf": "red", + "areas": [{"area_id": "1.1.1.1", "nssa": {"set": True}}], + }, + ], + }, + { + "process_id": "103", + "vrfs": [{"vrf": "red", "shutdown": True}], + }, + ], + } + result = self.execute_module(changed=False) + self.assertEqual(set(result["gathered"]), set(gathered)) + + def test_nxos_ospfv3_process_id_word(self): + self.get_config.return_value = dedent( + """\ + router ospfv3 100 + router-id 203.0.113.20 + router ospfv3 TEST-1 + router-id 198.51.100.1 + """, + ) + set_module_args( + dict( + config=dict( + processes=[ + dict(process_id="100", router_id="203.0.113.20"), + dict(process_id="TEST-1", router_id="198.51.100.1"), + dict(process_id="TEST-2", router_id="198.52.200.1"), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + + commands = ["router ospfv3 TEST-2", "router-id 198.52.200.1"] + + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_overlay_global.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_overlay_global.py new file mode 100644 index 00000000..976aa096 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_overlay_global.py @@ -0,0 +1,61 @@ +# (c) 2016 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from ansible_collections.cisco.nxos.plugins.modules import nxos_overlay_global +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, load_fixture, set_module_args + + +class TestNxosOverlayGlobalModule(TestNxosModule): + module = nxos_overlay_global + + def setUp(self): + super(TestNxosOverlayGlobalModule, self).setUp() + self.mock_load_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_overlay_global.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_get_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_overlay_global.get_config", + ) + self.get_config = self.mock_get_config.start() + + def tearDown(self): + super(TestNxosOverlayGlobalModule, self).tearDown() + self.mock_load_config.stop() + self.mock_get_config.stop() + + def load_fixtures(self, commands=None, device=""): + self.get_config.return_value = load_fixture("", "nxos_overlay_global_config.cfg") + self.load_config.return_value = None + + def test_nxos_overlay_global_up(self): + set_module_args(dict(anycast_gateway_mac="a.a.a")) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + ["fabric forwarding anycast-gateway-mac 000A.000A.000A"], + ) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_pim.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_pim.py new file mode 100644 index 00000000..eea38483 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_pim.py @@ -0,0 +1,102 @@ +# (c) 2016 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from ansible_collections.cisco.nxos.plugins.modules import nxos_pim +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, load_fixture, set_module_args + + +class TestNxosPimModule(TestNxosModule): + module = nxos_pim + + def setUp(self): + super(TestNxosPimModule, self).setUp() + + self.mock_get_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_pim.get_config", + ) + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_pim.load_config", + ) + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestNxosPimModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, device=""): + self.load_config.return_value = None + + def test_nxos_pim_1(self): + # Add/ Modify + self.get_config.return_value = load_fixture("nxos_pim", "config.cfg") + set_module_args(dict(ssm_range="233.0.0.0/8")) + self.execute_module(changed=True, commands=["ip pim ssm range 233.0.0.0/8"]) + + def test_nxos_pim_2(self): + # Remove existing values + self.get_config.return_value = load_fixture("nxos_pim", "config.cfg") + set_module_args(dict(bfd="disable", ssm_range="none")) + self.execute_module(changed=True, commands=["no ip pim bfd", "ip pim ssm range none"]) + + def test_nxos_pim_3(self): + # bfd None (disable)-> enable + self.get_config.return_value = None + set_module_args(dict(bfd="enable")) + self.execute_module(changed=True, commands=["ip pim bfd"]) + + # bfd None (disable) -> disable + set_module_args(dict(bfd="disable")) + self.execute_module(changed=False) + + # ssm None to 'default' + set_module_args(dict(ssm_range="default")) + self.execute_module(changed=False) + + def test_nxos_pim_4(self): + # SSM 'none' + self.get_config.return_value = load_fixture("nxos_pim", "config.cfg") + set_module_args(dict(ssm_range="none")) + self.execute_module(changed=True, commands=["ip pim ssm range none"]) + + def test_nxos_pim_5(self): + # SSM 'default' + self.get_config.return_value = load_fixture("nxos_pim", "config.cfg") + set_module_args(dict(ssm_range="default")) + self.execute_module(changed=True, commands=["no ip pim ssm range none"]) + + # SSM 'default' idempotence + self.get_config.return_value = None + set_module_args(dict(ssm_range="default")) + self.execute_module(changed=False) + + def test_nxos_pim_6(self): + # Idempotence + self.get_config.return_value = load_fixture("nxos_pim", "config.cfg") + set_module_args(dict(bfd="enable", ssm_range="127.0.0.0/31")) + self.execute_module(changed=False, commands=[]) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_pim_interface.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_pim_interface.py new file mode 100644 index 00000000..886a7794 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_pim_interface.py @@ -0,0 +1,297 @@ +# (c) 2016 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from ansible_collections.cisco.nxos.plugins.modules import nxos_pim_interface +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, load_fixture, set_module_args + + +class TestNxosIPInterfaceModule(TestNxosModule): + module = nxos_pim_interface + + def setUp(self): + super(TestNxosIPInterfaceModule, self).setUp() + + self.mock_get_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_pim_interface.get_config", + ) + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_pim_interface.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_run_commands = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_pim_interface.run_commands", + ) + self.run_commands = self.mock_run_commands.start() + + def tearDown(self): + super(TestNxosIPInterfaceModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + self.mock_run_commands.stop() + + def load_fixtures(self, commands=None, device=""): + module_name = self.module.__name__.rsplit(".", 1)[1] + + def load_from_file(*args, **kwargs): + module, commands = args + output = list() + + for command in commands: + if type(command) == dict: + command = command["command"] + filename = str(command).split(" | ", 1)[0].replace(" ", "_").replace("/", "_") + output.append(load_fixture(module_name, filename)) + return output + + self.get_config.return_value = load_fixture(module_name, "config.cfg") + self.load_config.return_value = None + self.run_commands.side_effect = load_from_file + + def test_nxos_pim_interface_present(self): + set_module_args( + dict( + interface="eth2/1", + dr_prio=10, + hello_interval=40, + sparse=True, + border=False, + ), + ) + self.execute_module( + changed=True, + commands=[ + "interface eth2/1", + "ip pim dr-priority 10", + "ip pim hello-interval 40000", + "ip pim sparse-mode", + ], + ) + + def test_nxos_pim_interface_jp(self): + set_module_args( + dict( + interface="eth2/1", + jp_policy_in="JPIN", + jp_policy_out="JPOUT", + jp_type_in="routemap", + jp_type_out="routemap", + ), + ) + self.execute_module( + changed=True, + commands=[ + "interface eth2/1", + "ip pim jp-policy JPOUT out", + "ip pim jp-policy JPIN in", + ], + ) + + def test_nxos_pim_interface_default(self): + set_module_args(dict(interface="eth2/1", state="default")) + self.execute_module(changed=False, commands=[]) + + def test_nxos_pim_interface_ip_absent(self): + set_module_args(dict(interface="eth2/1", state="absent")) + self.execute_module(changed=False, commands=[]) + + +class TestNxosPimInterfaceBfdModule(TestNxosModule): + module = nxos_pim_interface + + def setUp(self): + super(TestNxosPimInterfaceBfdModule, self).setUp() + + self.mock_get_interface_mode = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_pim_interface.get_interface_mode", + ) + self.get_interface_mode = self.mock_get_interface_mode.start() + + self.mock_get_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_pim_interface.get_config", + ) + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_pim_interface.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_run_commands = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_pim_interface.run_commands", + ) + self.run_commands = self.mock_run_commands.start() + + def tearDown(self): + super(TestNxosPimInterfaceBfdModule, self).tearDown() + self.mock_get_interface_mode.stop() + self.mock_get_config.stop() + self.mock_load_config.stop() + self.mock_run_commands.stop() + + def load_fixtures(self, commands=None, device=""): + self.load_config.return_value = None + + def test_bfd_1(self): + # default (None) -> enable + self.get_config.return_value = None + set_module_args(dict(interface="eth2/1", bfd="enable")) + self.execute_module(changed=True, commands=["interface eth2/1", "ip pim bfd-instance"]) + + # default (None) -> disable + set_module_args(dict(interface="eth2/1", bfd="disable")) + self.execute_module( + changed=True, + commands=["interface eth2/1", "ip pim bfd-instance disable"], + ) + + # default (None) -> default (None) (idempotence) + set_module_args(dict(interface="eth2/1", bfd="default")) + self.execute_module(changed=False) + + # default (None) -> interface state 'default' + set_module_args(dict(interface="Ethernet9/3", state="default")) + self.execute_module(changed=False) + + # default (None) -> interface state 'absent' + set_module_args(dict(interface="Ethernet9/3", state="absent")) + self.execute_module(changed=False) + + def test_bfd_2(self): + # From disable + self.get_config.return_value = """ + interface Ethernet9/2 + ip pim bfd-instance disable + """ + # disable -> enable + set_module_args(dict(interface="Ethernet9/2", bfd="enable")) + self.execute_module( + changed=True, + commands=["interface Ethernet9/2", "ip pim bfd-instance"], + ) + + # disable -> disable (idempotence) + set_module_args(dict(interface="Ethernet9/2", bfd="disable")) + self.execute_module(changed=False) + + # disable -> default (None) + set_module_args(dict(interface="Ethernet9/2", bfd="default")) + self.execute_module( + changed=True, + commands=["interface Ethernet9/2", "no ip pim bfd-instance"], + ) + # disable -> interface state 'default' + set_module_args(dict(interface="Ethernet9/3", state="default")) + self.execute_module( + changed=True, + commands=["interface Ethernet9/3", "no ip pim bfd-instance"], + ) + + # disable -> interface state 'absent' + set_module_args(dict(interface="Ethernet9/3", state="absent")) + self.execute_module( + changed=True, + commands=["interface Ethernet9/3", "no ip pim bfd-instance"], + ) + + def test_bfd_3(self): + # From enable + self.get_config.return_value = """ + interface Ethernet9/2 + ip pim bfd-instance + """ + # enable -> disabled + set_module_args(dict(interface="Ethernet9/3", bfd="disable")) + self.execute_module( + changed=True, + commands=["interface Ethernet9/3", "ip pim bfd-instance disable"], + ) + + # enable -> enable (idempotence) + set_module_args(dict(interface="Ethernet9/3", bfd="enable")) + self.execute_module(changed=False) + + # enable -> default (None) + set_module_args(dict(interface="Ethernet9/3", bfd="default")) + self.execute_module( + changed=True, + commands=["interface Ethernet9/3", "no ip pim bfd-instance"], + ) + + # enable -> interface state 'default' + set_module_args(dict(interface="Ethernet9/3", state="default")) + self.execute_module( + changed=True, + commands=["interface Ethernet9/3", "no ip pim bfd-instance"], + ) + + # enable -> interface state 'absent' + set_module_args(dict(interface="Ethernet9/3", state="absent")) + self.execute_module( + changed=True, + commands=["interface Ethernet9/3", "no ip pim bfd-instance"], + ) + + def test_bfd_4(self): + self.get_config.return_value = """ + interface Ethernet9/2 + ip pim hello-interval 1000 + """ + # update hello-interval (as milliseconds) + set_module_args( + dict( + interface="Ethernet9/2", + hello_interval=1, + hello_interval_ms=True, + ), + ) + self.execute_module( + changed=True, + commands=["interface Ethernet9/2", "ip pim hello-interval 1"], + ) + + # idempotent (as milliseconds) + set_module_args( + dict( + interface="Ethernet9/2", + hello_interval=1000, + hello_interval_ms=True, + ), + ) + self.execute_module(changed=False, commands=[]) + + # update hello-interval (default seconds) + set_module_args(dict(interface="Ethernet9/2", hello_interval=2)) + self.execute_module( + changed=True, + commands=["interface Ethernet9/2", "ip pim hello-interval 2000"], + ) + + # idempotent (default seconds) + set_module_args(dict(interface="Ethernet9/2", hello_interval=1)) + self.execute_module(changed=False, commands=[]) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_pim_rp_address.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_pim_rp_address.py new file mode 100644 index 00000000..f4dbd13a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_pim_rp_address.py @@ -0,0 +1,70 @@ +# (c) 2016 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from ansible_collections.cisco.nxos.plugins.modules import nxos_pim_rp_address +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, load_fixture, set_module_args + + +class TestNxosPimRpAddressModule(TestNxosModule): + module = nxos_pim_rp_address + + def setUp(self): + super(TestNxosPimRpAddressModule, self).setUp() + + self.mock_load_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_pim_rp_address.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_get_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_pim_rp_address.get_config", + ) + self.get_config = self.mock_get_config.start() + + def tearDown(self): + super(TestNxosPimRpAddressModule, self).tearDown() + self.mock_load_config.stop() + self.mock_get_config.stop() + + def load_fixtures(self, commands=None, device=""): + self.get_config.return_value = load_fixture("nxos_pim_rp_address", "config.cfg") + self.load_config.return_value = None + + def test_nxos_pim_rp_address(self): + set_module_args(dict(rp_address="5.6.7.8")) + self.execute_module(changed=True, commands=["ip pim rp-address 5.6.7.8"]) + + def test_nxos_pim_rp_address_no_change(self): + set_module_args(dict(rp_address="1.2.3.4")) + self.execute_module(changed=False, commands=[]) + + def test_nxos_pim_rp_address_absent(self): + set_module_args(dict(rp_address="1.2.3.4", state="absent")) + self.execute_module(changed=True, commands=["no ip pim rp-address 1.2.3.4"]) + + def test_nxos_pim_rp_address_absent_no_change(self): + set_module_args(dict(rp_address="5.6.7.8", state="absent")) + self.execute_module(changed=False, commands=[]) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_ping.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_ping.py new file mode 100644 index 00000000..73535f89 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_ping.py @@ -0,0 +1,262 @@ +# (c) 2021 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from ansible_collections.cisco.nxos.plugins.modules import nxos_ping +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, set_module_args + + +ignore_provider_arg = True + + +class TestNxosPingModule(TestNxosModule): + """Class used for Unit Tests agains ios_ping module""" + + module = nxos_ping + + def setUp(self): + super(TestNxosPingModule, self).setUp() + self.mock_run_commands = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_ping.run_commands", + ) + self.run_commands = self.mock_run_commands.start() + + def tearDown(self): + super(TestNxosPingModule, self).tearDown() + self.mock_run_commands.stop() + + def test_nxos_ping_expected_success(self): + self.run_commands.return_value = [ + """ + PING 172.28.128.7 (172.28.128.7): 56 data bytes + 64 bytes from 172.28.128.7: icmp_seq=0 ttl=253 time=2.564 ms + 64 bytes from 172.28.128.7: icmp_seq=1 ttl=253 time=4.197 ms + 64 bytes from 172.28.128.7: icmp_seq=2 ttl=253 time=1.597 ms + 64 bytes from 172.28.128.7: icmp_seq=3 ttl=253 time=1.622 ms + 64 bytes from 172.28.128.7: icmp_seq=4 ttl=253 time=1.621 ms + + --- 172.28.128.7 ping statistics --- + 5 packets transmitted, 5 packets received, 0.00% packet loss + round-trip min/avg/max = 1.597/2.32/4.197 ms + """, + ] + set_module_args(dict(dest="172.28.128.7", vrf="management")) + result = self.execute_module() + self.assertEqual(result["commands"], ["ping 172.28.128.7 count 5 vrf management"]) + self.assertEqual(result["packet_loss"], "0.00%") + self.assertEqual(result["packets_rx"], 5) + self.assertEqual(result["packets_tx"], 5) + self.assertEqual(result["rtt"]["min"], 1.597) + self.assertEqual(result["rtt"]["avg"], 2.32) + self.assertEqual(result["rtt"]["max"], 4.197) + + def test_nxos_ping_expected_failure(self): + self.run_commands.return_value = [ + """ + PING 172.28.128.8 (172.28.128.8): 56 data bytes + Request 0 timed out + Request 1 timed out + Request 2 timed out + Request 3 timed out + Request 4 timed out + + --- 172.28.128.8 ping statistics --- + 5 packets transmitted, 0 packets received, 100.00% packet loss + """, + ] + set_module_args(dict(dest="172.28.128.8", vrf="management", state="absent")) + self.execute_module(failed=False) + + def test_nxos_ping_expected_success_but_failed(self): + self.run_commands.return_value = [ + """ + PING 172.28.128.8 (172.28.128.8): 56 data bytes + Request 0 timed out + Request 1 timed out + Request 2 timed out + Request 3 timed out + Request 4 timed out + + --- 172.28.128.8 ping statistics --- + 5 packets transmitted, 0 packets received, 100.00% packet loss + """, + ] + set_module_args(dict(dest="172.28.128.8", vrf="management")) + result = self.execute_module(failed=True) + self.assertEqual(result["msg"], "Ping failed unexpectedly") + + def test_nxos_ping_expected_failure_but_succeeded(self): + self.run_commands.return_value = [ + """ + PING 172.28.128.7 (172.28.128.7): 56 data bytes + 64 bytes from 172.28.128.7: icmp_seq=0 ttl=253 time=2.564 ms + 64 bytes from 172.28.128.7: icmp_seq=1 ttl=253 time=4.197 ms + 64 bytes from 172.28.128.7: icmp_seq=2 ttl=253 time=1.597 ms + 64 bytes from 172.28.128.7: icmp_seq=3 ttl=253 time=1.622 ms + 64 bytes from 172.28.128.7: icmp_seq=4 ttl=253 time=1.621 ms + + --- 172.28.128.7 ping statistics --- + 5 packets transmitted, 5 packets received, 0.00% packet loss + round-trip min/avg/max = 1.597/2.32/4.197 ms + """, + ] + set_module_args(dict(dest="172.28.128.7", vrf="management", state="absent")) + result = self.execute_module(failed=True) + self.assertEqual(result["msg"], "Ping succeeded unexpectedly") + + def test_nxos_ping_expected_success_source(self): + self.run_commands.return_value = [ + """ + PING 172.28.128.7 (172.28.128.7): 56 data bytes + 64 bytes from 172.28.128.7: icmp_seq=0 ttl=253 time=2.564 ms + 64 bytes from 172.28.128.7: icmp_seq=1 ttl=253 time=4.197 ms + 64 bytes from 172.28.128.7: icmp_seq=2 ttl=253 time=1.597 ms + 64 bytes from 172.28.128.7: icmp_seq=3 ttl=253 time=1.622 ms + 64 bytes from 172.28.128.7: icmp_seq=4 ttl=253 time=1.621 ms + + --- 172.28.128.7 ping statistics --- + 5 packets transmitted, 5 packets received, 0.00% packet loss + round-trip min/avg/max = 1.597/2.32/4.197 ms + """, + ] + set_module_args(dict(dest="172.28.128.7", source="192.168.1.10")) + result = self.execute_module() + self.assertEqual( + result["commands"], + ["ping 172.28.128.7 count 5 source 192.168.1.10"], + ) + self.assertEqual(result["packet_loss"], "0.00%") + self.assertEqual(result["packets_rx"], 5) + self.assertEqual(result["packets_tx"], 5) + self.assertEqual(result["rtt"]["min"], 1.597) + self.assertEqual(result["rtt"]["avg"], 2.32) + self.assertEqual(result["rtt"]["max"], 4.197) + + def test_nxos_ping_expected_success_df_bit(self): + self.run_commands.return_value = [ + """ + PING 172.28.128.7 (172.28.128.7): 56 data bytes + 64 bytes from 172.28.128.7: icmp_seq=0 ttl=253 time=2.564 ms + 64 bytes from 172.28.128.7: icmp_seq=1 ttl=253 time=4.197 ms + 64 bytes from 172.28.128.7: icmp_seq=2 ttl=253 time=1.597 ms + 64 bytes from 172.28.128.7: icmp_seq=3 ttl=253 time=1.622 ms + 64 bytes from 172.28.128.7: icmp_seq=4 ttl=253 time=1.621 ms + + --- 172.28.128.7 ping statistics --- + 5 packets transmitted, 5 packets received, 0.00% packet loss + round-trip min/avg/max = 1.597/2.32/4.197 ms + """, + ] + set_module_args(dict(dest="172.28.128.7", df_bit=True)) + result = self.execute_module() + self.assertEqual(result["commands"], ["ping 172.28.128.7 count 5 df-bit"]) + + def test_nxos_ping_expected_success_size(self): + self.run_commands.return_value = [ + """ + PING 172.28.128.7 (172.28.128.7): 56 data bytes + 64 bytes from 172.28.128.7: icmp_seq=0 ttl=253 time=2.564 ms + 64 bytes from 172.28.128.7: icmp_seq=1 ttl=253 time=4.197 ms + 64 bytes from 172.28.128.7: icmp_seq=2 ttl=253 time=1.597 ms + 64 bytes from 172.28.128.7: icmp_seq=3 ttl=253 time=1.622 ms + 64 bytes from 172.28.128.7: icmp_seq=4 ttl=253 time=1.621 ms + + --- 172.28.128.7 ping statistics --- + 5 packets transmitted, 5 packets received, 0.00% packet loss + round-trip min/avg/max = 1.597/2.32/4.197 ms + """, + ] + set_module_args(dict(dest="172.28.128.7", size=65468)) + result = self.execute_module() + self.assertEqual(result["commands"], ["ping 172.28.128.7 count 5 packet-size 65468"]) + + def test_nxos_ping_expected_success_all(self): + self.run_commands.return_value = [ + """ + PING 172.28.128.7 (172.28.128.7): 56 data bytes + 64 bytes from 172.28.128.7: icmp_seq=0 ttl=253 time=2.564 ms + 64 bytes from 172.28.128.7: icmp_seq=1 ttl=253 time=4.197 ms + 64 bytes from 172.28.128.7: icmp_seq=2 ttl=253 time=1.597 ms + 64 bytes from 172.28.128.7: icmp_seq=3 ttl=253 time=1.622 ms + 64 bytes from 172.28.128.7: icmp_seq=4 ttl=253 time=1.621 ms + + --- 172.28.128.7 ping statistics --- + 5 packets transmitted, 5 packets received, 0.00% packet loss + round-trip min/avg/max = 1.597/2.32/4.197 ms + """, + ] + set_module_args( + dict( + dest="172.28.128.7", + count=10, + size=65468, + df_bit=True, + source="192.168.1.1", + vrf="management", + ), + ) + result = self.execute_module() + self.assertEqual( + result["commands"], + [ + "ping 172.28.128.7 count 10 source 192.168.1.1 vrf management packet-size 65468 df-bit", + ], + ) + + def test_nxos_ping_failed_cant_bind(self): + self.run_commands.return_value = [ + """ + ping: can't bind to address 192.168.1.10 + """, + ] + set_module_args( + dict( + dest="172.28.128.7", + count=10, + size=65468, + df_bit=True, + source="192.168.1.1", + vrf="management", + ), + ) + result = self.execute_module(failed=True) + self.assertEqual(result["msg"], "Can't bind to source address.") + + def test_nxos_ping_failed_bad_context(self): + self.run_commands.return_value = [ + """ + ping: bad context site-1 + """, + ] + set_module_args(dict(dest="172.28.128.7", count=10, vrf="site-1")) + result = self.execute_module(failed=True) + self.assertEqual(result["msg"], "Wrong VRF name inserted.") + + def test_nxos_ping_failed_error(self): + """Test for successful pings when destination should be reachable""" + self.run_commands.return_value = [""""""] + set_module_args(dict(dest="172.28.128.7", count=10, vrf="site-1")) + result = self.execute_module(failed=True) + self.assertEqual(result["msg"], "An unexpected error occurred. Check all params.") diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_prefix_lists.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_prefix_lists.py new file mode 100644 index 00000000..d94f0b3e --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_prefix_lists.py @@ -0,0 +1,621 @@ +# (c) 2021 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from textwrap import dedent + +from ansible_collections.cisco.nxos.plugins.modules import nxos_prefix_lists +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, set_module_args + + +ignore_provider_arg = True + + +class TestNxosPrefixListsModule(TestNxosModule): + # Testing strategy + # ------------------ + # (a) The unit tests cover `merged` and `replaced` for every attribute. + # Since `overridden` is essentially `replaced` but at a larger + # scale, these indirectly cover `overridden` as well. + # (b) For linear attributes replaced is not valid and hence, those tests + # delete the attributes from the config subsection. + # (c) The argspec for VRFs is same as the top-level spec and the config logic + # is re-used. Hence, those attributes are not explictly covered. However, a + # combination of VRF + top-level spec + AF is tested. + + module = nxos_prefix_lists + + def setUp(self): + super(TestNxosPrefixListsModule, self).setUp() + + self.mock_get_resource_connection = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module_base.get_resource_connection", + ) + self.get_resource_connection = self.mock_get_resource_connection.start() + + self.mock_get_config = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.facts.prefix_lists.prefix_lists.Prefix_listsFacts.get_config", + ) + self.get_config = self.mock_get_config.start() + + def tearDown(self): + super(TestNxosPrefixListsModule, self).tearDown() + self.get_resource_connection.stop() + self.get_config.stop() + + def test_nxos_prefix_lists_linear_merged(self): + # test merged for linear attributes + self.get_config.return_value = dedent( + """\ + """, + ) + set_module_args( + dict( + config=[ + dict( + afi="ipv4", + prefix_lists=[ + dict( + name="plist1", + description="Test plist1", + entries=[ + dict( + sequence=10, + action="permit", + prefix="192.168.1.0/24", + ), + dict( + sequence=20, + action="deny", + prefix="192.168.2.0/24", + mask="255.255.255.0", + ), + ], + ), + dict( + name="plist2", + entries=[ + dict( + sequence=20, + action="permit", + prefix="10.0.0.0/8", + eq=8, + ), + dict( + sequence=50, + action="deny", + prefix="10.0.0.8/24", + ge=25, + ), + ], + ), + ], + ), + dict( + afi="ipv6", + prefix_lists=[ + dict( + name="plist3", + description="Test plist3", + entries=[ + dict( + sequence=10, + action="deny", + prefix="2001:db8:1000::/36", + le=36, + ), + dict( + sequence=20, + action="permit", + prefix="2001:db8:2000::/36", + ), + ], + ), + dict( + name="plist4", + entries=[ + dict( + sequence=20, + action="permit", + prefix="2001:db8:3000::/36", + ), + dict( + sequence=50, + action="deny", + prefix="2001:db8:4000::/36", + ), + ], + ), + ], + ), + ], + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "ip prefix-list plist1 description Test plist1", + "ip prefix-list plist1 seq 10 permit 192.168.1.0/24", + "ip prefix-list plist1 seq 20 deny 192.168.2.0/24 mask 255.255.255.0", + "ip prefix-list plist2 seq 20 permit 10.0.0.0/8 eq 8", + "ip prefix-list plist2 seq 50 deny 10.0.0.8/24 ge 25", + "ipv6 prefix-list plist3 description Test plist3", + "ipv6 prefix-list plist3 seq 10 deny 2001:db8:1000::/36 le 36", + "ipv6 prefix-list plist3 seq 20 permit 2001:db8:2000::/36", + "ipv6 prefix-list plist4 seq 20 permit 2001:db8:3000::/36", + "ipv6 prefix-list plist4 seq 50 deny 2001:db8:4000::/36", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_prefix_lists_linear_merged_idempotent(self): + # test merged for linear attributes (idempotent) + self.get_config.return_value = dedent( + """\ + ip prefix-list plist1 description Test plist1 + ip prefix-list plist1 seq 10 permit 192.168.1.0/24 + ip prefix-list plist1 seq 20 deny 192.168.2.0/24 mask 255.255.255.0 + ip prefix-list plist2 seq 20 permit 10.0.0.0/8 eq 8 + ip prefix-list plist2 seq 50 deny 10.0.0.8/24 ge 25 + ipv6 prefix-list plist3 description Test plist3 + ipv6 prefix-list plist3 seq 10 deny 2001:db8:1000::/36 le 36 + ipv6 prefix-list plist3 seq 20 permit 2001:db8:2000::/36 + ipv6 prefix-list plist4 seq 20 permit 2001:db8:3000::/36 + ipv6 prefix-list plist4 seq 50 deny 2001:db8:4000::/36 + """, + ) + set_module_args( + dict( + config=[ + dict( + afi="ipv4", + prefix_lists=[ + dict( + name="plist1", + description="Test plist1", + entries=[ + dict( + sequence=10, + action="permit", + prefix="192.168.1.0/24", + ), + dict( + sequence=20, + action="deny", + prefix="192.168.2.0/24", + mask="255.255.255.0", + ), + ], + ), + dict( + name="plist2", + entries=[ + dict( + sequence=20, + action="permit", + prefix="10.0.0.0/8", + eq=8, + ), + dict( + sequence=50, + action="deny", + prefix="10.0.0.8/24", + ge=25, + ), + ], + ), + ], + ), + dict( + afi="ipv6", + prefix_lists=[ + dict( + name="plist3", + description="Test plist3", + entries=[ + dict( + sequence=10, + action="deny", + prefix="2001:db8:1000::/36", + le=36, + ), + dict( + sequence=20, + action="permit", + prefix="2001:db8:2000::/36", + ), + ], + ), + dict( + name="plist4", + entries=[ + dict( + sequence=20, + action="permit", + prefix="2001:db8:3000::/36", + ), + dict( + sequence=50, + action="deny", + prefix="2001:db8:4000::/36", + ), + ], + ), + ], + ), + ], + state="merged", + ), + ignore_provider_arg, + ) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_prefix_lists_merged_update(self): + # test existing sequence with merged (should fail) + self.get_config.return_value = dedent( + """\ + ip prefix-list plist1 description Test plist1 + ip prefix-list plist1 seq 10 permit 192.168.1.0/24 + ip prefix-list plist1 seq 20 deny 192.168.2.0/24 mask 255.255.255.0 + ip prefix-list plist2 seq 20 permit 10.0.0.0/8 eq 8 + ip prefix-list plist2 seq 50 deny 10.0.0.8/24 ge 25 + ipv6 prefix-list plist3 description Test plist3 + ipv6 prefix-list plist3 seq 10 deny 2001:db8:1000::/36 le 36 + ipv6 prefix-list plist3 seq 20 permit 2001:db8:2000::/36 + ipv6 prefix-list plist4 seq 20 permit 2001:db8:3000::/36 + ipv6 prefix-list plist4 seq 50 deny 2001:db8:4000::/36 + """, + ) + set_module_args( + dict( + config=[ + dict( + afi="ipv4", + prefix_lists=[ + dict( + name="plist1", + description="Test plist1", + entries=[ + dict( + sequence=10, + action="permit", + prefix="192.168.8.0/24", + ), + ], + ), + ], + ), + ], + state="merged", + ), + ignore_provider_arg, + ) + result = self.execute_module(failed=True) + self.assertEqual( + result["msg"], + "Cannot update existing sequence 10 of prefix list plist1 with state merged." + " Please use state replaced or overridden.", + ) + + def test_nxos_prefix_lists_replaced_update(self): + # test existing sequence with replaced + self.get_config.return_value = dedent( + """\ + ip prefix-list plist1 description Test plist1 + ip prefix-list plist1 seq 10 permit 192.168.1.0/24 + ip prefix-list plist1 seq 20 deny 192.168.2.0/24 mask 255.255.255.0 + ip prefix-list plist2 seq 20 permit 10.0.0.0/8 eq 8 + ip prefix-list plist2 seq 50 deny 10.0.0.8/24 ge 25 + ipv6 prefix-list plist3 description Test plist3 + ipv6 prefix-list plist3 seq 10 deny 2001:db8:1000::/36 le 36 + ipv6 prefix-list plist3 seq 20 permit 2001:db8:2000::/36 + ipv6 prefix-list plist4 seq 20 permit 2001:db8:3000::/36 + ipv6 prefix-list plist4 seq 50 deny 2001:db8:4000::/36 + """, + ) + set_module_args( + dict( + config=[ + dict( + afi="ipv4", + prefix_lists=[ + dict( + name="plist1", + description="Test plist1", + entries=[ + dict( + sequence=10, + action="permit", + prefix="192.168.8.0/24", + ), + dict( + sequence=20, + action="deny", + prefix="192.168.2.0/24", + mask="255.255.255.0", + ), + ], + ), + ], + ), + ], + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "no ip prefix-list plist1 seq 10 permit 192.168.1.0/24", + "ip prefix-list plist1 seq 10 permit 192.168.8.0/24", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_prefix_lists_replaced(self): + # test replaced + self.get_config.return_value = dedent( + """\ + ip prefix-list plist1 description Test plist1 + ip prefix-list plist1 seq 10 permit 192.168.1.0/24 + ip prefix-list plist1 seq 20 deny 192.168.2.0/24 mask 255.255.255.0 + ip prefix-list plist2 seq 20 permit 10.0.0.0/8 eq 8 + ip prefix-list plist2 seq 50 deny 10.0.0.8/24 ge 25 + ipv6 prefix-list plist3 description Test plist3 + ipv6 prefix-list plist3 seq 10 deny 2001:db8:1000::/36 le 36 + ipv6 prefix-list plist3 seq 20 permit 2001:db8:2000::/36 + ipv6 prefix-list plist4 seq 20 permit 2001:db8:3000::/36 + ipv6 prefix-list plist4 seq 50 deny 2001:db8:4000::/36 + """, + ) + set_module_args( + dict( + config=[ + dict( + afi="ipv4", + prefix_lists=[ + dict( + name="plist1", + entries=[ + dict( + sequence=10, + action="permit", + prefix="192.168.8.0/24", + ), + ], + ), + ], + ), + ], + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "no ip prefix-list plist1 description Test plist1", + "no ip prefix-list plist1 seq 20 deny 192.168.2.0/24 mask 255.255.255.0", + "no ip prefix-list plist1 seq 10 permit 192.168.1.0/24", + "ip prefix-list plist1 seq 10 permit 192.168.8.0/24", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_prefix_lists_overridden(self): + # test overridden + self.get_config.return_value = dedent( + """\ + ip prefix-list plist1 description Test plist1 + ip prefix-list plist1 seq 10 permit 192.168.1.0/24 + ip prefix-list plist1 seq 20 deny 192.168.2.0/24 mask 255.255.255.0 + ip prefix-list plist2 seq 20 permit 10.0.0.0/8 eq 8 + ip prefix-list plist2 seq 50 deny 10.0.0.8/24 ge 25 + ipv6 prefix-list plist3 description Test plist3 + ipv6 prefix-list plist3 seq 10 deny 2001:db8:1000::/36 le 36 + ipv6 prefix-list plist3 seq 20 permit 2001:db8:2000::/36 + ipv6 prefix-list plist4 seq 20 permit 2001:db8:3000::/36 + ipv6 prefix-list plist4 seq 50 deny 2001:db8:4000::/36 + """, + ) + set_module_args( + dict( + config=[ + dict( + afi="ipv4", + prefix_lists=[ + dict( + name="plist1", + entries=[ + dict( + sequence=10, + action="permit", + prefix="192.168.8.0/24", + ), + ], + ), + ], + ), + ], + state="overridden", + ), + ignore_provider_arg, + ) + commands = [ + "no ip prefix-list plist1 description Test plist1", + "no ip prefix-list plist1 seq 20 deny 192.168.2.0/24 mask 255.255.255.0", + "no ip prefix-list plist1 seq 10 permit 192.168.1.0/24", + "ip prefix-list plist1 seq 10 permit 192.168.8.0/24", + "no ipv6 prefix-list plist4", + "no ip prefix-list plist2", + "no ipv6 prefix-list plist3", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_prefix_lists_deleted_afi(self): + # test deleted (AFI) + self.get_config.return_value = dedent( + """\ + ip prefix-list plist1 description Test plist1 + ip prefix-list plist1 seq 10 permit 192.168.1.0/24 + ip prefix-list plist1 seq 20 deny 192.168.2.0/24 mask 255.255.255.0 + ip prefix-list plist2 seq 20 permit 10.0.0.0/8 eq 8 + ip prefix-list plist2 seq 50 deny 10.0.0.8/24 ge 25 + ipv6 prefix-list plist3 description Test plist3 + ipv6 prefix-list plist3 seq 10 deny 2001:db8:1000::/36 le 36 + ipv6 prefix-list plist3 seq 20 permit 2001:db8:2000::/36 + ipv6 prefix-list plist4 seq 20 permit 2001:db8:3000::/36 + ipv6 prefix-list plist4 seq 50 deny 2001:db8:4000::/36 + """, + ) + set_module_args( + dict(config=[dict(afi="ipv4")], state="deleted"), + ignore_provider_arg, + ) + commands = ["no ip prefix-list plist1", "no ip prefix-list plist2"] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_prefix_lists_deleted_prefix_list(self): + # test deleted (prefix-list) + self.get_config.return_value = dedent( + """\ + ip prefix-list plist1 description Test plist1 + ip prefix-list plist1 seq 10 permit 192.168.1.0/24 + ip prefix-list plist1 seq 20 deny 192.168.2.0/24 mask 255.255.255.0 + ip prefix-list plist2 seq 20 permit 10.0.0.0/8 eq 8 + ip prefix-list plist2 seq 50 deny 10.0.0.8/24 ge 25 + ipv6 prefix-list plist3 description Test plist3 + ipv6 prefix-list plist3 seq 10 deny 2001:db8:1000::/36 le 36 + ipv6 prefix-list plist3 seq 20 permit 2001:db8:2000::/36 + ipv6 prefix-list plist4 seq 20 permit 2001:db8:3000::/36 + ipv6 prefix-list plist4 seq 50 deny 2001:db8:4000::/36 + """, + ) + set_module_args( + dict( + config=[dict(afi="ipv6", prefix_lists=[dict(name="plist3")])], + state="deleted", + ), + ignore_provider_arg, + ) + commands = ["no ipv6 prefix-list plist3"] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_prefix_lists_deleted_all(self): + # test deleted + self.get_config.return_value = dedent( + """\ + ip prefix-list plist1 description Test plist1 + ip prefix-list plist1 seq 10 permit 192.168.1.0/24 + ip prefix-list plist1 seq 20 deny 192.168.2.0/24 mask 255.255.255.0 + ip prefix-list plist2 seq 20 permit 10.0.0.0/8 eq 8 + ip prefix-list plist2 seq 50 deny 10.0.0.8/24 ge 25 + ipv6 prefix-list plist3 description Test plist3 + ipv6 prefix-list plist3 seq 10 deny 2001:db8:1000::/36 le 36 + ipv6 prefix-list plist3 seq 20 permit 2001:db8:2000::/36 + ipv6 prefix-list plist4 seq 20 permit 2001:db8:3000::/36 + ipv6 prefix-list plist4 seq 50 deny 2001:db8:4000::/36 + """, + ) + set_module_args(dict(state="deleted"), ignore_provider_arg) + commands = [ + "no ip prefix-list plist1", + "no ip prefix-list plist2", + "no ipv6 prefix-list plist3", + "no ipv6 prefix-list plist4", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_prefix_lists_parsed(self): + # test parsed + cfg = dedent( + """\ + ip prefix-list plist1 description Test plist1 + ipv6 prefix-list plist3 description Test plist3 + """, + ) + set_module_args(dict(running_config=cfg, state="parsed"), ignore_provider_arg) + parsed = [ + { + "afi": "ipv4", + "prefix_lists": [{"name": "plist1", "description": "Test plist1"}], + }, + { + "afi": "ipv6", + "prefix_lists": [{"name": "plist3", "description": "Test plist3"}], + }, + ] + result = self.execute_module(changed=False) + self.assertEqual(result["parsed"], parsed) + + def test_nxos_prefix_lists_gathered(self): + # test gathered + self.get_config.return_value = dedent( + """\ + ip prefix-list plist1 description Test plist1 + ip prefix-list plist1 seq 20 deny 192.168.2.0/24 mask 255.255.255.0 + ipv6 prefix-list plist3 description Test plist3 + ipv6 prefix-list plist3 seq 50 deny 2001:db8:4000::/36 + """, + ) + set_module_args(dict(state="gathered"), ignore_provider_arg) + gathered = [ + { + "afi": "ipv4", + "prefix_lists": [ + { + "name": "plist1", + "description": "Test plist1", + "entries": [ + { + "sequence": 20, + "action": "deny", + "prefix": "192.168.2.0/24", + "mask": "255.255.255.0", + }, + ], + }, + ], + }, + { + "afi": "ipv6", + "prefix_lists": [ + { + "name": "plist3", + "description": "Test plist3", + "entries": [ + { + "sequence": 50, + "action": "deny", + "prefix": "2001:db8:4000::/36", + }, + ], + }, + ], + }, + ] + result = self.execute_module(changed=False) + self.assertEqual(result["gathered"], gathered) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_route_maps.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_route_maps.py new file mode 100644 index 00000000..aae0699a --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_route_maps.py @@ -0,0 +1,1013 @@ +# (c) 2020 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from textwrap import dedent + +from ansible_collections.cisco.nxos.plugins.modules import nxos_route_maps +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, set_module_args + + +ignore_provider_arg = True + + +class TestNxosRouteMapsModule(TestNxosModule): + # Testing strategy + # ------------------ + # (a) The unit tests cover `merged` and `replaced` for every attribute. + # Since `overridden` is essentially `replaced` but at a larger + # scale, these indirectly cover `overridden` as well. + # (b) For linear attributes replaced is not valid and hence, those tests + # delete the attributes from the config subsection. + # (c) The argspec for VRFs is same as the top-level spec and the config logic + # is re-used. Hence, those attributes are not explictly covered. However, a + # combination of VRF + top-level spec + AF is tested. + + module = nxos_route_maps + + def setUp(self): + super(TestNxosRouteMapsModule, self).setUp() + + self.mock_get_resource_connection = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module_base.get_resource_connection", + ) + self.get_resource_connection = self.mock_get_resource_connection.start() + + self.mock_get_config = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.facts.route_maps.route_maps.Route_mapsFacts.get_config", + ) + self.get_config = self.mock_get_config.start() + + def tearDown(self): + super(TestNxosRouteMapsModule, self).tearDown() + self.get_resource_connection.stop() + self.get_config.stop() + + def test_nxos_route_maps_linear_merged(self): + # test merged for linear attributes + self.get_config.return_value = dedent( + """\ + """, + ) + set_module_args( + dict( + config=[ + dict( + route_map="rmap1", + entries=[ + dict( + action="permit", + sequence=10, + description="rmap1-permit-10", + continue_sequence=30, + ), + dict( + action="deny", + sequence=40, + description="rmap1-deny-40", + set=dict( + as_path=dict(prepend=dict(last_as=10), tag=True), + comm_list="comm1", + dampening=dict( + half_life=10, + start_reuse_route=20, + start_suppress_route=30, + max_suppress_time=80, + ), + extcomm_list="extcomm1", + forwarding_address=True, + ), + ), + ], + ), + dict( + route_map="rmap2", + entries=[ + dict( + sequence=10, + action="permit", + set=dict( + null_interface="null0", + ip=dict( + address=dict(prefix_list="prefixlist1"), + precedence="critical", + ), + ipv6=dict( + address=dict(prefix_list="prefixlist2"), + precedence="immediate", + ), + label_index=20, + level="level-1", + local_preference=200, + metric=dict( + bandwidth=1000, + igrp_delay_metric=90, + igrp_reliability_metric=80, + igrp_effective_bandwidth_metric=100, + igrp_mtu=900, + ), + metric_type="external", + nssa_only=True, + origin="egp", + path_selection="all", + tag=10, + weight=40, + ), + ), + ], + ), + ], + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "route-map rmap1 permit 10", + "description rmap1-permit-10", + "continue 30", + "route-map rmap1 deny 40", + "description rmap1-deny-40", + "set as-path prepend last-as 10", + "set as-path tag", + "set comm-list comm1 delete", + "set dampening 10 20 30 80", + "set extcomm-list extcomm1 delete", + "set forwarding-address", + "route-map rmap2 permit 10", + "set interface null0", + "set ip address prefix-list prefixlist1", + "set ip precedence critical", + "set ipv6 address prefix-list prefixlist2", + "set ipv6 precedence immediate", + "set label-index 20", + "set level level-1", + "set local-preference 200", + "set metric 1000 90 80 100 900", + "set metric-type external", + "set nssa-only", + "set origin egp", + "set path-selection all advertise", + "set tag 10", + "set weight 40", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_route_maps_linear_merged_idempotent(self): + # test merged for linear attributes + self.get_config.return_value = dedent( + """\ + route-map rmap1 permit 10 + description rmap1-permit-10 + continue 30 + route-map rmap1 deny 40 + description rmap1-deny-40 + set as-path prepend last-as 10 + set as-path tag + set comm-list comm1 delete + set dampening 10 20 30 80 + set extcomm-list extcomm1 delete + set forwarding-address + route-map rmap2 permit 10 + description rmap1-deny-40 + set interface null0 + set ip address prefix-list prefixlist1 + set ip precedence critical + set ipv6 address prefix-list prefixlist2 + set ipv6 precedence immediate + set label-index 20 + set level level-1 + set local-preference 200 + set metric 1000 90 80 100 900 + set metric-type external + set nssa-only + set origin egp + set path-selection all advertise + set tag 10 + set weight 40 + """, + ) + set_module_args( + dict( + config=[ + dict( + route_map="rmap1", + entries=[ + dict( + action="permit", + sequence=10, + description="rmap1-permit-10", + continue_sequence=30, + ), + dict( + action="deny", + sequence=40, + description="rmap1-deny-40", + set=dict( + as_path=dict(prepend=dict(last_as=10), tag=True), + comm_list="comm1", + dampening=dict( + half_life=10, + start_reuse_route=20, + start_suppress_route=30, + max_suppress_time=80, + ), + extcomm_list="extcomm1", + forwarding_address=True, + ), + ), + ], + ), + dict( + route_map="rmap2", + entries=[ + dict( + sequence=10, + action="permit", + set=dict( + null_interface="null0", + ip=dict( + address=dict(prefix_list="prefixlist1"), + precedence="critical", + ), + ipv6=dict( + address=dict(prefix_list="prefixlist2"), + precedence="immediate", + ), + label_index=20, + level="level-1", + local_preference=200, + metric=dict( + bandwidth=1000, + igrp_delay_metric=90, + igrp_reliability_metric=80, + igrp_effective_bandwidth_metric=100, + igrp_mtu=900, + ), + metric_type="external", + nssa_only=True, + origin="egp", + path_selection="all", + tag=10, + weight=40, + ), + ), + ], + ), + ], + state="merged", + ), + ignore_provider_arg, + ) + commands = [] + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], commands) + + def test_nxos_route_maps_linear_replaced(self): + # test replaced for linear attributes + self.get_config.return_value = dedent( + """\ + route-map rmap1 permit 10 + description rmap1-permit-10 + continue 30 + route-map rmap1 deny 40 + description rmap1-deny-40 + set as-path prepend last-as 10 + set as-path tag + set comm-list comm1 delete + set dampening 10 20 30 80 + set extcomm-list extcomm1 delete + set forwarding-address + route-map rmap2 permit 10 + description rmap1-deny-40 + set interface null0 + set ip address prefix-list prefixlist1 + set ip precedence critical + set ipv6 address prefix-list prefixlist2 + set ipv6 precedence immediate + set label-index 20 + set level level-1 + set local-preference 200 + set metric 1000 90 80 100 900 + set metric-type external + set nssa-only + set origin egp + set path-selection all advertise + set tag 10 + set weight 40 + """, + ) + set_module_args( + dict( + config=[ + dict( + route_map="rmap1", + entries=[ + dict( + action="permit", + sequence=10, + description="rmap1-permit-10", + continue_sequence=40, + ), + dict( + action="deny", + sequence=40, + description="rmap1-deny-40-2", + set=dict( + extcomm_list="extcomm2", + forwarding_address=True, + ), + ), + ], + ), + dict(route_map="rmap2"), + dict( + route_map="rmap3", + entries=[ + dict( + sequence=11, + action="deny", + set=dict( + ip=dict( + address=dict(prefix_list="prefixlist1"), + precedence="critical", + ), + ), + ), + ], + ), + ], + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "no route-map rmap2 permit 10", + "route-map rmap1 permit 10", + "continue 40", + "route-map rmap1 deny 40", + "description rmap1-deny-40-2", + "no set as-path prepend last-as 10", + "no set as-path tag", + "no set comm-list comm1 delete", + "no set dampening 10 20 30 80", + "set extcomm-list extcomm2 delete", + "route-map rmap3 deny 11", + "set ip address prefix-list prefixlist1", + "set ip precedence critical", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_route_maps_parsed(self): + # test parsed + set_module_args( + dict( + running_config=dedent( + """\ + route-map rmap1 permit 10 + description rmap1-permit-10 + continue 30 + route-map rmap1 deny 40 + description rmap1-deny-40 + set as-path prepend last-as 10 + set as-path tag + route-map rmap2 permit 10 + description rmap1-deny-40 + set interface null0 + set ip address prefix-list prefixlist1 + set ip precedence critical + set ipv6 address prefix-list prefixlist2 + set ipv6 precedence immediate + """, + ), + state="parsed", + ), + ignore_provider_arg, + ) + + parsed = [ + dict( + route_map="rmap1", + entries=[ + dict( + action="permit", + sequence=10, + description="rmap1-permit-10", + continue_sequence=30, + ), + dict( + action="deny", + sequence=40, + description="rmap1-deny-40", + set=dict(as_path=dict(prepend=dict(last_as=10), tag=True)), + ), + ], + ), + dict( + route_map="rmap2", + entries=[ + dict( + sequence=10, + action="permit", + set=dict( + null_interface="null0", + ip=dict( + address=dict(prefix_list="prefixlist1"), + precedence="critical", + ), + ipv6=dict( + address=dict(prefix_list="prefixlist2"), + precedence="immediate", + ), + ), + ), + ], + ), + ] + + result = self.execute_module(changed=False) + self.assertEqual(set(result["parsed"][0]), set(parsed[0])) + self.assertEqual(set(result["parsed"][1]), set(parsed[1])) + + def test_nxos_route_maps_gathered(self): + # test parsed + self.get_config.return_value = dedent( + """\ + route-map rmap1 permit 10 + description rmap1-permit-10 + continue 30 + route-map rmap1 deny 40 + description rmap1-deny-40 + set as-path prepend last-as 10 + set as-path tag + route-map rmap2 permit 10 + description rmap1-deny-40 + set interface null0 + set ip address prefix-list prefixlist1 + set ip precedence critical + set ipv6 address prefix-list prefixlist2 + set ipv6 precedence immediate + """, + ) + set_module_args(dict(state="gathered"), ignore_provider_arg) + + gathered = [ + dict( + route_map="rmap1", + entries=[ + dict( + action="permit", + sequence=10, + description="rmap1-permit-10", + continue_sequence=30, + ), + dict( + action="deny", + sequence=40, + description="rmap1-deny-40", + set=dict(as_path=dict(prepend=dict(last_as=10), tag=True)), + ), + ], + ), + dict( + route_map="rmap2", + entries=[ + dict( + sequence=10, + action="permit", + set=dict( + null_interface="null0", + ip=dict( + address=dict(prefix_list="prefixlist1"), + precedence="critical", + ), + ipv6=dict( + address=dict(prefix_list="prefixlist2"), + precedence="immediate", + ), + ), + ), + ], + ), + ] + + result = self.execute_module(changed=False) + self.assertEqual(set(result["gathered"][0]), set(gathered[0])) + self.assertEqual(set(result["gathered"][1]), set(gathered[1])) + + def test_nxos_route_maps_rendered(self): + # test rendered + set_module_args( + dict( + config=[ + dict( + route_map="rmap1", + entries=[ + dict( + action="permit", + sequence=10, + description="rmap1-permit-10", + continue_sequence=40, + ), + dict( + action="deny", + sequence=40, + description="rmap1-deny-40-2", + set=dict( + extcomm_list="extcomm2", + forwarding_address=True, + ), + ), + ], + ), + dict( + route_map="rmap3", + entries=[ + dict( + sequence=11, + action="deny", + set=dict( + ip=dict( + address=dict(prefix_list="prefixlist1"), + precedence="critical", + ), + ), + ), + ], + ), + ], + state="rendered", + ), + ignore_provider_arg, + ) + rendered = [ + "route-map rmap1 permit 10", + "description rmap1-permit-10", + "continue 40", + "route-map rmap1 deny 40", + "description rmap1-deny-40-2", + "set extcomm-list extcomm2 delete", + "set forwarding-address", + "route-map rmap3 deny 11", + "set ip address prefix-list prefixlist1", + "set ip precedence critical", + ] + result = self.execute_module(changed=False) + self.assertEqual(set(result["rendered"]), set(rendered)) + + def test_nxos_route_maps_overridden(self): + # test overridden + self.get_config.return_value = dedent( + """\ + route-map rmap1 permit 10 + description rmap1-permit-10 + continue 30 + route-map rmap1 deny 40 + description rmap1-deny-40 + set as-path prepend last-as 10 + set as-path tag + route-map rmap2 permit 10 + description rmap2-permit-10 + set interface null0 + route-map rmap2 permit 11 + description rmap2-permit-11 + route-map rmap3 permit 21 + description rmap3-permit-21 + route-map rmap3 permit 22 + description rmap3-permit-21 + """, + ) + set_module_args( + dict( + config=[ + dict( + route_map="rmap1", + entries=[ + dict( + action="permit", + sequence=10, + description="rmap1-permit-10", + continue_sequence=30, + ), + dict( + action="deny", + sequence=40, + description="rmap1-deny-40", + set=dict( + ipv6=dict( + address=dict(prefix_list="prefixlist2"), + precedence="immediate", + ), + ), + ), + ], + ), + dict( + route_map="rmap2", + entries=[ + dict( + sequence=10, + action="permit", + description="rmap2-permit-10", + set=dict(null_interface="null0"), + ), + ], + ), + ], + state="overridden", + ), + ignore_provider_arg, + ) + commands = [ + "no route-map rmap3 permit 21", + "no route-map rmap3 permit 22", + "no route-map rmap2 permit 11", + "route-map rmap1 deny 40", + "no set as-path prepend last-as 10", + "no set as-path tag", + "set ipv6 address prefix-list prefixlist2", + "set ipv6 precedence immediate", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_route_maps_deleted_1(self): + # test deleted - single route-map + self.get_config.return_value = dedent( + """\ + route-map rmap1 permit 10 + description rmap1-permit-10 + continue 30 + route-map rmap1 deny 40 + description rmap1-deny-40 + set as-path prepend last-as 10 + set as-path tag + route-map rmap2 permit 10 + description rmap2-permit-10 + set interface null0 + route-map rmap2 permit 11 + description rmap2-permit-11 + route-map rmap3 permit 21 + description rmap3-permit-21 + route-map rmap3 permit 22 + description rmap3-permit-21 + """, + ) + set_module_args( + dict(config=[dict(route_map="rmap1")], state="deleted"), + ignore_provider_arg, + ) + commands = [ + "no route-map rmap1 permit 10", + "no route-map rmap1 deny 40", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_route_maps_deleted_2(self): + # test deleted - all route-maps + self.get_config.return_value = dedent( + """\ + route-map rmap1 permit 10 + description rmap1-permit-10 + continue 30 + route-map rmap1 deny 40 + description rmap1-deny-40 + set as-path prepend last-as 10 + set as-path tag + route-map rmap2 permit 10 + description rmap2-permit-10 + set interface null0 + route-map rmap2 permit 11 + description rmap2-permit-11 + route-map rmap3 permit 21 + description rmap3-permit-21 + route-map rmap3 permit 22 + description rmap3-permit-21 + """, + ) + set_module_args(dict(state="deleted"), ignore_provider_arg) + commands = [ + "no route-map rmap1 permit 10", + "no route-map rmap1 deny 40", + "no route-map rmap2 permit 10", + "no route-map rmap2 permit 11", + "no route-map rmap3 permit 21", + "no route-map rmap3 permit 22", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_route_maps_complex_merged(self): + # test merged for complex attributes + self.get_config.return_value = dedent( + """\ + """, + ) + set_module_args( + dict( + config=[ + dict( + route_map="rmap1", + entries=[ + dict( + action="permit", + sequence=10, + match=dict( + as_number=dict( + asn=["64455", "65546"], + as_path_list=["acl1", "acl2"], + ), + as_path=["65565", "65578", "65590"], + community=dict(community_list=["comm1", "comm2"]), + evpn=dict(route_types=["1", "2-mac-ip"]), + extcommunity=dict( + extcommunity_list=[ + "extcomm1", + "extcomm2", + ], + ), + interfaces=["Ethernet1/1", "Ethernet1/2"], + ip=dict( + address=dict( + access_list="acl1", + prefix_lists=["pl1", "pl2", "pl3"], + ), + multicast=dict( + group=dict(prefix="239.0.0.1/24"), + rp=dict( + prefix="209.165.201.0/27", + rp_type="Bidir", + ), + source="192.168.1.0/24", + ), + next_hop=dict(prefix_lists=["pl1", "pl2"]), + route_source=dict(prefix_lists=["pl3", "pl4"]), + ), + mac_list=["mac1", "mac2"], + metric=[100, 200], + ospf_area=[200, 300], + route_types=["external", "inter-area"], + source_protocol=["eigrp", "ospf"], + tags=[10, 200], + ), + ), + dict( + action="permit", + sequence=20, + match=dict( + ipv6=dict( + address=dict( + access_list="acl1", + prefix_lists=["pl1", "pl2", "pl3"], + ), + multicast=dict( + group=dict(prefix="239.0.0.1/24"), + rp=dict( + prefix="209.165.201.0/27", + rp_type="Bidir", + ), + source="192.168.1.0/24", + ), + next_hop=dict(prefix_lists=["pl1", "pl2"]), + route_source=dict(prefix_lists=["pl3", "pl4"]), + ), + ), + ), + dict( + sequence=40, + action="permit", + set=dict( + as_path=dict(prepend=dict(as_number=["65546", "78878"])), + distance=dict( + igp_ebgp_routes=10, + internal_routes=20, + local_routes=90, + ), + evpn=dict(gateway_ip=dict(ip="192.168.1.1")), + ), + ), + dict( + sequence=52, + action="permit", + set=dict( + evpn=dict(gateway_ip=dict(use_nexthop=True)), + community=dict( + internet=True, + number=["655:10", "655:20"], + no_export=True, + no_advertise=True, + local_as=True, + graceful_shutdown=True, + additive=True, + ), + ), + ), + ], + ), + ], + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "route-map rmap1 permit 10", + "match as-number as-path-list acl1 acl2", + "match as-number 64455, 65546", + "match as-path 65565 65578 65590", + "match community comm1 comm2", + "match evpn route-type 1 2-mac-ip", + "match extcommunity extcomm1 extcomm2", + "match interface Ethernet1/1 Ethernet1/2", + "match ip address acl1", + "match ip address prefix-list pl1 pl2 pl3", + "match ip multicast source 192.168.1.0/24 group 239.0.0.1/24 rp 209.165.201.0/27 rp-type Bidir", + "match ip next-hop prefix-list pl1 pl2", + "match ip route-source prefix-list pl3 pl4", + "match mac-list mac1 mac2", + "match metric 100 200", + "match ospf-area 200 300", + "match route-type external inter-area", + "match source-protocol eigrp ospf", + "match tag 10 200", + "route-map rmap1 permit 20", + "match ipv6 address acl1", + "match ipv6 address prefix-list pl1 pl2 pl3", + "match ipv6 multicast source 192.168.1.0/24 group 239.0.0.1/24 rp 209.165.201.0/27 rp-type Bidir", + "match ipv6 next-hop prefix-list pl1 pl2", + "match ipv6 route-source prefix-list pl3 pl4", + "route-map rmap1 permit 40", + "set as-path prepend 65546 78878", + "set distance 10 20 90", + "set evpn gateway-ip 192.168.1.1", + "route-map rmap1 permit 52", + "set community internet 655:10 655:20 no-export no-advertise local-AS graceful-shutdown additive", + "set evpn gateway-ip use-nexthop", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_route_maps_complex_merged_2(self): + # test merged for complex attributes + self.get_config.return_value = dedent( + """\ + """, + ) + set_module_args( + dict( + config=[ + dict( + route_map="rmap1", + entries=[ + dict( + action="permit", + sequence=10, + match=dict( + ip=dict( + multicast=dict( + group_range=dict( + first="239.0.0.1", + last="239.255.255.255", + ), + rp=dict( + prefix="209.165.201.0/27", + rp_type="Bidir", + ), + source="192.168.1.0/24", + ), + ), + ipv6=dict( + multicast=dict( + group_range=dict( + first="fd00:80::", + last="fd00:ff:ffff:ffff::", + ), + rp=dict( + prefix="fd00:280::/25", + rp_type="Bidir", + ), + source="2001:db8:2000::/36", + ), + ), + ), + set=dict( + metric=dict( + bandwidth=1000, + igrp_delay_metric=90, + igrp_reliability_metric=80, + igrp_effective_bandwidth_metric=100, + ), + ), + ), + ], + ), + ], + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "route-map rmap1 permit 10", + "match ip multicast source 192.168.1.0/24 group-range 239.0.0.1 to 239.255.255.255 rp 209.165.201.0/27 rp-type Bidir", + "match ipv6 multicast source 2001:db8:2000::/36 group-range fd00:80:: to fd00:ff:ffff:ffff:: rp fd00:280::/25 rp-type Bidir", + "set metric 1000 90 80 100", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_route_maps_complex_replaced(self): + # test replaced for complex attributes + self.get_config.return_value = dedent( + """\ + route-map rmap1 permit 10 + match ip address prefix-list pl1 pl2 pl3 + match ip multicast source 192.168.1.0/24 group-range 239.0.0.1 to 239.255.255.255 rp 209.165.201.0/27 rp-type Bidir + match ipv6 multicast source 2001:db8:2000::/36 group-range fd00:80:: to fd00:ff:ffff:ffff:: rp fd00:280::/25 rp-type Bidir + """, + ) + set_module_args( + dict( + config=[ + dict( + route_map="rmap1", + entries=[ + dict( + action="permit", + sequence=10, + match=dict( + ip=dict( + address=dict(prefix_lists=["pl4"]), + multicast=dict( + group=dict(prefix="239.0.0.1/24"), + rp=dict( + prefix="209.165.201.0/27", + rp_type="Bidir", + ), + source="192.168.1.0/24", + ), + ), + ipv6=dict( + multicast=dict( + group_range=dict( + first="fd00:80::", + last="fd00:ff:ffff:ffff::", + ), + rp=dict( + prefix="fd00:280::/25", + rp_type="Bidir", + ), + source="2001:db8:2000::/36", + ), + ), + ), + ), + ], + ), + ], + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "route-map rmap1 permit 10", + "no match ip multicast source 192.168.1.0/24 group-range 239.0.0.1 to 239.255.255.255 rp 209.165.201.0/27 rp-type Bidir", + "match ip multicast source 192.168.1.0/24 group 239.0.0.1/24 rp 209.165.201.0/27 rp-type Bidir", + "no match ip address prefix-list pl1 pl2 pl3", + "match ip address prefix-list pl4", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_route_maps_gathered_empty(self): + # test gathered for empty config + self.get_config.return_value = dedent( + """\ + """, + ) + set_module_args(dict(state="gathered"), ignore_provider_arg) + + result = self.execute_module(changed=False) + self.assertEqual(result["gathered"], []) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_snmp_server.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_snmp_server.py new file mode 100644 index 00000000..38e1b659 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_snmp_server.py @@ -0,0 +1,1026 @@ +# (c) 2021 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from textwrap import dedent + +from ansible_collections.cisco.nxos.plugins.modules import nxos_snmp_server +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, set_module_args + + +ignore_provider_arg = True + + +class TestNxosSnmpServerModule(TestNxosModule): + module = nxos_snmp_server + + def setUp(self): + super(TestNxosSnmpServerModule, self).setUp() + + self.mock_get_resource_connection = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module_base.get_resource_connection", + ) + self.get_resource_connection = self.mock_get_resource_connection.start() + + self.mock_get_config = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.facts.snmp_server.snmp_server.Snmp_serverFacts.get_config", + ) + self.get_config = self.mock_get_config.start() + + def tearDown(self): + super(TestNxosSnmpServerModule, self).tearDown() + self.get_resource_connection.stop() + self.get_config.stop() + + def test_nxos_snmp_server_linear_merged(self): + # test merged for linear attributes + self.get_config.return_value = dedent( + """\ + """, + ) + set_module_args( + dict( + config=dict( + aaa_user=dict(cache_timeout=36000), + contact="testswitch@localhost", + context=dict(name="public", vrf="siteA", instance="test"), + counter=dict(cache=dict(timeout=1800)), + drop=dict(unknown_engine_id=True, unknown_user=True), + engine_id=dict(local="'00:00:00:63:00:01:00:10:20:15:10:03'"), + communities=[ + dict(name="private", group="network-admin"), + dict(community="public", use_ipv4acl="myacl"), + ], + global_enforce_priv=True, + location="lab", + mib=dict(community_map=dict(community="public", context="public1")), + packetsize=484, + protocol=dict(enable=True), + source_interface=dict(informs="Ethernet1/1", traps="Ethernet1/2"), + system_shutdown=True, + tcp_session=dict(auth=True), + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "snmp-server community private group network-admin", + "snmp-server community public use-ipv4acl myacl", + "snmp-server globalEnforcePriv", + "snmp-server tcp-session auth", + "snmp-server counter cache timeout 1800", + "snmp-server packetsize 484", + "snmp-server drop unknown-user", + "snmp-server source-interface informs Ethernet1/1", + "snmp-server context public instance test vrf siteA", + "snmp-server protocol enable", + "snmp-server system-shutdown", + "snmp-server aaa-user cache-timeout 36000", + "snmp-server engineID local '00:00:00:63:00:01:00:10:20:15:10:03'", + "snmp-server contact testswitch@localhost", + "snmp-server drop unknown-engine-id", + "snmp-server location lab", + "snmp-server mib community-map public context public1", + "snmp-server source-interface traps Ethernet1/2", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_snmp_server_linear_merged_idempotent(self): + # test merged for linear attributes + self.get_config.return_value = dedent( + """\ + snmp-server globalEnforcePriv + snmp-server tcp-session auth + snmp-server counter cache timeout 1800 + snmp-server packetsize 484 + snmp-server drop unknown-user + snmp-server source-interface informs Ethernet1/1 + snmp-server context public vrf siteA + snmp-server protocol enable + snmp-server system-shutdown + snmp-server aaa-user cache-timeout 36000 + snmp-server engineID local 00:00:00:63:00:01:00:10:20:15:10:03 + snmp-server contact testswitch@localhost + snmp-server drop unknown-engine-id + snmp-server location lab + snmp-server mib community-map public context public1 + snmp-server source-interface traps Ethernet1/2 + """, + ) + set_module_args( + dict( + config=dict( + aaa_user=dict(cache_timeout=36000), + contact="testswitch@localhost", + context=dict(name="public", vrf="siteA"), + counter=dict(cache=dict(timeout=1800)), + drop=dict(unknown_engine_id=True, unknown_user=True), + engine_id=dict(local="00:00:00:63:00:01:00:10:20:15:10:03"), + global_enforce_priv=True, + location="lab", + mib=dict(community_map=dict(community="public", context="public1")), + packetsize=484, + protocol=dict(enable=True), + source_interface=dict(informs="Ethernet1/1", traps="Ethernet1/2"), + system_shutdown=True, + tcp_session=dict(auth=True), + ), + state="merged", + ), + ignore_provider_arg, + ) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_snmp_server_linear_replaced(self): + # test replaced for linear attributes + self.get_config.return_value = dedent( + """\ + snmp-server globalEnforcePriv + snmp-server tcp-session auth + snmp-server counter cache timeout 1800 + snmp-server packetsize 484 + snmp-server drop unknown-user + snmp-server source-interface informs Ethernet1/1 + snmp-server context public vrf siteA + snmp-server protocol enable + snmp-server system-shutdown + snmp-server aaa-user cache-timeout 36000 + snmp-server engineID local 00:00:00:63:00:01:00:10:20:15:10:03 + snmp-server contact testswitch@localhost + snmp-server drop unknown-engine-id + snmp-server location lab + snmp-server mib community-map public context public1 + snmp-server source-interface traps Ethernet1/2 + """, + ) + set_module_args( + dict( + config=dict( + aaa_user=dict(cache_timeout=36500), + contact="testswitch@localhost", + context=dict(name="public", vrf="siteA"), + counter=dict(cache=dict(timeout=1860)), + engine_id=dict(local="00:00:00:63:00:01:00:10:20:15:10:03"), + global_enforce_priv=True, + location="lab", + mib=dict(community_map=dict(community="public", context="public1")), + packetsize=484, + protocol=dict(enable=True), + source_interface=dict(informs="Ethernet1/3", traps="Ethernet1/2"), + tcp_session=dict(auth=True), + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "snmp-server counter cache timeout 1860", + "no snmp-server drop unknown-user", + "no snmp-server drop unknown-engine-id", + "snmp-server source-interface informs Ethernet1/3", + "no snmp-server system-shutdown", + "snmp-server aaa-user cache-timeout 36500", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_snmp_server_linear_overridden(self): + # test overridden for linear attributes + self.get_config.return_value = dedent( + """\ + snmp-server globalEnforcePriv + snmp-server tcp-session auth + snmp-server counter cache timeout 1800 + snmp-server packetsize 484 + snmp-server drop unknown-user + snmp-server source-interface informs Ethernet1/1 + snmp-server context public vrf siteA + snmp-server protocol enable + snmp-server system-shutdown + snmp-server aaa-user cache-timeout 36000 + snmp-server engineID local 00:00:00:63:00:01:00:10:20:15:10:03 + snmp-server contact testswitch@localhost + snmp-server drop unknown-engine-id + snmp-server location lab + snmp-server mib community-map public context public1 + snmp-server source-interface traps Ethernet1/2 + """, + ) + set_module_args( + dict( + config=dict( + aaa_user=dict(cache_timeout=36500), + contact="testswitch@localhost", + context=dict(name="public", vrf="siteA"), + counter=dict(cache=dict(timeout=1860)), + engine_id=dict(local="00:00:00:63:00:01:00:10:20:15:10:03"), + global_enforce_priv=True, + location="lab", + mib=dict(community_map=dict(community="public", context="public1")), + packetsize=484, + protocol=dict(enable=True), + source_interface=dict(informs="Ethernet1/3", traps="Ethernet1/2"), + tcp_session=dict(auth=True), + ), + state="overridden", + ), + ignore_provider_arg, + ) + commands = [ + "snmp-server counter cache timeout 1860", + "no snmp-server drop unknown-user", + "no snmp-server drop unknown-engine-id", + "snmp-server source-interface informs Ethernet1/3", + "no snmp-server system-shutdown", + "snmp-server aaa-user cache-timeout 36500", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_snmp_server_location_spaces(self): + # test replaced for linear attributes + self.get_config.return_value = dedent( + """\ + snmp-server contact testswitch@localhost + snmp-server location lab + """, + ) + set_module_args( + dict( + config=dict( + contact="test-switch @t localhost", + location="long/and.(complicated) address", + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "snmp-server contact test-switch @t localhost", + "snmp-server location long/and.(complicated) address", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_snmp_server_traps_merged(self): + # test merged for traps + self.get_config.return_value = dedent( + """\ + """, + ) + set_module_args( + dict( + config=dict( + traps=dict( + aaa=dict(server_state_change=True), + bridge=dict(enable=True), + callhome=dict(event_notify=True, smtp_send_fail=True), + bgp=dict(enable=True), + ospf=dict(enable=True), + ospfv3=dict(enable=True), + ), + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "snmp-server enable traps aaa server-state-change", + "snmp-server enable traps bridge newroot", + "snmp-server enable traps bridge topologychange", + "snmp-server enable traps callhome event-notify", + "snmp-server enable traps callhome smtp-send-fail", + "snmp-server enable traps bgp", + "snmp-server enable traps ospf", + "snmp-server enable traps ospfv3", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_snmp_server_traps_merged_idempotent(self): + # test merged for traps (idempotent) + self.get_config.return_value = dedent( + """\ + snmp-server enable traps aaa server-state-change + snmp-server enable traps bridge newroot + snmp-server enable traps bridge topologychange + snmp-server enable traps callhome event-notify + snmp-server enable traps callhome smtp-send-fail + snmp-server enable traps bgp + snmp-server enable traps ospf + snmp-server enable traps ospfv3 + """, + ) + set_module_args( + dict( + config=dict( + traps=dict( + aaa=dict(server_state_change=True), + bridge=dict(enable=True), + callhome=dict(event_notify=True, smtp_send_fail=True), + bgp=dict(enable=True), + ospf=dict(enable=True), + ospfv3=dict(enable=True), + ), + ), + state="merged", + ), + ignore_provider_arg, + ) + + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_snmp_server_traps_replaced(self): + # test replaced for traps + self.get_config.return_value = dedent( + """\ + snmp-server enable traps aaa server-state-change + snmp-server enable traps bridge newroot + snmp-server enable traps bridge topologychange + snmp-server enable traps callhome event-notify + snmp-server enable traps callhome smtp-send-fail + snmp-server enable traps link cisco-xcvr-mon-status-chg + """, + ) + set_module_args( + dict( + config=dict( + traps=dict( + aaa=dict(server_state_change=True), + bridge=dict(enable=True), + cfs=dict(merge_failure=True), + link=dict(cisco_xcvr_mon_status_chg=False), + ), + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "no snmp-server enable traps callhome event-notify", + "no snmp-server enable traps callhome smtp-send-fail", + "snmp-server enable traps cfs merge-failure", + "no snmp-server enable traps link cisco-xcvr-mon-status-chg", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_snmp_server_traps_replaced(self): + # test replaced for traps + self.get_config.return_value = dedent( + """\ + snmp-server enable traps aaa server-state-change + snmp-server enable traps bridge newroot + snmp-server enable traps bridge topologychange + snmp-server enable traps callhome event-notify + snmp-server enable traps callhome smtp-send-fail + """, + ) + set_module_args( + dict( + config=dict( + traps=dict( + aaa=dict(server_state_change=True), + bridge=dict(enable=True), + cfs=dict(merge_failure=True), + ), + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "no snmp-server enable traps callhome event-notify", + "no snmp-server enable traps callhome smtp-send-fail", + "snmp-server enable traps cfs merge-failure", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_snmp_server_hosts_merged(self): + # test merged for hosts + self.get_config.return_value = dedent( + """\ + """, + ) + set_module_args( + dict( + config=dict( + hosts=[ + dict( + host="192.168.1.1", + version="2c", + community="public", + traps=True, + ), + dict(host="192.168.1.1", source_interface="Ethernet1/1"), + dict( + host="192.168.2.1", + version="1", + community="private", + traps=True, + ), + dict( + host="192.168.2.1", + version="2c", + community="private", + informs=True, + ), + dict( + host="192.168.3.1", + version="3", + auth="private", + informs=True, + udp_port=65550, + ), + dict( + host="192.168.4.1", + version="3", + priv="private", + informs=True, + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "snmp-server host 192.168.2.1 informs version 2c private", + "snmp-server host 192.168.1.1 traps version 2c public", + "snmp-server host 192.168.4.1 informs version 3 priv private", + "snmp-server host 192.168.1.1 source-interface Ethernet1/1", + "snmp-server host 192.168.2.1 traps version 1 private", + "snmp-server host 192.168.3.1 informs version 3 auth private udp-port 65550", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_snmp_server_hosts_merged(self): + # test merged for hosts + self.get_config.return_value = dedent( + """\ + snmp-server host 192.168.2.1 informs version 2c private + snmp-server host 192.168.1.1 traps version 2c public + snmp-server host 192.168.4.1 informs version 3 priv private + snmp-server host 192.168.1.1 source-interface Ethernet1/1 + snmp-server host 192.168.2.1 traps version 1 private + snmp-server host 192.168.3.1 informs version 3 auth private udp-port 65550 + """, + ) + set_module_args( + dict( + config=dict( + hosts=[ + dict( + host="192.168.1.1", + version="2c", + community="public", + traps=True, + ), + dict(host="192.168.1.1", source_interface="Ethernet1/1"), + dict( + host="192.168.2.1", + version="1", + community="private", + traps=True, + ), + dict( + host="192.168.2.1", + version="2c", + community="private", + informs=True, + ), + dict( + host="192.168.3.1", + version="3", + auth="private", + informs=True, + udp_port=65550, + ), + dict( + host="192.168.4.1", + version="3", + priv="private", + informs=True, + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_snmp_server_hosts_replaced(self): + # test replaced for hosts + self.get_config.return_value = dedent( + """\ + snmp-server host 192.168.2.1 informs version 2c private + snmp-server host 192.168.1.1 traps version 2c public + snmp-server host 192.168.4.1 informs version 3 priv private + snmp-server host 192.168.1.1 source-interface Ethernet1/1 + snmp-server host 192.168.2.1 traps version 1 private + snmp-server host 192.168.3.1 informs version 3 auth private udp-port 65550 + """, + ) + set_module_args( + dict( + config=dict( + hosts=[ + dict( + host="192.168.1.1", + version="2c", + community="public", + traps=True, + ), + dict(host="192.168.1.1", source_interface="Ethernet1/1"), + dict( + host="192.168.2.1", + version="1", + community="private", + traps=True, + ), + dict( + host="192.168.2.1", + version="2c", + community="private", + informs=True, + ), + dict(host="192.168.2.1", filter_vrf="siteA"), + dict(host="192.168.4.1", use_vrf="siteB"), + ], + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "no snmp-server host 192.168.4.1 informs version 3 priv private", + "no snmp-server host 192.168.3.1 informs version 3 auth private udp-port 65550", + "snmp-server host 192.168.2.1 filter-vrf siteA", + "snmp-server host 192.168.4.1 use-vrf siteB", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_snmp_server_users_merged(self): + # test merged for users + self.get_config.return_value = dedent( + """\ + """, + ) + set_module_args( + dict( + config=dict( + users=dict( + auth=[ + dict( + user="snmp_user_1", + group="network-admin", + authentication=dict( + algorithm="md5", + password="0x5632724fb8ac3699296af26281e1d0f1", + engine_id="1:1:1:1:1", + localized_key=True, + ), + ), + dict( + user="snmp_user_2", + group="network-admin", + authentication=dict( + algorithm="md5", + password="0x5632724fb8ac3699296af26281e1d0f1", + engine_id="2:2:2:2:2", + priv=dict( + privacy_password="0x5632724fb8ac3699296af26281e1d0f1", + ), + localizedv2_key=True, + ), + ), + dict( + user="snmp_user_3", + group="network-admin", + authentication=dict( + algorithm="md5", + password="0x5632724fb8ac3699296af26281e1d0f1", + engine_id="3:3:3:3:3", + priv=dict( + privacy_password="0x5632724fb8ac3699296af26281e1d0f1", + aes_128=True, + ), + localized_key=True, + ), + ), + dict( + user="snmp_user_4", + group="network-admin", + authentication=dict( + algorithm="sha-256", + password="0x5632724fb8ac3699296af26281e1d0f1", + engine_id="4:4:4:4:4", + priv=dict( + privacy_password="0x5632724fb8ac3699296af26281e1d0f1", + aes_128=True, + ), + localized_key=True, + ), + ), + ], + ), + ), + state="merged", + ), + ignore_provider_arg, + ) + commands = [ + "snmp-server user snmp_user_2 network-admin auth md5 0x5632724fb8ac3699296af26281e1d0f1 priv 0x5632724fb8ac3699296af26281e1d0f1" + " localizedkey engineID 2:2:2:2:2", + "snmp-server user snmp_user_3 network-admin auth md5 0x5632724fb8ac3699296af26281e1d0f1 priv aes-128" + " 0x5632724fb8ac3699296af26281e1d0f1 localizedV2key engineID 3:3:3:3:3", + "snmp-server user snmp_user_1 network-admin auth md5 0x5632724fb8ac3699296af26281e1d0f1" + " localizedkey engineID 1:1:1:1:1", + "snmp-server user snmp_user_4 network-admin auth sha-256 0x5632724fb8ac3699296af26281e1d0f1 priv aes-128" + " 0x5632724fb8ac3699296af26281e1d0f1 localizedkey engineID 4:4:4:4:4", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_snmp_server_users_merged(self): + # test merged for users + self.get_config.return_value = dedent( + """\ + snmp-server user user2 network-admin auth md5 0x5632724fb8ac3699296af262 priv 0x5632724fb8ac3699296af262 localizedV2key engineID 2:2:2:2:2 + snmp-server user user3 network-admin auth md5 0x5632724fb8ac3699296af262 priv aes-128 0x5632724fb8ac3699296af262 localizedkey engineID 3:3:3:3:3 + snmp-server user user1 network-admin auth md5 0x5632724fb8ac3699296af262 localizedkey engineID 1:1:1:1:1 + snmp-server user user4 network-admin auth sha-256 0x5632724fb8ac3699296af262 priv aes-128 0x5632724fb8ac3699296af262 localizedkey engineID 4:4:4:4:4 + """, + ) + set_module_args( + dict( + config=dict( + users=dict( + auth=[ + dict( + user="user1", + group="network-admin", + authentication=dict( + algorithm="md5", + password="0x5632724fb8ac3699296af262", + engine_id="1:1:1:1:1", + localized_key=True, + ), + ), + dict( + user="user2", + group="network-admin", + authentication=dict( + algorithm="md5", + password="0x5632724fb8ac3699296af262", + engine_id="2:2:2:2:2", + priv=dict(privacy_password="0x5632724fb8ac3699296af262"), + localizedv2_key=True, + ), + ), + dict( + user="user3", + group="network-admin", + authentication=dict( + algorithm="md5", + password="0x5632724fb8ac3699296af262", + engine_id="3:3:3:3:3", + priv=dict( + privacy_password="0x5632724fb8ac3699296af262", + aes_128=True, + ), + localized_key=True, + ), + ), + dict( + user="user4", + group="network-admin", + authentication=dict( + algorithm="sha-256", + password="0x5632724fb8ac3699296af262", + engine_id="4:4:4:4:4", + priv=dict( + privacy_password="0x5632724fb8ac3699296af262", + aes_128=True, + ), + localized_key=True, + ), + ), + ], + ), + ), + state="merged", + ), + ignore_provider_arg, + ) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_snmp_server_users_replaced(self): + # test replaced for users + self.get_config.return_value = dedent( + """\ + snmp-server user user2 network-admin auth md5 0x5632724fb8ac3699296af262 priv 0x5632724fb8ac3699296af262 localizedkey engineID 2:2:2:2:2 + snmp-server user user3 network-admin auth md5 0x5632724fb8ac3699296af262 priv aes-128 0x5632724fb8ac3699296af262 localizedkey engineID 3:3:3:3:3 + snmp-server user user1 network-admin auth md5 0x5632724fb8ac3699296af262 localizedkey engineID 1:1:1:1:1 + """, + ) + set_module_args( + dict( + config=dict( + users=dict( + auth=[ + dict( + user="user1", + group="network-admin", + authentication=dict( + algorithm="md5", + password="0x5632724fb8ac3699296af262", + engine_id="1:1:1:1:1", + localized_key=True, + ), + ), + dict( + user="user4", + group="network-admin", + authentication=dict( + algorithm="md5", + password="0x5632724fb8ac3699296af262", + engine_id="3:3:3:3:3", + priv=dict( + privacy_password="0x5632724fb8ac3699296af262", + aes_128=True, + ), + localized_key=True, + ), + ), + ], + ), + ), + state="replaced", + ), + ignore_provider_arg, + ) + commands = [ + "no snmp-server user user2 network-admin auth md5 0x5632724fb8ac3699296af262 priv" + " 0x5632724fb8ac3699296af262 localizedkey engineID 2:2:2:2:2", + "no snmp-server user user3 network-admin auth md5 0x5632724fb8ac3699296af262 priv" + " aes-128 0x5632724fb8ac3699296af262 localizedkey engineID 3:3:3:3:3", + "snmp-server user user4 network-admin auth md5 0x5632724fb8ac3699296af262 priv aes-128" + " 0x5632724fb8ac3699296af262 localizedkey engineID 3:3:3:3:3", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_snmp_server_deleted(self): + # test deleted + self.get_config.return_value = dedent( + """\ + snmp-server globalEnforcePriv + snmp-server tcp-session auth + snmp-server counter cache timeout 1800 + snmp-server packetsize 484 + snmp-server drop unknown-user + snmp-server source-interface informs Ethernet1/1 + snmp-server context public vrf siteA + snmp-server protocol enable + snmp-server system-shutdown + snmp-server aaa-user cache-timeout 36000 + snmp-server engineID local 00:00:00:63:00:01:00:10:20:15:10:03 + snmp-server contact testswitch@localhost + snmp-server drop unknown-engine-id + snmp-server location lab + snmp-server mib community-map public context public1 + snmp-server source-interface traps Ethernet1/2 + """, + ) + set_module_args(dict(state="deleted"), ignore_provider_arg) + commands = [ + "no snmp-server globalEnforcePriv", + "no snmp-server tcp-session auth", + "no snmp-server counter cache timeout 1800", + "no snmp-server packetsize 484", + "no snmp-server drop unknown-user", + "no snmp-server source-interface informs Ethernet1/1", + "no snmp-server context public vrf siteA", + "no snmp-server protocol enable", + "no snmp-server system-shutdown", + "no snmp-server aaa-user cache-timeout 36000", + "no snmp-server engineID local 00:00:00:63:00:01:00:10:20:15:10:03", + "no snmp-server contact testswitch@localhost", + "no snmp-server drop unknown-engine-id", + "no snmp-server location lab", + "no snmp-server mib community-map public context public1", + "no snmp-server source-interface traps Ethernet1/2", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_snmp_server_parsed(self): + # test parsed + set_module_args( + dict( + running_config=dedent( + """\ + snmp-server community private group network-admin + snmp-server community public use-ipv4acl myacl + snmp-server globalEnforcePriv + snmp-server tcp-session auth + snmp-server counter cache timeout 1800 + snmp-server packetsize 484 + snmp-server drop unknown-user + snmp-server source-interface informs Ethernet1/1 + snmp-server context public vrf siteA + snmp-server protocol enable + snmp-server system-shutdown + snmp-server aaa-user cache-timeout 36000 + snmp-server engineID local 00:00:00:63:00:01:00:10:20:15:10:03 + snmp-server contact testswitch@localhost + snmp-server drop unknown-engine-id + snmp-server location lab + snmp-server mib community-map public context public1 + snmp-server source-interface traps Ethernet1/2 + snmp-server user 1234 network-admin auth md5 0x7d425fbf09417c44bca69e1d9e9ce889 priv 0x7d425fbf09417c44bca69e1d9e9ce889 localizedkey + snmp-server user snmp_user_1 network-operator auth md5 0x5632724fb8ac3699296af26281e1d0f1 localizedkey + """, + ), + state="parsed", + ), + ignore_provider_arg, + ) + + parsed = dict( + aaa_user=dict(cache_timeout=36000), + contact="testswitch@localhost", + communities=[ + dict(name="private", group="network-admin"), + dict(name="public", use_ipv4acl="myacl"), + ], + context=dict(name="public", vrf="siteA"), + counter=dict(cache=dict(timeout=1800)), + drop=dict(unknown_engine_id=True, unknown_user=True), + engine_id=dict(local="00:00:00:63:00:01:00:10:20:15:10:03"), + global_enforce_priv=True, + location="lab", + mib=dict(community_map=dict(community="public", context="public1")), + packetsize=484, + protocol=dict(enable=True), + source_interface=dict(informs="Ethernet1/1", traps="Ethernet1/2"), + system_shutdown=True, + tcp_session=dict(auth=True), + users=dict( + auth=[ + dict( + user="1234", + group="network-admin", + authentication=dict( + algorithm="md5", + password="0x7d425fbf09417c44bca69e1d9e9ce889", + localized_key=True, + priv=dict(privacy_password="0x7d425fbf09417c44bca69e1d9e9ce889"), + ), + ), + dict( + user="snmp_user_1", + group="network-operator", + authentication=dict( + algorithm="md5", + password="0x5632724fb8ac3699296af26281e1d0f1", + localized_key=True, + ), + ), + ], + ), + ) + result = self.execute_module(changed=False) + self.assertEqual(result["parsed"], parsed) + + def test_nxos_snmp_server_rendered(self): + # test rendered + set_module_args( + dict( + config=dict( + aaa_user=dict(cache_timeout=36000), + contact="testswitch@localhost", + context=dict(name="public", vrf="siteA"), + counter=dict(cache=dict(timeout=1800)), + drop=dict(unknown_engine_id=True, unknown_user=True), + engine_id=dict(local="'00:00:00:63:00:01:00:10:20:15:10:03'"), + global_enforce_priv=True, + location="lab", + mib=dict(community_map=dict(community="public", context="public1")), + packetsize=484, + protocol=dict(enable=True), + source_interface=dict(informs="Ethernet1/1", traps="Ethernet1/2"), + system_shutdown=True, + tcp_session=dict(auth=True), + ), + state="rendered", + ), + ignore_provider_arg, + ) + rendered = [ + "snmp-server globalEnforcePriv", + "snmp-server tcp-session auth", + "snmp-server counter cache timeout 1800", + "snmp-server packetsize 484", + "snmp-server drop unknown-user", + "snmp-server source-interface informs Ethernet1/1", + "snmp-server context public vrf siteA", + "snmp-server protocol enable", + "snmp-server system-shutdown", + "snmp-server aaa-user cache-timeout 36000", + "snmp-server engineID local '00:00:00:63:00:01:00:10:20:15:10:03'", + "snmp-server contact testswitch@localhost", + "snmp-server drop unknown-engine-id", + "snmp-server location lab", + "snmp-server mib community-map public context public1", + "snmp-server source-interface traps Ethernet1/2", + ] + result = self.execute_module(changed=False) + self.assertEqual(set(result["rendered"]), set(rendered)) + + def test_nxos_snmp_server_gathered(self): + # test gathered + self.get_config.return_value = dedent( + """\ + snmp-server globalEnforcePriv + snmp-server tcp-session auth + snmp-server counter cache timeout 1800 + snmp-server packetsize 484 + snmp-server drop unknown-user + snmp-server source-interface informs Ethernet1/1 + snmp-server context public vrf siteA + snmp-server protocol enable + snmp-server system-shutdown + snmp-server aaa-user cache-timeout 36000 + snmp-server engineID local 00:00:00:63:00:01:00:10:20:15:10:03 + snmp-server contact testswitch@localhost + snmp-server drop unknown-engine-id + snmp-server location lab + snmp-server mib community-map public context public1 + snmp-server source-interface traps Ethernet1/2 + """, + ) + set_module_args(dict(state="gathered"), ignore_provider_arg) + + gathered = dict( + aaa_user=dict(cache_timeout=36000), + contact="testswitch@localhost", + context=dict(name="public", vrf="siteA"), + counter=dict(cache=dict(timeout=1800)), + drop=dict(unknown_engine_id=True, unknown_user=True), + engine_id=dict(local="00:00:00:63:00:01:00:10:20:15:10:03"), + global_enforce_priv=True, + location="lab", + mib=dict(community_map=dict(community="public", context="public1")), + packetsize=484, + protocol=dict(enable=True), + source_interface=dict(informs="Ethernet1/1", traps="Ethernet1/2"), + system_shutdown=True, + tcp_session=dict(auth=True), + ) + result = self.execute_module(changed=False) + self.assertEqual(result["gathered"], gathered) + + def test_nxos_snmp_server_gathered_empty(self): + self.get_config.return_value = dedent( + """\ + """, + ) + set_module_args(dict(state="gathered"), ignore_provider_arg) + + gathered = {} + result = self.execute_module(changed=False) + self.assertEqual(result["gathered"], gathered) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_static_routes.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_static_routes.py new file mode 100644 index 00000000..69f5f74b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_static_routes.py @@ -0,0 +1,516 @@ +# +# (c) 2019, Ansible by Red Hat, inc +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +# + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from ansible_collections.cisco.nxos.plugins.modules import nxos_static_routes +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch +from ansible_collections.cisco.nxos.tests.unit.modules.utils import set_module_args + +from .nxos_module import TestNxosModule + + +class TestNxosStaticRoutesModule(TestNxosModule): + module = nxos_static_routes + + def setUp(self): + super(TestNxosStaticRoutesModule, self).setUp() + + self.mock_get_config = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.get_config", + ) + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_get_resource_connection_config = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base.get_resource_connection", + ) + self.get_resource_connection_config = self.mock_get_resource_connection_config.start() + + self.mock_get_resource_connection_facts = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection", + ) + self.get_resource_connection_facts = self.mock_get_resource_connection_facts.start() + + self.mock_edit_config = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.config.static_routes.static_routes.Static_routes.edit_config", + ) + self.edit_config = self.mock_edit_config.start() + + self.mock_execute_show_command = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.facts.static_routes.static_routes.Static_routesFacts.get_device_data", + ) + self.execute_show_command = self.mock_execute_show_command.start() + + def tearDown(self): + super(TestNxosStaticRoutesModule, self).tearDown() + self.mock_get_resource_connection_config.stop() + self.mock_get_resource_connection_facts.stop() + self.mock_edit_config.stop() + self.mock_get_config.stop() + self.mock_load_config.stop() + self.mock_execute_show_command.stop() + + def load_fixtures(self, commands=None, device=""): + def load_from_file(*args, **kwargs): + non_vrf_data = ["ip route 192.0.2.16/28 192.0.2.24 name initial_route"] + vrf_data = [ + "vrf context test\n ip route 192.0.2.96/28 192.0.2.122 vrf dest_vrf" + "\n ip route static bfd Vlan100 192.168.1.100\n ipv6 route 2001:db8:12::/32 2001:db8::1001 name ipv6_route 3\n", + ] + + output = non_vrf_data + vrf_data + return output + + self.execute_show_command.side_effect = load_from_file + + def test_nxos_static_routes_merged(self): + set_module_args( + dict( + config=[ + dict( + address_families=[ + dict( + afi="ipv4", + routes=[ + dict( + dest="192.0.2.32/28", + next_hops=[ + dict( + forward_router_address="192.0.2.40", + interface="Ethernet1/2", + admin_distance=5, + ), + ], + ), + ], + ), + ], + ), + ], + state="merged", + ), + ) + commands = [ + "configure terminal", + "ip route 192.0.2.32/28 Ethernet1/2 192.0.2.40 5", + ] + self.execute_module(changed=True, commands=commands) + + def test_nxos_static_routes_merged_idempotent(self): + set_module_args( + dict( + config=[ + dict( + address_families=[ + dict( + afi="ipv4", + routes=[ + dict( + dest="192.0.2.16/28", + next_hops=[ + dict( + forward_router_address="192.0.2.24", + route_name="initial_route", + ), + ], + ), + ], + ), + ], + ), + ], + state="merged", + ), + ) + self.execute_module(changed=False, commands=[]) + + def test_nxos_static_routes_replaced(self): + set_module_args( + dict( + config=[ + dict( + address_families=[ + dict( + afi="ipv4", + routes=[ + dict( + dest="192.0.2.16/28", + next_hops=[ + dict( + forward_router_address="192.0.2.50", + tag=12, + route_name="replaced_route", + ), + ], + ), + ], + ), + ], + ), + ], + state="replaced", + ), + ) + commands = [ + "configure terminal", + "no ip route 192.0.2.16/28 192.0.2.24 name initial_route", + "ip route 192.0.2.16/28 192.0.2.50 name replaced_route tag 12", + ] + self.execute_module(changed=True, commands=commands) + + def test_nxos_static_routes_replaced_idempotent(self): + set_module_args( + dict( + config=[ + dict( + address_families=[ + dict( + afi="ipv4", + routes=[ + dict( + dest="192.0.2.16/28", + next_hops=[ + dict( + forward_router_address="192.0.2.24", + route_name="initial_route", + ), + ], + ), + ], + ), + ], + ), + ], + state="replaced", + ), + ) + self.execute_module(changed=False, commands=[]) + + def test_nxos_static_routes_overridden(self): + set_module_args( + dict( + config=[ + dict( + address_families=[ + dict( + afi="ipv4", + routes=[ + dict( + dest="192.0.2.112/28", + next_hops=[ + dict( + forward_router_address="192.0.2.68", + route_name="overridden_route", + dest_vrf="end_vrf", + ), + ], + ), + ], + ), + ], + ), + ], + state="overridden", + ), + ) + commands = [ + "configure terminal", + "no ip route 192.0.2.16/28 192.0.2.24 name initial_route", + "ip route 192.0.2.112/28 192.0.2.68 vrf end_vrf name overridden_route", + "vrf context test", + "no ipv6 route 2001:db8:12::/32 2001:db8::1001 name ipv6_route 3", + "no ip route 192.0.2.96/28 192.0.2.122 vrf dest_vrf", + ] + self.execute_module(changed=True, commands=commands) + + def test_nxos_static_routes_overridden_idempotent(self): + set_module_args( + dict( + config=[ + dict( + vrf="test", + address_families=[ + dict( + afi="ipv4", + routes=[ + dict( + dest="192.0.2.96/28", + next_hops=[ + dict( + forward_router_address="192.0.2.122", + dest_vrf="dest_vrf", + ), + ], + ), + ], + ), + ], + ), + dict( + address_families=[ + dict( + afi="ipv4", + routes=[ + dict( + dest="192.0.2.16/28", + next_hops=[ + dict( + forward_router_address="192.0.2.24", + route_name="initial_route", + ), + ], + ), + ], + ), + ], + ), + ], + state="overridden", + ), + ) + self.execute_module(changed=False, commands=[]) + + def test_nxos_static_routes_deletedvrf(self): + set_module_args(dict(config=[dict(vrf="test")], state="deleted")) + commands = [ + "vrf context test", + "no ip route 192.0.2.96/28 192.0.2.122 vrf dest_vrf", + "no ipv6 route 2001:db8:12::/32 2001:db8::1001 name ipv6_route 3", + ] + self.execute_module(changed=True, commands=commands) + + def test_nxos_static_routes_deletedafi(self): + set_module_args( + dict( + config=[dict(address_families=[dict(afi="ipv4")])], + state="deleted", + ), + ) + commands = [ + "configure terminal", + "no ip route 192.0.2.16/28 192.0.2.24 name initial_route", + ] + self.execute_module(changed=True, commands=commands) + + def test_nxos_static_routes_deleteddest(self): + set_module_args( + dict( + config=[ + dict( + vrf="test", + address_families=[dict(afi="ipv4", routes=[dict(dest="192.0.2.96/28")])], + ), + ], + state="deleted", + ), + ) + commands = [ + "vrf context test", + "no ip route 192.0.2.96/28 192.0.2.122 vrf dest_vrf", + ] + self.execute_module(changed=True, commands=commands) + + def test_nxos_static_routes_deletedroute(self): + set_module_args( + dict( + config=[ + dict( + vrf="test", + address_families=[ + dict( + afi="ipv6", + routes=[ + dict( + dest="2001:db8:12::/32", + next_hops=[ + dict( + forward_router_address="2001:db8::1001", + route_name="ipv6_route", + admin_distance=3, + ), + ], + ), + ], + ), + ], + ), + ], + state="deleted", + ), + ) + commands = [ + "vrf context test", + "no ipv6 route 2001:db8:12::/32 2001:db8::1001 name ipv6_route 3", + ] + self.execute_module(changed=True, commands=commands) + + def test_nxos_static_routes_rendered(self): + set_module_args( + dict( + config=[ + dict( + vrf="testvrf", + address_families=[ + dict( + afi="ipv6", + routes=[ + dict( + dest="1200:10::/64", + next_hops=[ + dict( + forward_router_address="2048:ae12::/64", + interface="Eth1/4", + admin_distance=5, + ), + ], + ), + ], + ), + ], + ), + ], + state="rendered", + ), + ) + commands = [ + "vrf context testvrf", + "ipv6 route 1200:10::/64 Ethernet1/4 2048:ae12::/64 5", + ] + result = self.execute_module(changed=False) + self.assertEqual(sorted(result["rendered"]), sorted(commands), result["rendered"]) + + def test_nxos_static_routes_parsed(self): + set_module_args( + dict( + running_config="""ip route 192.0.2.16/28 192.0.2.24 name initial_route + vrf context test + ip route 192.0.2.96/28 192.0.2.122 vrf dest_vrf + ipv6 route 2001:db8:12::/32 2001:db8::1001 name ipv6_route 3""", + state="parsed", + ), + ) + result = self.execute_module(changed=False) + compare_list = [ + { + "vrf": "test", + "address_families": [ + { + "routes": [ + { + "dest": "192.0.2.96/28", + "next_hops": [ + { + "dest_vrf": "dest_vrf", + "forward_router_address": "192.0.2.122", + }, + ], + }, + ], + "afi": "ipv4", + }, + { + "routes": [ + { + "dest": "2001:db8:12::/32", + "next_hops": [ + { + "route_name": "ipv6_route", + "forward_router_address": "2001:db8::1001", + "admin_distance": 3, + }, + ], + }, + ], + "afi": "ipv6", + }, + ], + }, + { + "address_families": [ + { + "routes": [ + { + "dest": "192.0.2.16/28", + "next_hops": [ + { + "route_name": "initial_route", + "forward_router_address": "192.0.2.24", + }, + ], + }, + ], + "afi": "ipv4", + }, + ], + }, + ] + self.assertEqual(result["parsed"], compare_list, result["parsed"]) + + def test_nxos_static_routes_gathered(self): + set_module_args(dict(config=[], state="gathered")) + result = self.execute_module(changed=False) + compare_list = [ + { + "vrf": "test", + "address_families": [ + { + "routes": [ + { + "dest": "192.0.2.96/28", + "next_hops": [ + { + "dest_vrf": "dest_vrf", + "forward_router_address": "192.0.2.122", + }, + ], + }, + ], + "afi": "ipv4", + }, + { + "routes": [ + { + "dest": "2001:db8:12::/32", + "next_hops": [ + { + "route_name": "ipv6_route", + "forward_router_address": "2001:db8::1001", + "admin_distance": 3, + }, + ], + }, + ], + "afi": "ipv6", + }, + ], + }, + { + "address_families": [ + { + "routes": [ + { + "dest": "192.0.2.16/28", + "next_hops": [ + { + "route_name": "initial_route", + "forward_router_address": "192.0.2.24", + }, + ], + }, + ], + "afi": "ipv4", + }, + ], + }, + ] + self.assertEqual(result["gathered"], compare_list, result["gathered"]) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_system.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_system.py new file mode 100644 index 00000000..ea7eec95 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_system.py @@ -0,0 +1,205 @@ +# +# (c) 2016 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from ansible_collections.cisco.nxos.plugins.modules import nxos_system +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, load_fixture, set_module_args + + +class TestNxosSystemModule(TestNxosModule): + module = nxos_system + + def setUp(self): + super(TestNxosSystemModule, self).setUp() + + self.mock_get_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_system.get_config", + ) + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_system.load_config", + ) + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestNxosSystemModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, device=""): + self.get_config.return_value = load_fixture("nxos_system", "config.cfg", device=device) + self.load_config.return_value = None + + def test_nxos_system_hostname_changed(self): + set_module_args(dict(hostname="foo")) + commands = ["hostname foo"] + self.execute_module(changed=True, commands=commands) + + def test_nxos_system_domain_lookup(self): + set_module_args(dict(domain_lookup=True)) + commands = ["ip domain-lookup"] + self.execute_module(changed=True, commands=commands) + + def test_nxos_system_missing_vrf(self): + domain_name = dict(name="example.com", vrf="example") + set_module_args(dict(domain_name=domain_name)) + self.execute_module(failed=True) + + def test_nxos_system_domain_name(self): + set_module_args(dict(domain_name=["example.net"])) + commands = [ + "no ip domain-name ansible.com", + "vrf context management", + "no ip domain-name eng.ansible.com", + "exit", + "ip domain-name example.net", + ] + self.execute_module(changed=True, commands=commands) + + def test_nxos_system_domain_name_vrf_only(self): + set_module_args( + dict( + domain_name=[ + {"name": "abc.com", "vrf": "test"}, + {"name": "xyz.com", "vrf": "test2"}, + ], + ), + ) + commands = [] + self.execute_module(changed=False, commands=commands, device="vrf_only") + + def test_nxos_system_domain_name_complex(self): + domain_name = dict(name="example.net", vrf="management") + set_module_args(dict(domain_name=[domain_name])) + commands = [ + "no ip domain-name ansible.com", + "vrf context management", + "no ip domain-name eng.ansible.com", + "exit", + "vrf context management", + "ip domain-name example.net", + "exit", + ] + self.execute_module(changed=True, commands=commands) + + def test_nxos_system_domain_search(self): + set_module_args(dict(domain_search=["example.net"])) + commands = [ + "vrf context management", + "no ip domain-list ansible.com", + "exit", + "vrf context management", + "no ip domain-list redhat.com", + "exit", + "no ip domain-list ansible.com", + "no ip domain-list redhat.com", + "ip domain-list example.net", + ] + self.execute_module(changed=True, commands=commands) + + def test_nxos_system_domain_search_complex(self): + domain_search = dict(name="example.net", vrf="management") + set_module_args(dict(domain_search=[domain_search])) + commands = [ + "vrf context management", + "no ip domain-list ansible.com", + "exit", + "vrf context management", + "no ip domain-list redhat.com", + "exit", + "no ip domain-list ansible.com", + "no ip domain-list redhat.com", + "vrf context management", + "ip domain-list example.net", + "exit", + ] + self.execute_module(changed=True, commands=commands) + + def test_nxos_system_name_servers(self): + set_module_args(dict(name_servers=["1.2.3.4", "8.8.8.8"])) + commands = [ + "no ip name-server 172.26.1.1", + "vrf context management", + "no ip name-server 8.8.8.8", + "exit", + "vrf context management", + "no ip name-server 172.26.1.1", + "exit", + "ip name-server 1.2.3.4", + ] + self.execute_module(changed=True, commands=commands) + + def test_nxos_system_name_servers_complex(self): + name_servers = dict(server="1.2.3.4", vrf="management") + set_module_args(dict(name_servers=[name_servers])) + commands = [ + "no ip name-server 8.8.8.8", + "no ip name-server 172.26.1.1", + "vrf context management", + "no ip name-server 8.8.8.8", + "exit", + "vrf context management", + "no ip name-server 172.26.1.1", + "exit", + "vrf context management", + "ip name-server 1.2.3.4", + "exit", + ] + self.execute_module(changed=True, commands=commands) + + def test_nxos_system_system_mtu(self): + set_module_args(dict(system_mtu=2000)) + commands = ["system jumbomtu 2000"] + self.execute_module(changed=True, commands=commands) + + def test_nxos_system_state_absent(self): + set_module_args(dict(state="absent")) + commands = [ + "no hostname", + "no ip domain-name ansible.com", + "vrf context management", + "no ip domain-name eng.ansible.com", + "exit", + "no ip domain-list ansible.com", + "no ip domain-list redhat.com", + "vrf context management", + "no ip domain-list ansible.com", + "exit", + "vrf context management", + "no ip domain-list redhat.com", + "exit", + "no ip name-server 8.8.8.8", + "no ip name-server 172.26.1.1", + "vrf context management", + "no ip name-server 8.8.8.8", + "exit", + "vrf context management", + "no ip name-server 172.26.1.1", + "exit", + "no system jumbomtu", + ] + self.execute_module(changed=True, commands=commands) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_telemetry.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_telemetry.py new file mode 100644 index 00000000..160804c1 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_telemetry.py @@ -0,0 +1,1926 @@ +# (c) 2019 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from textwrap import dedent + +# TBD: These imports / import checks are only needed as a workaround for +# shippable, which fails this test due to import yaml & import ordereddict. +import pytest + +from ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.nxos import ( + nxosCmdRef_import_check, +) +from ansible_collections.cisco.nxos.plugins.modules import nxos_telemetry +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch +from ansible_collections.cisco.nxos.tests.unit.modules.utils import AnsibleFailJson + +from .nxos_module import TestNxosModule, load_fixture, set_module_args + + +msg = nxosCmdRef_import_check() +ignore_provider_arg = True + + +@pytest.mark.skipif(len(msg), reason=msg) +class TestNxosTelemetryModule(TestNxosModule): + module = nxos_telemetry + + def setUp(self): + super(TestNxosTelemetryModule, self).setUp() + + self.mock_FACT_LEGACY_SUBSETS = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.facts.facts.FACT_LEGACY_SUBSETS", + ) + self.FACT_LEGACY_SUBSETS = self.mock_FACT_LEGACY_SUBSETS.start() + + self.mock_get_resource_connection_config = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base.get_resource_connection", + ) + self.get_resource_connection_config = self.mock_get_resource_connection_config.start() + + self.mock_get_resource_connection_facts = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection", + ) + self.get_resource_connection_facts = self.mock_get_resource_connection_facts.start() + + self.mock_edit_config = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.config.telemetry.telemetry.Telemetry.edit_config", + ) + self.edit_config = self.mock_edit_config.start() + + self.mock_execute_show_command = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.nxos.NxosCmdRef.execute_show_command", + ) + self.execute_show_command = self.mock_execute_show_command.start() + + self.mock_get_platform_shortname = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.nxos.NxosCmdRef.get_platform_shortname", + ) + self.get_platform_shortname = self.mock_get_platform_shortname.start() + + def tearDown(self): + super(TestNxosTelemetryModule, self).tearDown() + self.mock_FACT_LEGACY_SUBSETS.stop() + self.mock_get_resource_connection_config.stop() + self.mock_get_resource_connection_facts.stop() + self.mock_edit_config.stop() + self.mock_execute_show_command.stop() + self.get_platform_shortname.stop() + + def load_fixtures(self, commands=None, device=""): + self.mock_FACT_LEGACY_SUBSETS.return_value = dict() + self.get_resource_connection_config.return_value = "Connection" + self.get_resource_connection_facts.return_value = "Connection" + self.edit_config.return_value = None + + # --------------------------- + # Telemetry Global Test Cases + # --------------------------- + + def test_tms_global_merged_n9k(self): + # Assumes feature telemetry is disabled + # TMS global config is not present. + self.execute_show_command.return_value = None + self.get_platform_shortname.return_value = "N9K" + set_module_args( + dict( + config=dict( + certificate={ + "key": "/bootflash/sample.key", + "hostname": "server.example.com", + }, + compression="gzip", + source_interface="Ethernet2/1", + vrf="blue", + ), + ), + ignore_provider_arg, + ) + self.execute_module( + changed=True, + commands=[ + "feature telemetry", + "telemetry", + "certificate /bootflash/sample.key server.example.com", + "destination-profile", + "use-compression gzip", + "source-interface Ethernet2/1", + "use-vrf blue", + ], + ) + + def test_tms_global_checkmode_n9k(self): + # Assumes feature telemetry is disabled + # TMS global config is not present. + self.execute_show_command.return_value = None + self.get_platform_shortname.return_value = "N9K" + set_module_args( + dict( + _ansible_check_mode=True, + config=dict( + certificate={ + "key": "/bootflash/sample.key", + "hostname": "server.example.com", + }, + compression="gzip", + source_interface="Ethernet2/1", + vrf="blue", + ), + ), + ignore_provider_arg, + ) + self.execute_module( + changed=True, + commands=[ + "feature telemetry", + "telemetry", + "certificate /bootflash/sample.key server.example.com", + "destination-profile", + "use-compression gzip", + "source-interface Ethernet2/1", + "use-vrf blue", + ], + ) + + def test_tms_global_merged2_n9k(self): + # Assumes feature telemetry is disabled + # TMS global config is not present. + # Configure only vrf + self.execute_show_command.return_value = None + self.get_platform_shortname.return_value = "N9K" + set_module_args(dict(config=dict(vrf="blue")), ignore_provider_arg) + self.execute_module( + changed=True, + commands=[ + "feature telemetry", + "telemetry", + "destination-profile", + "use-vrf blue", + ], + ) + + def test_tms_global_idempotent_n9k(self): + # Assumes feature telemetry is enabled + # TMS global config is present. + self.execute_show_command.return_value = load_fixture("nxos_telemetry", "N9K.cfg") + self.get_platform_shortname.return_value = "N9K" + set_module_args( + dict( + config=dict( + certificate={ + "key": "/bootflash/server.key", + "hostname": "localhost", + }, + compression="gzip", + source_interface="loopback55", + vrf="management", + ), + ), + ignore_provider_arg, + ) + self.execute_module(changed=False) + + def test_tms_global_change_cert_n9k(self): + # Assumes feature telemetry is enabled + # TMS global config is present + # Change certificate + self.execute_show_command.return_value = load_fixture("nxos_telemetry", "N9K.cfg") + self.get_platform_shortname.return_value = "N9K" + set_module_args( + dict( + config=dict( + certificate={ + "key": "/bootflash/server.key", + "hostname": "my_host", + }, + compression="gzip", + source_interface="loopback55", + vrf="management", + ), + ), + ignore_provider_arg, + ) + self.execute_module( + changed=True, + commands=[ + "telemetry", + "certificate /bootflash/server.key my_host", + ], + ) + + def test_tms_global_change_interface_n9k(self): + # Assumes feature telemetry is enabled + # TMS global config is present + # Change interface + self.execute_show_command.return_value = load_fixture("nxos_telemetry", "N9K.cfg") + self.get_platform_shortname.return_value = "N9K" + set_module_args( + dict( + config=dict( + certificate={ + "key": "/bootflash/server.key", + "hostname": "localhost", + }, + compression="gzip", + source_interface="Ethernet8/1", + vrf="management", + ), + ), + ignore_provider_arg, + ) + self.execute_module( + changed=True, + commands=[ + "telemetry", + "destination-profile", + "source-interface Ethernet8/1", + ], + ) + + def test_tms_global_change_several_n9k(self): + # Assumes feature telemetry is enabled + # TMS global config is present + # Change source_interface, vrf and cert + self.execute_show_command.return_value = load_fixture("nxos_telemetry", "N9K.cfg") + self.get_platform_shortname.return_value = "N9K" + set_module_args( + dict( + config=dict( + certificate={ + "key": "/bootflash/server_5.key", + "hostname": "my_host", + }, + compression="gzip", + source_interface="Ethernet8/1", + vrf="blue", + ), + ), + ignore_provider_arg, + ) + self.execute_module( + changed=True, + commands=[ + "telemetry", + "certificate /bootflash/server_5.key my_host", + "destination-profile", + "source-interface Ethernet8/1", + "use-vrf blue", + ], + ) + + # ------------------------------ + # Telemetry DestGroup Test Cases + # ------------------------------ + + def test_tms_destgroup_input_validation_1(self): + # Mandatory parameter 'id' missing. + self.execute_show_command.return_value = None + self.get_platform_shortname.return_value = "N9K" + args = build_args( + [ + { + "destination": { + "ip": "192.168.1.1", + "port": "5001", + "protocol": "GRPC", + "encoding": "GPB", + }, + }, + ], + "destination_groups", + ) + set_module_args(args, ignore_provider_arg) + with pytest.raises(AnsibleFailJson) as errinfo: + self.execute_module() + testdata = errinfo.value.args[0] + assert "Parameter <id> under <destination_groups> is required" in str(testdata["msg"]) + assert testdata["failed"] + + def test_tms_destgroup_input_validation_2(self): + # Parameter 'destination' is not a dict. + self.execute_show_command.return_value = None + self.get_platform_shortname.return_value = "N9K" + args = build_args([{"id": "88", "destination": "192.168.1.1"}], "destination_groups") + set_module_args(args, ignore_provider_arg) + with pytest.raises(AnsibleFailJson) as errinfo: + self.execute_module() + testdata = errinfo.value.args[0] + assert "Parameter <destination> under <destination_groups> must be a dict" in str( + testdata["msg"], + ) + assert testdata["failed"] + + def test_tms_destgroup_input_validation_3(self): + # Parameter 'destination' is not a dict. + self.execute_show_command.return_value = None + self.get_platform_shortname.return_value = "N9K" + args = build_args( + [{"id": "88", "ip": "192.168.1.1", "port": "5001"}], + "destination_groups", + ) + set_module_args(args, ignore_provider_arg) + with pytest.raises(AnsibleFailJson) as errinfo: + self.execute_module() + testdata = errinfo.value.args[0] + assert "Playbook entry contains unrecongnized parameters" in str(testdata["msg"]) + assert testdata["failed"] + + def test_tms_destgroup_merged_n9k(self): + # Assumes feature telemetry is enabled + # TMS destgroup config is not present. + self.execute_show_command.return_value = None + self.get_platform_shortname.return_value = "N9K" + args = build_args( + [ + { + "id": "88", + "destination": { + "ip": "192.168.1.1", + "port": "5001", + "protocol": "GRPC", + "encoding": "GPB", + }, + }, + { + "id": "88", + "destination": { + "ip": "192.168.1.2", + "port": "6001", + "protocol": "GRPC", + "encoding": "GPB", + }, + }, + { + "id": "99", + "destination": { + "ip": "192.168.1.2", + "port": "6001", + "protocol": "GRPC", + "encoding": "GPB", + }, + }, + { + "id": "99", + "destination": { + "ip": "192.168.1.1", + "port": "5001", + "protocol": "GRPC", + "encoding": "GPB", + }, + }, + ], + "destination_groups", + ) + set_module_args(args, ignore_provider_arg) + self.execute_module( + changed=True, + commands=[ + "feature telemetry", + "telemetry", + "destination-group 88", + "ip address 192.168.1.1 port 5001 protocol grpc encoding gpb", + "ip address 192.168.1.2 port 6001 protocol grpc encoding gpb", + "destination-group 99", + "ip address 192.168.1.2 port 6001 protocol grpc encoding gpb", + "ip address 192.168.1.1 port 5001 protocol grpc encoding gpb", + ], + ) + + def test_tms_destgroup_checkmode_n9k(self): + # Assumes feature telemetry is enabled + # TMS destgroup config is not present. + self.execute_show_command.return_value = None + self.get_platform_shortname.return_value = "N9K" + args = build_args( + [ + { + "id": "88", + "destination": { + "ip": "192.168.1.1", + "port": "5001", + "protocol": "GRPC", + "encoding": "GPB", + }, + }, + ], + "destination_groups", + state="merged", + check_mode=True, + ) + set_module_args(args, ignore_provider_arg) + self.execute_module( + changed=True, + commands=[ + "feature telemetry", + "telemetry", + "destination-group 88", + "ip address 192.168.1.1 port 5001 protocol grpc encoding gpb", + ], + ) + + def test_tms_destgroup_merged2_n9k(self): + # Assumes feature telemetry is enabled + # TMS destgroup config is not present. + # Configure only identifier + self.execute_show_command.return_value = None + self.get_platform_shortname.return_value = "N9K" + args = build_args([{"id": "88"}], "destination_groups") + set_module_args(args, ignore_provider_arg) + self.execute_module( + changed=True, + commands=[ + "feature telemetry", + "telemetry", + "destination-group 88", + ], + ) + + def test_tms_destgroup_idempotent_n9k(self): + # Assumes feature telemetry is enabled + # TMS destgroup config is not present. + # Configure only identifier + self.execute_show_command.return_value = load_fixture("nxos_telemetry", "N9K.cfg") + self.get_platform_shortname.return_value = "N9K" + args = build_args( + [ + { + "id": "2", + "destination": { + "ip": "192.168.0.2", + "port": "60001", + "protocol": "grpc", + "encoding": "gpb", + }, + }, + ], + "destination_groups", + ) + set_module_args(args, ignore_provider_arg) + self.execute_module(changed=False) + + def test_tms_destgroup_idempotent2_n9k(self): + # Assumes feature telemetry is enabled + # TMS destgroup config is not present. + # Configure only identifier + self.execute_show_command.return_value = load_fixture("nxos_telemetry", "N9K.cfg") + self.get_platform_shortname.return_value = "N9K" + args = build_args([{"id": "2"}], "destination_groups") + set_module_args(args, ignore_provider_arg) + self.execute_module(changed=False) + + def test_tms_destgroup_merged_aggregate_idempotent_n9k(self): + # Assumes feature telemetry is enabled + # TMS destgroup config is present. + self.execute_show_command.return_value = load_fixture("nxos_telemetry", "N9K.cfg") + self.get_platform_shortname.return_value = "N9K" + args = build_args( + [ + { + "id": "2", + "destination": { + "ip": "192.168.0.1", + "port": "50001", + "protocol": "gRPC", + "encoding": "gpb", + }, + }, + { + "id": "10", + "destination": { + "ip": "192.168.0.1", + "port": "50001", + "protocol": "gRPC", + "encoding": "gpb", + }, + }, + ], + "destination_groups", + ) + set_module_args(args, ignore_provider_arg) + self.execute_module(changed=False) + + def test_tms_destgroup_change_n9k(self): + # TMS destgroup config is not present. + # Change protocol and encoding for dest group 2 + self.execute_show_command.return_value = load_fixture("nxos_telemetry", "N9K.cfg") + self.get_platform_shortname.return_value = "N9K" + args = build_args( + [ + { + "id": "2", + "destination": { + "ip": "192.168.0.1", + "port": "50001", + "protocol": "http", + "encoding": "JSON", + }, + }, + { + "id": "10", + "destination": { + "ip": "192.168.0.1", + "port": "50001", + "protocol": "gRPC", + "encoding": "gpb", + }, + }, + ], + "destination_groups", + ) + set_module_args(args, ignore_provider_arg) + self.execute_module( + changed=True, + commands=[ + "telemetry", + "destination-group 2", + "ip address 192.168.0.1 port 50001 protocol http encoding json", + ], + ) + + def test_tms_destgroup_add_n9k(self): + # TMS destgroup config is not present. + # Add destinations to destgroup 10 + # Add new destgroup 55 and 56 + self.execute_show_command.return_value = load_fixture("nxos_telemetry", "N9K.cfg") + self.get_platform_shortname.return_value = "N9K" + args = build_args( + [ + { + "id": "10", + "destination": { + "ip": "192.168.0.1", + "port": "50001", + "protocol": "gRPC", + "encoding": "gpb", + }, + }, + { + "id": "10", + "destination": { + "ip": "192.168.0.10", + "port": "50001", + "protocol": "gRPC", + "encoding": "gpb", + }, + }, + { + "id": "55", + "destination": { + "ip": "192.168.0.2", + "port": "50001", + "protocol": "gRPC", + "encoding": "gpb", + }, + }, + {"id": "56"}, + ], + "destination_groups", + ) + set_module_args(args, ignore_provider_arg) + self.execute_module( + changed=True, + commands=[ + "telemetry", + "destination-group 10", + "ip address 192.168.0.10 port 50001 protocol grpc encoding gpb", + "destination-group 55", + "ip address 192.168.0.2 port 50001 protocol grpc encoding gpb", + "destination-group 56", + ], + ) + + # -------------------------------- + # Telemetry SensorGroup Test Cases + # -------------------------------- + + def test_tms_sensorgroup_merged_n9k(self): + # Assumes feature telemetry is enabled + # TMS sensorgroup config is not present. + self.execute_show_command.return_value = None + self.get_platform_shortname.return_value = "N9K" + td55_name = "sys/bgp/inst/dom-default/peer-[10.10.10.11]/ent-[10.10.10.11]" + td55_fc = 'or(eq(ethpmPhysIf.operSt,"down"),eq(ethpmPhysIf.operSt,"up"))' + args = build_args( + [ + { + "id": "2", + "data_source": "NX-API", + "path": { + "name": "sys/bgp", + "depth": 0, + "query_condition": "foo", + "filter_condition": "foo", + }, + }, + { + "id": "2", + "data_source": "NX-API", + "path": { + "name": "sys/bgp/inst", + "depth": "unbounded", + "query_condition": "foo", + "filter_condition": "foo", + }, + }, + { + "id": "55", + "data_source": "DME", + "path": { + "name": td55_name, + "depth": 0, + "query_condition": "foo", + "filter_condition": "foo", + }, + }, + { + "id": "55", + "data_source": "DME", + "path": { + "name": "sys/ospf", + "depth": 0, + "query_condition": "foo", + "filter_condition": td55_fc, + }, + }, + ], + "sensor_groups", + ) + set_module_args(args, ignore_provider_arg) + self.execute_module( + changed=True, + commands=[ + "feature telemetry", + "telemetry", + "sensor-group 2", + "data-source NX-API", + "path sys/bgp depth 0 query-condition foo filter-condition foo", + "path sys/bgp/inst depth unbounded query-condition foo filter-condition foo", + "sensor-group 55", + "data-source DME", + "path sys/bgp/inst/dom-default/peer-[10.10.10.11]/ent-[10.10.10.11] depth 0 query-condition foo filter-condition foo", + 'path sys/ospf depth 0 query-condition foo filter-condition or(eq(ethpmPhysIf.operSt,"down"),eq(ethpmPhysIf.operSt,"up"))', + ], + ) + + def test_tms_sensorgroup_input_validation_1(self): + # Mandatory parameter 'id' missing. + self.execute_show_command.return_value = None + self.get_platform_shortname.return_value = "N9K" + args = build_args( + [ + { + "data_source": "DME", + "path": { + "name": "sys/bgp", + "depth": 0, + "query_condition": "query_condition_xyz", + "filter_condition": "filter_condition_xyz", + }, + }, + ], + "sensor_groups", + ) + set_module_args(args, ignore_provider_arg) + with pytest.raises(AnsibleFailJson) as errinfo: + self.execute_module() + testdata = errinfo.value.args[0] + assert "Parameter <id> under <sensor_groups> is required" in str(testdata["msg"]) + assert testdata["failed"] + + def test_tms_sensorgroup_input_validation_2(self): + # Path present but mandatory 'name' key is not + self.execute_show_command.return_value = None + self.get_platform_shortname.return_value = "N9K" + args = build_args( + [ + { + "id": "77", + "data_source": "DME", + "path": { + "depth": 0, + "query_condition": "query_condition_xyz", + "filter_condition": "filter_condition_xyz", + }, + }, + ], + "sensor_groups", + ) + set_module_args(args, ignore_provider_arg) + with pytest.raises(AnsibleFailJson) as errinfo: + self.execute_module() + testdata = errinfo.value.args[0] + assert "Parameter <path> under <sensor_groups> requires <name> key" in str(testdata["msg"]) + assert testdata["failed"] + + def test_tms_sensorgroup_resource_key_n9k(self): + # TMS sensorgroup config is not present. + self.execute_show_command.return_value = None + self.get_platform_shortname.return_value = "N9K" + args = build_args([{"id": "77"}], "sensor_groups") + set_module_args(args, ignore_provider_arg) + self.execute_module( + changed=True, + commands=["feature telemetry", "telemetry", "sensor-group 77"], + ) + + def test_tms_sensorgroup_merged_variable_args1_n9k(self): + # TMS sensorgroup config is not present. + # Only path key name provided + self.execute_show_command.return_value = None + self.get_platform_shortname.return_value = "N9K" + args = build_args( + [{"id": "77", "data_source": "DME", "path": {"name": "sys/bgp"}}], + "sensor_groups", + ) + set_module_args(args, ignore_provider_arg) + self.execute_module( + changed=True, + commands=[ + "feature telemetry", + "telemetry", + "sensor-group 77", + "data-source DME", + "path sys/bgp", + ], + ) + + def test_tms_sensorgroup_merged_variable_args2_n9k(self): + # TMS sensorgroup config is not present. + # Only path keys name and depth provided + self.execute_show_command.return_value = None + self.get_platform_shortname.return_value = "N9K" + args = build_args( + [ + { + "id": "77", + "data_source": "DME", + "path": {"name": "sys/bgp", "depth": 0}, + }, + ], + "sensor_groups", + ) + set_module_args(args, ignore_provider_arg) + self.execute_module( + changed=True, + commands=[ + "feature telemetry", + "telemetry", + "sensor-group 77", + "data-source DME", + "path sys/bgp depth 0", + ], + ) + + def test_tms_sensorgroup_merged_variable_args3_n9k(self): + # TMS sensorgroup config is not present. + # Only path keys name, depth and query_condition provided + self.execute_show_command.return_value = None + self.get_platform_shortname.return_value = "N9K" + args = build_args( + [ + { + "id": "77", + "data_source": "DME", + "path": { + "name": "sys/bgp", + "depth": 0, + "query_condition": "query_condition_xyz", + }, + }, + ], + "sensor_groups", + ) + set_module_args(args, ignore_provider_arg) + self.execute_module( + changed=True, + commands=[ + "feature telemetry", + "telemetry", + "sensor-group 77", + "data-source DME", + "path sys/bgp depth 0 query-condition query_condition_xyz", + ], + ) + + def test_tms_sensorgroup_merged_variable_args4_n9k(self): + # TMS sensorgroup config is not present. + # Only path keys name, depth and filter_condition provided + self.execute_show_command.return_value = None + self.get_platform_shortname.return_value = "N9K" + args = build_args( + [ + { + "id": "77", + "data_source": "DME", + "path": { + "name": "sys/bgp", + "depth": 0, + "filter_condition": "filter_condition_xyz", + }, + }, + ], + "sensor_groups", + ) + set_module_args(args, ignore_provider_arg) + self.execute_module( + changed=True, + commands=[ + "feature telemetry", + "telemetry", + "sensor-group 77", + "data-source DME", + "path sys/bgp depth 0 filter-condition filter_condition_xyz", + ], + ) + + def test_tms_sensorgroup_merged_idempotent_n9k(self): + # Assumes feature telemetry is enabled + # TMS sensorgroup config is not present. + self.execute_show_command.return_value = load_fixture("nxos_telemetry", "N9K.cfg") + self.get_platform_shortname.return_value = "N9K" + args = build_args( + [ + { + "id": "2", + "data_source": "DME", + "path": { + "name": "sys/ospf", + "depth": 0, + "query_condition": "qc", + "filter_condition": "fc", + }, + }, + ], + "sensor_groups", + ) + set_module_args(args, ignore_provider_arg) + self.execute_module(changed=False) + + def test_tms_sensorgroup_quotes_merged_idempotent_n9k(self): + # Assumes feature telemetry is enabled + # TMS sensorgroup config is present with quotes in NX-API path. + self.execute_show_command.return_value = load_fixture("nxos_telemetry", "N9K_SGs.cfg") + self.get_platform_shortname.return_value = "N9K" + args = build_args( + [ + { + "id": "2", + "data_source": "NX-API", + "path": { + "name": '"show mac address-table count"', + "depth": 2, + }, + }, + { + "id": "3", + "data_source": "NX-API", + "path": {"name": '"show interface ethernet1/1-52"'}, + }, + {"id": "1", "path": {"name": "sys/procsys", "depth": 1}}, + ], + "sensor_groups", + ) + set_module_args(args, ignore_provider_arg) + self.execute_module(changed=False) + + def test_tms_sensorgroup_vxlan_idempotent_n9k(self): + # TMS sensorgroup config present. + self.execute_show_command.return_value = load_fixture("nxos_telemetry", "N9K.cfg") + self.get_platform_shortname.return_value = "N9K" + args = build_args( + [{"id": "56", "data_source": "DME", "path": {"name": "vxlan"}}], + "sensor_groups", + ) + set_module_args(args, ignore_provider_arg) + self.execute_module(changed=False) + + def test_tms_sensorgroup_idempotent_variable1_n9k(self): + # TMS sensorgroup config is present with path key name. + self.execute_show_command.return_value = load_fixture("nxos_telemetry", "N9K.cfg") + self.get_platform_shortname.return_value = "N9K" + args = build_args( + [ + { + "id": "2", + "data_source": "DME", + "path": { + "name": "sys/bgp/inst/dom-default/peer-[10.10.10.11]/ent-[10.10.10.11]", + }, + }, + ], + "sensor_groups", + ) + set_module_args(args, ignore_provider_arg) + self.execute_module(changed=False) + + def test_tms_sensorgroup_idempotent_variable2_n9k(self): + # TMS sensorgroup config is present with path key name and depth. + self.execute_show_command.return_value = load_fixture("nxos_telemetry", "N9K.cfg") + self.get_platform_shortname.return_value = "N9K" + args = build_args( + [ + { + "id": "2", + "data_source": "DME", + "path": {"name": "boo", "depth": 0}, + }, + ], + "sensor_groups", + ) + set_module_args(args, ignore_provider_arg) + self.execute_module(changed=False) + + def test_tms_sensorgroup_idempotent_resource_key_n9k(self): + # TMS sensorgroup config is present resource key only. + self.execute_show_command.return_value = load_fixture("nxos_telemetry", "N9K.cfg") + self.get_platform_shortname.return_value = "N9K" + args = build_args([{"id": "55"}], "sensor_groups") + set_module_args(args, ignore_provider_arg) + self.execute_module(changed=False) + + def test_tms_sensorgroup_present_path_environment_n9k(self): + # TMS sensorgroup config is not present. + # Path name 'environment' test + self.execute_show_command.return_value = None + self.get_platform_shortname.return_value = "N9K" + args = build_args( + [ + { + "id": "77", + "data_source": "YANG", + "path": {"name": "environment"}, + }, + ], + "sensor_groups", + ) + set_module_args(args, ignore_provider_arg) + self.execute_module( + changed=True, + commands=[ + "feature telemetry", + "telemetry", + "sensor-group 77", + "data-source YANG", + "path environment", + ], + ) + + def test_tms_sensorgroup_present_path_interface_n9k(self): + # TMS sensorgroup config is not present. + # Path name 'interface' test + self.execute_show_command.return_value = None + self.get_platform_shortname.return_value = "N9K" + args = build_args( + [ + { + "id": "77", + "data_source": "NATIVE", + "path": {"name": "interface"}, + }, + ], + "sensor_groups", + ) + set_module_args(args, ignore_provider_arg) + self.execute_module( + changed=True, + commands=[ + "feature telemetry", + "telemetry", + "sensor-group 77", + "data-source NATIVE", + "path interface", + ], + ) + + def test_tms_sensorgroup_present_path_interface_n9k(self): + # TMS sensorgroup config is not present. + # Path name 'resources' test + self.execute_show_command.return_value = None + self.get_platform_shortname.return_value = "N9K" + args = build_args( + [ + { + "id": "77", + "data_source": "NX-API", + "path": {"name": "resources"}, + }, + ], + "sensor_groups", + ) + set_module_args(args, ignore_provider_arg) + self.execute_module( + changed=True, + commands=[ + "feature telemetry", + "telemetry", + "sensor-group 77", + "data-source NX-API", + "path resources", + ], + ) + + # --------------------------------- + # Telemetry Subscription Test Cases + # --------------------------------- + + def test_tms_subscription_merged_n9k(self): + # TMS subscription config is not present. + self.execute_show_command.return_value = None + self.get_platform_shortname.return_value = "N9K" + args = build_args( + [ + { + "id": 5, + "destination_group": 55, + "sensor_group": {"id": 1, "sample_interval": 1000}, + }, + { + "id": 88, + "destination_group": 3, + "sensor_group": {"id": 4, "sample_interval": 2000}, + }, + ], + "subscriptions", + ) + set_module_args(args, ignore_provider_arg) + self.execute_module( + changed=True, + commands=[ + "feature telemetry", + "telemetry", + "subscription 5", + "dst-grp 55", + "snsr-grp 1 sample-interval 1000", + "subscription 88", + "dst-grp 3", + "snsr-grp 4 sample-interval 2000", + ], + ) + + def test_tms_subscription_merged_idempotent_n9k(self): + # TMS subscription config is not present. + self.execute_show_command.return_value = load_fixture("nxos_telemetry", "N9K.cfg") + self.get_platform_shortname.return_value = "N9K" + args = build_args( + [ + {"id": 3}, + { + "id": 7, + "destination_group": 10, + "sensor_group": {"id": 2, "sample_interval": 1000}, + }, + { + "id": 5, + "destination_group": 2, + "sensor_group": {"id": 2, "sample_interval": 1000}, + }, + ], + "subscriptions", + ) + set_module_args(args, ignore_provider_arg) + self.execute_module(changed=False) + + def test_tms_subscription_merged_change1_n9k(self): + # TMS subscription config present. + # Change sample interval for sensor group 2 + self.execute_show_command.return_value = load_fixture("nxos_telemetry", "N9K.cfg") + self.get_platform_shortname.return_value = "N9K" + args = build_args( + [ + {"id": 3}, + { + "id": 7, + "destination_group": 10, + "sensor_group": {"id": 2, "sample_interval": 3000}, + }, + { + "id": 5, + "destination_group": 2, + "sensor_group": {"id": 2, "sample_interval": 1000}, + }, + ], + "subscriptions", + ) + set_module_args(args, ignore_provider_arg) + self.execute_module( + changed=True, + commands=[ + "telemetry", + "subscription 7", + "snsr-grp 2 sample-interval 3000", + ], + ) + + def test_tms_subscription_add_n9k(self): + # TMS subscription config present. + # Add new destination_group and sensor_group to subscription 5 + self.execute_show_command.return_value = load_fixture("nxos_telemetry", "N9K.cfg") + self.get_platform_shortname.return_value = "N9K" + args = build_args( + [ + {"id": 3}, + { + "id": 7, + "destination_group": 10, + "sensor_group": {"id": 2, "sample_interval": 1000}, + }, + { + "id": 5, + "destination_group": 2, + "sensor_group": {"id": 2, "sample_interval": 1000}, + }, + { + "id": 5, + "destination_group": 7, + "sensor_group": {"id": 2, "sample_interval": 1000}, + }, + { + "id": 5, + "destination_group": 8, + "sensor_group": {"id": 9, "sample_interval": 1000}, + }, + { + "id": 5, + "destination_group": 9, + "sensor_group": {"id": 10, "sample_interval": 1000}, + }, + ], + "subscriptions", + ) + set_module_args(args, ignore_provider_arg) + self.execute_module( + changed=True, + commands=[ + "telemetry", + "subscription 5", + "dst-grp 7", + "dst-grp 8", + "dst-grp 9", + "snsr-grp 9 sample-interval 1000", + "snsr-grp 10 sample-interval 1000", + ], + ) + + def test_telemetry_full_n9k(self): + # Assumes feature telemetry is disabled + # TMS global config is not present. + self.execute_show_command.return_value = None + self.get_platform_shortname.return_value = "N9K" + set_module_args( + { + "state": "merged", + "config": { + "certificate": { + "key": "/bootflash/sample.key", + "hostname": "server.example.com", + }, + "compression": "gzip", + "source_interface": "Ethernet2/1", + "vrf": "blue", + "destination_groups": [ + { + "id": "88", + "destination": { + "ip": "192.168.1.1", + "port": "5001", + "protocol": "GRPC", + "encoding": "GPB", + }, + }, + { + "id": "88", + "destination": { + "ip": "192.168.1.2", + "port": "6001", + "protocol": "GRPC", + "encoding": "GPB", + }, + }, + { + "id": "99", + "destination": { + "ip": "192.168.1.2", + "port": "6001", + "protocol": "GRPC", + "encoding": "GPB", + }, + }, + { + "id": "99", + "destination": { + "ip": "192.168.1.1", + "port": "5001", + "protocol": "GRPC", + "encoding": "GPB", + }, + }, + ], + "sensor_groups": [ + { + "id": "77", + "data_source": "DME", + "path": { + "name": "sys/bgp", + "depth": 0, + "query_condition": "query_condition_xyz", + "filter_condition": "filter_condition_xyz", + }, + }, + { + "id": "99", + "data_source": "DME", + "path": { + "name": "sys/bgp", + "depth": 0, + "query_condition": "query_condition_xyz", + "filter_condition": "filter_condition_xyz", + }, + }, + ], + "subscriptions": [ + { + "id": 5, + "destination_group": 88, + "sensor_group": { + "id": 77, + "sample_interval": 1000, + }, + }, + { + "id": 5, + "destination_group": 99, + "sensor_group": { + "id": 77, + "sample_interval": 1000, + }, + }, + { + "id": 88, + "destination_group": 99, + "sensor_group": { + "id": 99, + "sample_interval": 2000, + }, + }, + ], + }, + }, + ignore_provider_arg, + ) + self.execute_module( + changed=True, + commands=[ + "feature telemetry", + "telemetry", + "certificate /bootflash/sample.key server.example.com", + "destination-profile", + "use-compression gzip", + "source-interface Ethernet2/1", + "use-vrf blue", + "destination-group 88", + "ip address 192.168.1.1 port 5001 protocol grpc encoding gpb", + "ip address 192.168.1.2 port 6001 protocol grpc encoding gpb", + "destination-group 99", + "ip address 192.168.1.2 port 6001 protocol grpc encoding gpb", + "ip address 192.168.1.1 port 5001 protocol grpc encoding gpb", + "sensor-group 77", + "data-source DME", + "path sys/bgp depth 0 query-condition query_condition_xyz filter-condition filter_condition_xyz", + "sensor-group 99", + "data-source DME", + "path sys/bgp depth 0 query-condition query_condition_xyz filter-condition filter_condition_xyz", + "subscription 5", + "dst-grp 88", + "dst-grp 99", + "snsr-grp 77 sample-interval 1000", + "subscription 88", + "dst-grp 99", + "snsr-grp 99 sample-interval 2000", + ], + ) + + def test_telemetry_deleted_input_validation_n9k(self): + # State is 'deleted' and 'config' key present. + self.execute_show_command.return_value = load_fixture("nxos_telemetry", "N9K.cfg") + self.get_platform_shortname.return_value = "N9K" + set_module_args( + dict( + state="deleted", + config=dict( + certificate={ + "key": "/bootflash/server.key", + "hostname": "localhost", + }, + compression="gzip", + source_interface="loopback55", + vrf="management", + ), + ), + ignore_provider_arg, + ) + with pytest.raises(AnsibleFailJson) as errinfo: + self.execute_module() + testdata = errinfo.value.args[0] + assert "Remove config key from playbook when state is <deleted>" in str(testdata["msg"]) + assert testdata["failed"] + + def test_telemetry_deleted_n9k(self): + # Assumes feature telemetry is enabled + # TMS global config is present. + # Make absent with all playbook keys provided + self.execute_show_command.return_value = load_fixture("nxos_telemetry", "N9K.cfg") + self.get_platform_shortname.return_value = "N9K" + set_module_args(dict(state="deleted"), ignore_provider_arg) + self.execute_module(changed=True, commands=["no telemetry"]) + + def test_telemetry_deleted_idempotent_n9k(self): + # Assumes feature telemetry is enabled + # TMS global config is present. + # Make absent with all playbook keys provided + self.execute_show_command.return_value = None + self.get_platform_shortname.return_value = "N9K" + set_module_args(dict(state="deleted"), ignore_provider_arg) + self.execute_module(changed=False) + + def test_tms_replaced1_n9k(self): + # Assumes feature telemetry is enabled + # Modify global config and remove everything else + self.execute_show_command.return_value = load_fixture("nxos_telemetry", "N9K.cfg") + self.get_platform_shortname.return_value = "N9K" + set_module_args( + dict( + state="replaced", + config=dict( + certificate={ + "key": "/bootflash/sample.key", + "hostname": "server.example.com", + }, + compression="gzip", + vrf="blue", + ), + ), + ignore_provider_arg, + ) + self.execute_module( + changed=True, + commands=[ + "telemetry", + "no subscription 3", + "no subscription 4", + "no subscription 5", + "no subscription 6", + "no subscription 7", + "no sensor-group 2", + "no sensor-group 55", + "no sensor-group 56", + "no destination-group 2", + "no destination-group 10", + "certificate /bootflash/sample.key server.example.com", + "destination-profile", + "no source-interface loopback55", + "use-vrf blue", + ], + ) + + def test_tms_replaced2_n9k(self): + # Assumes feature telemetry is enabled + # Remove/default all global config + # Modify destination-group 10, add 11 and 99, remove 2 + # Modify sensor-group 55, 56 + # remove all subscriptions + self.execute_show_command.return_value = load_fixture("nxos_telemetry", "N9K.cfg") + self.get_platform_shortname.return_value = "N9K" + set_module_args( + { + "state": "replaced", + "config": { + "destination_groups": [ + { + "id": 10, + "destination": { + "ip": "192.168.1.1", + "port": "5001", + "protocol": "GRPC", + "encoding": "GPB", + }, + }, + { + "id": 11, + "destination": { + "ip": "192.168.1.2", + "port": "6001", + "protocol": "GRPC", + "encoding": "GPB", + }, + }, + { + "id": 99, + "destination": { + "ip": "192.168.1.2", + "port": "6001", + "protocol": "GRPC", + "encoding": "GPB", + }, + }, + { + "id": "99", + "destination": { + "ip": "192.168.1.1", + "port": "5001", + "protocol": "GRPC", + "encoding": "GPB", + }, + }, + ], + "sensor_groups": [ + { + "id": 55, + "data_source": "NX-API", + "path": { + "name": "sys/bgp", + "depth": 0, + "query_condition": "query_condition_xyz", + "filter_condition": "filter_condition_xyz", + }, + }, + { + "id": "56", + "data_source": "NX-API", + "path": { + "name": "sys/bgp", + "depth": 0, + "query_condition": "query_condition_xyz", + "filter_condition": "filter_condition_xyz", + }, + }, + ], + }, + }, + ignore_provider_arg, + ) + self.execute_module( + changed=True, + commands=[ + "telemetry", + "no subscription 3", + "no subscription 5", + "no subscription 4", + "no subscription 7", + "no subscription 6", + "sensor-group 56", + "no data-source DME", + "no path environment", + "no path interface", + "no path resources", + "no path vxlan", + "no sensor-group 2", + "destination-group 10", + "no ip address 192.168.0.1 port 50001 protocol grpc encoding gpb", + "no ip address 192.168.0.2 port 60001 protocol grpc encoding gpb", + "no destination-group 2", + "destination-group 11", + "ip address 192.168.1.2 port 6001 protocol grpc encoding gpb", + "destination-group 10", + "ip address 192.168.1.1 port 5001 protocol grpc encoding gpb", + "destination-group 99", + "ip address 192.168.1.2 port 6001 protocol grpc encoding gpb", + "ip address 192.168.1.1 port 5001 protocol grpc encoding gpb", + "sensor-group 55", + "data-source NX-API", + "path sys/bgp depth 0 query-condition query_condition_xyz filter-condition filter_condition_xyz", + "sensor-group 56", + "data-source NX-API", + "path sys/bgp depth 0 query-condition query_condition_xyz filter-condition filter_condition_xyz", + "no certificate /bootflash/server.key localhost", + "no destination-profile", + ], + ) + + def test_tms_replaced3_n9k(self): + # Assumes feature telemetry is enabled + # Modify vrf global config, remove default all other global config. + # destination-group 2 destination '192.168.0.1' idempotent + # destination-group 2 destination '192.168.0.2' remove + # remove all other destination-groups + # Modify sensor-group 55 and delete all others + # Modify subscription 7, add 10 and delete all others + self.execute_show_command.return_value = load_fixture("nxos_telemetry", "N9K.cfg") + self.get_platform_shortname.return_value = "N9K" + set_module_args( + { + "state": "replaced", + "config": { + "vrf": "blue", + "destination_groups": [ + { + "id": 2, + "destination": { + "ip": "192.168.0.1", + "port": 50001, + "protocol": "GRPC", + "encoding": "GPB", + }, + }, + ], + "sensor_groups": [ + { + "id": 55, + "data_source": "NX-API", + "path": { + "name": "sys/bgp", + "depth": 0, + "query_condition": "query_condition_xyz", + "filter_condition": "filter_condition_xyz", + }, + }, + ], + "subscriptions": [ + { + "id": 7, + "destination_group": 10, + "sensor_group": { + "id": 55, + "sample_interval": 1000, + }, + }, + { + "id": 10, + "destination_group": 2, + "sensor_group": { + "id": 55, + "sample_interval": 1000, + }, + }, + ], + }, + }, + ignore_provider_arg, + ) + self.execute_module( + changed=True, + commands=[ + "telemetry", + "no subscription 3", + "no subscription 5", + "no subscription 4", + "subscription 7", + "no snsr-grp 2 sample-interval 1000", + "no subscription 6", + "no sensor-group 56", + "no sensor-group 2", + "no destination-group 10", + "destination-group 2", + "no ip address 192.168.0.2 port 60001 protocol grpc encoding gpb", + "sensor-group 55", + "data-source NX-API", + "path sys/bgp depth 0 query-condition query_condition_xyz filter-condition filter_condition_xyz", + "subscription 10", + "dst-grp 2", + "snsr-grp 55 sample-interval 1000", + "subscription 7", + "snsr-grp 55 sample-interval 1000", + "no certificate /bootflash/server.key localhost", + "destination-profile", + "no use-compression gzip", + "no source-interface loopback55", + "use-vrf blue", + ], + ) + + def test_tms_replaced_idempotent_n9k(self): + # Assumes feature telemetry is enabled + # Modify vrf global config, remove default all other global config. + # destination-group 2 destination '192.168.0.1' idempotent + # destination-group 2 destination '192.168.0.2' remove + # remove all other destination-groups + # Modify sensor-group 55 and delete all others + # Modify subscription 7, add 10 and delete all others + self.execute_show_command.return_value = load_fixture("nxos_telemetry", "N9K.cfg") + self.get_platform_shortname.return_value = "N9K" + set_module_args( + { + "state": "replaced", + "config": { + "certificate": { + "key": "/bootflash/server.key", + "hostname": "localhost", + }, + "compression": "gzip", + "vrf": "management", + "source_interface": "loopback55", + "destination_groups": [ + { + "id": 2, + "destination": { + "ip": "192.168.0.1", + "port": 50001, + "protocol": "GRPC", + "encoding": "GPB", + }, + }, + { + "id": 2, + "destination": { + "ip": "192.168.0.2", + "port": 60001, + "protocol": "GRPC", + "encoding": "GPB", + }, + }, + { + "id": 10, + "destination": { + "ip": "192.168.0.1", + "port": 50001, + "protocol": "GRPC", + "encoding": "GPB", + }, + }, + { + "id": 10, + "destination": { + "ip": "192.168.0.2", + "port": 60001, + "protocol": "GRPC", + "encoding": "GPB", + }, + }, + ], + "sensor_groups": [ + { + "id": 2, + "data_source": "DME", + "path": {"name": "boo", "depth": 0}, + }, + { + "id": 2, + "path": { + "name": "sys/ospf", + "depth": 0, + "query_condition": "qc", + "filter_condition": "fc", + }, + }, + {"id": 2, "path": {"name": "interfaces", "depth": 0}}, + {"id": 2, "path": {"name": "sys/bgp"}}, + { + "id": 2, + "path": { + "name": "sys/bgp/inst", + "depth": 0, + "query_condition": "foo", + "filter_condition": "foo", + }, + }, + { + "id": 2, + "path": { + "name": "sys/bgp/inst/dom-default/peer-[10.10.10.11]/ent-[10.10.10.11]", + }, + }, + { + "id": 2, + "path": { + "name": "sys/bgp/inst/dom-default/peer-[20.20.20.11]/ent-[20.20.20.11]", + }, + }, + { + "id": 2, + "path": { + "name": "too", + "depth": 0, + "filter_condition": "foo", + }, + }, + {"id": 55}, + {"id": 56, "data_source": "DME"}, + {"id": 56, "path": {"name": "environment"}}, + {"id": 56, "path": {"name": "interface"}}, + {"id": 56, "path": {"name": "resources"}}, + {"id": 56, "path": {"name": "vxlan"}}, + ], + "subscriptions": [ + {"id": 3}, + { + "id": 4, + "destination_group": 2, + "sensor_group": {"id": 2, "sample_interval": 1000}, + }, + {"id": 5, "destination_group": 2}, + { + "id": 5, + "sensor_group": {"id": 2, "sample_interval": 1000}, + }, + {"id": 6, "destination_group": 10}, + { + "id": 7, + "destination_group": 10, + "sensor_group": {"id": 2, "sample_interval": 1000}, + }, + ], + }, + }, + ignore_provider_arg, + ) + self.execute_module(changed=False, commands=[]) + + def test_telemetry_gathered(self): + self.execute_show_command.return_value = dedent( + """ + telemetry + certificate /bootflash/server.key localhost + destination-profile + use-vrf managements + use-compression gzip + source-interface loopback55 + destination-group 2 + ip address 192.168.0.1 port 50001 protocol gRPC encoding GPB + ip address 192.168.0.2 port 60001 protocol gRPC encoding GPB + """, + ) + self.get_platform_shortname.return_value = "N9K" + set_module_args(dict(state="gathered"), ignore_provider_arg) + + gathered = { + "certificate": { + "hostname": "localhost", + "key": "/bootflash/server.key", + }, + "compression": "gzip", + "source_interface": "loopback55", + "vrf": "managements", + "destination_groups": [ + { + "id": "2", + "destination": { + "ip": "192.168.0.1", + "port": "50001", + "protocol": "grpc", + "encoding": "gpb", + }, + }, + { + "id": "2", + "destination": { + "ip": "192.168.0.2", + "port": "60001", + "protocol": "grpc", + "encoding": "gpb", + }, + }, + ], + } + + result = self.execute_module(changed=False) + self.assertEqual(result["gathered"], gathered) + + def test_tms_names(self): + # TMS input with strings + self.execute_show_command.return_value = "" + self.get_platform_shortname.return_value = "N9K" + set_module_args( + dict( + config=dict( + destination_groups=[ + dict( + id="collector", + destination=dict( + ip="192.168.1.100", + port=50051, + protocol="gRPC", + encoding="GPB", + ), + ), + ], + sensor_groups=[ + dict( + id="dme_bgp", + data_source="DME", + path=dict( + name="sys/bd", + depth="unbounded", + ), + ), + ], + subscriptions=[ + dict( + id="collector_sub", + destination_group="collector", + sensor_group=dict( + id="dme_bgp", + sample_interval=1000, + ), + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + self.execute_module( + changed=True, + commands=[ + "feature telemetry", + "telemetry", + "destination-group collector", + "ip address 192.168.1.100 port 50051 protocol grpc encoding gpb", + "sensor-group dme_bgp", + "data-source DME", + "path sys/bd depth unbounded", + "subscription collector_sub", + "dst-grp collector", + "snsr-grp dme_bgp sample-interval 1000", + ], + ) + + def test_tms_names_idempotent(self): + # TMS input with strings + self.execute_show_command.return_value = dedent( + """\ + feature telemetry + telemetry + destination-group collector + ip address 192.168.1.100 port 50051 protocol grpc encoding gpb + sensor-group dme_bgp + data-source DME + path sys/bd depth unbounded + subscription collector_sub + dst-grp collector + snsr-grp dme_bgp sample-interval 1000 + """, + ) + self.get_platform_shortname.return_value = "N9K" + set_module_args( + dict( + config=dict( + destination_groups=[ + dict( + id="collector", + destination=dict( + ip="192.168.1.100", + port=50051, + protocol="gRPC", + encoding="GPB", + ), + ), + ], + sensor_groups=[ + dict( + id="dme_bgp", + data_source="DME", + path=dict( + name="sys/bd", + depth="unbounded", + ), + ), + ], + subscriptions=[ + dict( + id="collector_sub", + destination_group="collector", + sensor_group=dict( + id="dme_bgp", + sample_interval=1000, + ), + ), + ], + ), + state="merged", + ), + ignore_provider_arg, + ) + self.execute_module(changed=False, commands=[]) + + +def build_args(data, type, state=None, check_mode=None): + if state is None: + state = "merged" + if check_mode is None: + check_mode = False + args = { + "state": state, + "_ansible_check_mode": check_mode, + "config": {type: data}, + } + return args diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_user.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_user.py new file mode 100644 index 00000000..b634ca4f --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_user.py @@ -0,0 +1,102 @@ +# (c) 2020 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from ansible_collections.cisco.nxos.plugins.modules import nxos_user +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, set_module_args + + +ignore_provider_arg = True + + +class TestNxosUserModule(TestNxosModule): + module = nxos_user + + def setUp(self): + super(TestNxosUserModule, self).setUp() + + self.mock_run_commands = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_user.run_commands", + ) + self.run_commands = self.mock_run_commands.start() + + self.mock_load_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_user.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_get_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_user.get_config", + ) + self.get_config = self.mock_get_config.start() + + self.mock_get_device_info = patch( + "ansible_collections.cisco.nxos.plugins.cliconf.nxos.Cliconf.get_device_info", + ) + self.get_device_info = self.mock_get_device_info.start() + + def tearDown(self): + super(TestNxosUserModule, self).tearDown() + self.mock_run_commands.stop() + self.mock_load_config.stop() + self.mock_get_config.stop() + self.mock_get_device_info.stop() + + def test_mds(self): + self.get_config.return_value = "" + self.run_commands.return_value = [ + { + "TABLE_template": { + "ROW_template": [ + { + "usr_name": "admin", + "expire_date": "this user account has no expiry date", + "TABLE_role": {"ROW_role": {"role": "network-admin"}}, + }, + { + "usr_name": "ansible-test-1", + "expire_date": "this user account has no expiry date", + "TABLE_role": {"ROW_role": [{"role": "priv-10"}]}, + }, + ], + }, + }, + ] + self.get_device_info.return_value = { + "network_os": "nxos", + "network_os_version": "8.4(2b)", + "network_os_model": 'MDS 9148S 16G 48 FC (1 Slot) Chassis ("2/4/8/16 Gbps FC/Supervisor")', + "network_os_hostname": "sw109-Mini", + "network_os_image": "bootflash:///m9100-s5ek9-mz.8.4.2b.bin", + "network_os_platform": "DS-C9710", + } + set_module_args(dict(name="ansible-test-2", configured_password="ansible")) + self.execute_module( + changed=True, + commands=[ + "username ansible-test-2", + "username ansible-test-2 password ansible", + ], + ) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_vlans.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_vlans.py new file mode 100644 index 00000000..97870e76 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_vlans.py @@ -0,0 +1,283 @@ +# (c) 2019 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from ansible_collections.cisco.nxos.plugins.modules import nxos_vlans +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, load_fixture, set_module_args + + +ignore_provider_arg = True + + +class TestNxosVlansModule(TestNxosModule): + module = nxos_vlans + + def setUp(self): + super(TestNxosVlansModule, self).setUp() + + self.mock_FACT_LEGACY_SUBSETS = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.facts.facts.FACT_LEGACY_SUBSETS", + ) + self.FACT_LEGACY_SUBSETS = self.mock_FACT_LEGACY_SUBSETS.start() + + self.mock_get_resource_connection_config = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base.get_resource_connection", + ) + self.get_resource_connection_config = self.mock_get_resource_connection_config.start() + + self.mock_get_resource_connection_facts = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection", + ) + self.get_resource_connection_facts = self.mock_get_resource_connection_facts.start() + + self.mock_edit_config = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.config.vlans.vlans.Vlans.edit_config", + ) + self.edit_config = self.mock_edit_config.start() + + self.mock_get_device_data = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.facts.vlans.vlans.VlansFacts.get_device_data", + ) + self.get_device_data = self.mock_get_device_data.start() + + self.mock_get_platform = patch( + "ansible_collections.cisco.nxos.plugins.module_utils.network.nxos.config.vlans.vlans.Vlans.get_platform", + ) + self.get_platform = self.mock_get_platform.start() + + def tearDown(self): + super(TestNxosVlansModule, self).tearDown() + self.mock_FACT_LEGACY_SUBSETS.stop() + self.mock_get_resource_connection_config.stop() + self.mock_get_resource_connection_facts.stop() + self.mock_edit_config.stop() + self.mock_get_platform.stop() + + def prepare(self, test=""): + if test == "_no_facts": + self.get_device_data.side_effect = self.load_from_file_no_facts + else: + self.get_device_data.side_effect = self.load_from_file + self.get_platform.return_value = "N9K-NXOSv" + + def load_from_file(self, *args, **kwargs): + cmd = args[1] + filename = str(cmd).split(" | ", 1)[0].replace(" ", "_") + return load_fixture("nxos_vlans", filename) + + def load_from_file_no_facts(self, *args, **kwargs): + cmd = args[1] + filename = str(cmd).split(" | ", 1)[0].replace(" ", "_") + filename += "_no_facts" + return load_fixture("nxos_vlans", filename) + + def test_1(self): + """ + **NOTE** This config is for reference only! See fixtures files for real data. + vlan 1,3-5,8 + vlan 3 + name test-vlan3 + !Note:vlan 4 is present with default settings + vlan 5 + shutdown + name test-changeme + mode fabricpath + state suspend + vn-segment 942 + !Note:vlan 7 is not present + vlan 8 + shutdown + name test-changeme-not + state suspend + """ + self.prepare() + self.get_platform.return_value = "N7K-Cxxx" + + playbook = dict( + config=[ + dict(vlan_id=4), + dict(vlan_id=5, mapped_vni=555, mode="ce"), + dict(vlan_id=7, mapped_vni=777, name="test-vlan7", enabled=False), + dict(vlan_id="8", state="active", name="test-changeme-not"), + # vlan 3 is not present in playbook. + ], + ) + + merged = [ + # Update existing device states with any differences in the playbook. + "vlan 5", + "vn-segment 555", + "mode ce", + "vlan 7", + "vn-segment 777", + "name test-vlan7", + "shutdown", + "vlan 8", + "state active", + ] + playbook["state"] = "merged" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=merged) + + self.get_platform.return_value = "N9K-NXOSv" + deleted = [ + # Reset existing device state to default values. Scope is limited to + # objects in the play when the 'config' key is specified. For vlans + # this means deleting each vlan listed in the playbook and ignoring + # any play attrs other than 'vlan_id'. + "no vlan 4", + "no vlan 5", + "no vlan 8", + ] + playbook["state"] = "deleted" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=deleted) + + self.get_platform.return_value = "N5K-Cxxx" + overridden = [ + # The play is the source of truth. Similar to replaced but the scope + # includes all objects on the device; i.e. it will also reset state + # on objects not found in the play. + "no vlan 1", + "no vlan 3", + "vlan 5", + "mode ce", + "vn-segment 555", + "no state", + "no shutdown", + "no name", + "vlan 8", + "no shutdown", + "state active", + "vlan 7", + "name test-vlan7", + "shutdown", + "vn-segment 777", + ] + playbook["state"] = "overridden" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=overridden) + + self.get_platform.return_value = "N7K-NXOSv" + replaced = [ + # Scope is limited to objects in the play. + # replaced should ignore existing vlan 3. + "vlan 5", + "mode ce", + "vn-segment 555", + "no state", + "no shutdown", + "no name", + "vlan 7", + "shutdown", + "name test-vlan7", + "vn-segment 777", + "vlan 8", + "no shutdown", + "state active", + ] + playbook["state"] = "replaced" + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=replaced) + + def test_2(self): + # Test when no 'config' key is used in playbook. + self.prepare() + deleted = [ + "no vlan 1", + "no vlan 3", + "no vlan 4", + "no vlan 5", + "no vlan 8", + ] + playbook = dict(state="deleted") + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=deleted) + + for test_state in ["merged", "replaced", "overridden"]: + set_module_args(dict(state=test_state), ignore_provider_arg) + self.execute_module(failed=True) + + def test_3(self): + # Test no facts returned + self.prepare(test="_no_facts") + playbook = dict(state="deleted") + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=False) + + def test_4(self): + self.prepare() + # Misc tests to hit codepaths highlighted by code coverage tool as missed. + playbook = dict(config=[dict(vlan_id=8, enabled=True)]) + replaced = [ + # Update existing device states with any differences in the playbook. + "vlan 8", + "no shutdown", + "no state", + "no name", + ] + playbook["state"] = "replaced" + playbook["_ansible_check_mode"] = True + set_module_args(playbook, ignore_provider_arg) + self.execute_module(changed=True, commands=replaced) + + def test_5(self): + """ + Idempotency test + """ + + self.prepare() + playbook = dict( + config=[ + dict(vlan_id=1, name="default", enabled=True), + dict(vlan_id=3, name="test-vlan3", enabled=True), + dict(vlan_id=4, enabled=True), + dict( + vlan_id=5, + name="test-changeme", + mapped_vni=942, + state="suspend", + enabled=False, + ), + dict( + vlan_id=8, + name="test-changeme-not", + state="suspend", + enabled=False, + ), + ], + ) + + playbook["state"] = "merged" + set_module_args(playbook, ignore_provider_arg) + r = self.execute_module(changed=False) + + playbook["state"] = "overridden" + set_module_args(playbook, ignore_provider_arg) + r = self.execute_module(changed=False) + + playbook["state"] = "replaced" + set_module_args(playbook, ignore_provider_arg) + r = self.execute_module(changed=False) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_vpc.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_vpc.py new file mode 100644 index 00000000..a74525e8 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_vpc.py @@ -0,0 +1,216 @@ +# (c) 2016 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from ansible_collections.cisco.nxos.plugins.modules import nxos_vpc +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, load_fixture, set_module_args + + +class TestNxosVpcModule(TestNxosModule): + module = nxos_vpc + + def setUp(self): + super(TestNxosVpcModule, self).setUp() + + self.mock_get_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_vpc.get_config", + ) + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_vpc.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_run_commands = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_vpc.run_commands", + ) + self.run_commands = self.mock_run_commands.start() + + def tearDown(self): + super(TestNxosVpcModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + self.mock_run_commands.stop() + + def load_fixtures(self, commands=None, device=""): + def load_from_file(*args, **kwargs): + module, commands = args + output = list() + + for command in commands: + filename = str(command).split(" | ", 1)[0].replace(" ", "_") + output.append(load_fixture("nxos_vpc", filename)) + return output + + def vrf_load_from_file(*args, **kwargs): + """Load vpc output for vrf tests""" + module, commands = args + output = list() + for command in commands: + filename = "vrf_test_" + str(command).split(" | ", 1)[0].replace(" ", "_") + output.append(load_fixture("nxos_vpc", filename)) + return output + + self.load_config.return_value = None + if device == "_vrf_test": + self.run_commands.side_effect = vrf_load_from_file + else: + self.run_commands.side_effect = load_from_file + + def test_nxos_vpc_present(self): + set_module_args( + dict( + domain=100, + role_priority=32667, + system_priority=2000, + pkl_dest="192.168.100.4", + pkl_src="10.1.100.20", + peer_gw=True, + auto_recovery=True, + ), + ) + self.execute_module( + changed=True, + commands=[ + "vpc domain 100", + "terminal dont-ask", + "role priority 32667", + "system-priority 2000", + "peer-keepalive destination 192.168.100.4 source 10.1.100.20", + "peer-gateway", + "auto-recovery", + ], + ) + + def test_nxos_vpc_vrf_1(self): + # No vrf -> vrf 'default' + set_module_args( + dict( + domain=100, + pkl_dest="192.168.1.1", + pkl_src="10.1.1.1", + pkl_vrf="default", + ), + ) + self.execute_module( + changed=True, + commands=[ + "vpc domain 100", + "peer-keepalive destination 192.168.1.1 source 10.1.1.1 vrf default", + ], + ) + + def test_nxos_vpc_vrf_2(self): + # vrf 'my_vrf'-> vrf 'test-vrf' + # All pkl commands should be present + self.get_config.return_value = load_fixture("nxos_vpc", "vrf_test_vpc_config") + set_module_args( + dict( + domain=100, + pkl_dest="192.168.1.1", + pkl_src="10.1.1.1", + pkl_vrf="test-vrf", + ), + ) + self.execute_module( + changed=True, + device="_vrf_test", + commands=[ + "vpc domain 100", + "peer-keepalive destination 192.168.1.1 source 10.1.1.1 vrf test-vrf", + ], + ) + + def test_nxos_vpc_vrf_3(self): + # vrf 'my_vrf' -> vrf 'obviously-different-vrf' + # Existing pkl_src should be retained even though playbook does not specify it + self.get_config.return_value = load_fixture("nxos_vpc", "vrf_test_vpc_config") + set_module_args( + dict( + domain=100, + pkl_dest="192.168.1.1", + pkl_vrf="obviously-different-vrf", + ), + ) + self.execute_module( + changed=True, + device="_vrf_test", + commands=[ + "vpc domain 100", + "peer-keepalive destination 192.168.1.1 source 10.1.1.1 vrf obviously-different-vrf", + ], + ) + + def test_nxos_vpc_vrf_4(self): + # vrf 'my_vrf'-> vrf 'management' + # 'management' is the default value for vrf, it will not nvgen + self.get_config.return_value = load_fixture("nxos_vpc", "vrf_test_vpc_config") + set_module_args(dict(domain=100, pkl_dest="192.168.1.1", pkl_vrf="management")) + self.execute_module( + changed=True, + device="_vrf_test", + commands=[ + "vpc domain 100", + "peer-keepalive destination 192.168.1.1 source 10.1.1.1 vrf management", + ], + ) + + def test_nxos_vpc_vrf_5(self): + # vrf 'my_vrf' -> vrf 'my_vrf' (idempotence) + self.get_config.return_value = load_fixture("nxos_vpc", "vrf_test_vpc_config") + set_module_args( + dict( + domain=100, + pkl_dest="192.168.1.1", + pkl_src="10.1.1.1", + pkl_vrf="my_vrf", + ), + ) + self.execute_module(changed=False, device="_vrf_test") + + def test_nxos_vpc_vrf_6(self): + # vrf 'my_vrf' -> absent tests + self.get_config.return_value = load_fixture("nxos_vpc", "vrf_test_vpc_config") + set_module_args(dict(domain=100, state="absent")) + self.execute_module( + changed=True, + device="_vrf_test", + commands=["terminal dont-ask", "no vpc domain 100"], + ) + + def test_nxos_vpc_vrf_7(self): + # dest 192.168.1.1 source 10.1.1.1 vrf my_vrf -> (dest only) (idempotence) + # pkl_src/pkl_vrf not in playbook but exists on device. + self.get_config.return_value = load_fixture("nxos_vpc", "vrf_test_vpc_config") + set_module_args(dict(domain=100, pkl_dest="192.168.1.1")) + self.execute_module(changed=False, device="_vrf_test") + + def test_nxos_vpc_vrf_8(self): + # dest 192.168.1.1 source 10.1.1.1 vrf my_vrf -> (optional vrf) (idempotence) + # pkl_src not in playbook but exists on device. + self.get_config.return_value = load_fixture("nxos_vpc", "vrf_test_vpc_config") + set_module_args(dict(domain=100, pkl_dest="192.168.1.1", pkl_vrf="my_vrf")) + self.execute_module(changed=False, device="_vrf_test") diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_vpc_interface.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_vpc_interface.py new file mode 100644 index 00000000..de7ad79b --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_vpc_interface.py @@ -0,0 +1,78 @@ +# (c) 2016 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from ansible_collections.cisco.nxos.plugins.modules import nxos_vpc_interface +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, load_fixture, set_module_args + + +class TestNxosVpcModule(TestNxosModule): + module = nxos_vpc_interface + + def setUp(self): + super(TestNxosVpcModule, self).setUp() + + self.mock_load_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_vpc_interface.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_get_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_vpc_interface.get_config", + ) + self.get_config = self.mock_get_config.start() + + self.mock_run_commands = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_vpc_interface.run_commands", + ) + self.run_commands = self.mock_run_commands.start() + + def tearDown(self): + super(TestNxosVpcModule, self).tearDown() + self.mock_load_config.stop() + self.mock_get_config.stop() + self.mock_run_commands.stop() + + def load_fixtures(self, commands=None, device=""): + def load_from_file(*args, **kwargs): + module, commands = args + output = list() + for command in commands: + filename = str(command).split(" | ", 1)[0].replace(" ", "_") + output.append(load_fixture("nxos_vpc_interface", filename)) + return output + + self.run_commands.side_effect = load_from_file + self.load_config.return_value = None + + def test_nxos_vpc_interface_absent(self): + set_module_args(dict(portchannel=10, vpc=100, state="absent")) + result = self.execute_module(changed=True) + self.assertEqual(result["commands"], ["interface port-channel10", "no vpc"]) + + def test_nxos_vpc_interface_present(self): + set_module_args(dict(portchannel=20, vpc=200, state="present")) + result = self.execute_module(changed=True) + self.assertEqual(result["commands"], ["interface port-channel20", "vpc 200"]) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_vrf.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_vrf.py new file mode 100644 index 00000000..8f2a2ae1 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_vrf.py @@ -0,0 +1,86 @@ +# (c) 2016 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from ansible_collections.cisco.nxos.plugins.modules import nxos_vrf +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, load_fixture, set_module_args + + +class TestNxosVrfModule(TestNxosModule): + module = nxos_vrf + + def setUp(self): + super(TestNxosVrfModule, self).setUp() + + self.mock_load_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_vrf.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_run_commands = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_vrf.run_commands", + ) + self.run_commands = self.mock_run_commands.start() + + def tearDown(self): + super(TestNxosVrfModule, self).tearDown() + self.mock_load_config.stop() + self.mock_run_commands.stop() + + def load_fixtures(self, commands=None, device=""): + def load_from_file(*args, **kwargs): + module, commands = args + output = list() + + for command in commands: + if isinstance(command, dict): + command = command["command"] + filename = str(command).split(" | ", 1)[0].replace(" ", "_") + output.append(load_fixture("nxos_vrf", filename)) + return output + + self.load_config.return_value = None + self.run_commands.side_effect = load_from_file + + def test_nxos_vrf_present(self): + set_module_args(dict(vrf="ntc", state="present", admin_state="up")) + self.execute_module(changed=True, commands=["vrf context ntc", "no shutdown", "exit"]) + + def test_nxos_vrf_present_no_change(self): + set_module_args(dict(vrf="management", state="present", admin_state="up")) + self.execute_module(changed=False, commands=[]) + + def test_nxos_vrf_absent(self): + set_module_args(dict(vrf="management", state="absent")) + self.execute_module(changed=True, commands=["no vrf context management"]) + + def test_nxos_vrf_absent_no_change(self): + set_module_args(dict(vrf="ntc", state="absent")) + self.execute_module(changed=False, commands=[]) + + def test_nxos_vrf_default(self): + set_module_args(dict(vrf="default")) + result = self.execute_module(failed=True) + self.assertEqual(result["msg"], "cannot use default as name of a VRF") diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_vrf_af.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_vrf_af.py new file mode 100644 index 00000000..bfc2adef --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_vrf_af.py @@ -0,0 +1,1107 @@ +# (c) 2016 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from ansible_collections.cisco.nxos.plugins.modules import nxos_vrf_af +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, load_fixture, set_module_args + + +class TestNxosVrfafModule(TestNxosModule): + module = nxos_vrf_af + + def setUp(self): + super(TestNxosVrfafModule, self).setUp() + + self.mock_load_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_vrf_af.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_get_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_vrf_af.get_config", + ) + self.get_config = self.mock_get_config.start() + + self.mock_get_capabilities = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_vrf_af.get_capabilities", + ) + self.get_capabilities = self.mock_get_capabilities.start() + self.get_capabilities.return_value = {"device_info": {"network_os_platform": "N7K-C7018"}} + + def tearDown(self): + super(TestNxosVrfafModule, self).tearDown() + self.mock_load_config.stop() + self.mock_get_config.stop() + self.mock_get_capabilities.stop() + + def load_fixtures(self, commands=None, device=""): + self.get_config.return_value = load_fixture("nxos_vrf_af", "config.cfg") + self.load_config.return_value = None + + def test_nxos_vrf_af_present_current_non_existing(self): + set_module_args(dict(vrf="vrf0", afi="ipv4", state="present")) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + ["vrf context vrf0", "address-family ipv4 unicast"], + ) + + def test_nxos_vrf_af_present_current_existing(self): + set_module_args(dict(vrf="vrf1", afi="ipv4", state="present")) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_vrf_af_absent_current_non_existing(self): + set_module_args(dict(vrf="vrf0", afi="ipv4", state="absent")) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_vrf_af_absent_current_existing(self): + set_module_args(dict(vrf="vrf1", afi="ipv4", state="absent")) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + ["vrf context vrf1", "no address-family ipv4 unicast"], + ) + + def test_nxos_vrf_af_auto_evpn_route_target_present_current_existing(self): + set_module_args(dict(vrf="vrf11", afi="ipv4", route_target_both_auto_evpn=True)) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_vrf_af_auto_evpn_route_target_present_current_non_existing( + self, + ): + set_module_args(dict(vrf="vrf10", afi="ipv4", route_target_both_auto_evpn=True)) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "vrf context vrf10", + "address-family ipv4 unicast", + "route-target both auto evpn", + ], + ) + + def test_nxos_vrf_af_auto_evpn_route_target_absent_current_existing(self): + set_module_args(dict(vrf="vrf11", afi="ipv4", route_target_both_auto_evpn=False)) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "vrf context vrf11", + "address-family ipv4 unicast", + "no route-target both auto evpn", + ], + ) + + def test_nxos_vrf_af_auto_evpn_route_target_absent_current_non_existing( + self, + ): + set_module_args(dict(vrf="vrf1", afi="ipv4", route_target_both_auto_evpn=False)) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_vrf_af_route_target_import_present_current_non_existing( + self, + ): + set_module_args( + dict( + vrf="vrf1", + afi="ipv4", + route_targets=[ + { + "rt": "65000:1000", + "direction": "import", + "state": "present", + }, + ], + ), + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "vrf context vrf1", + "address-family ipv4 unicast", + "route-target import 65000:1000", + ], + ) + + def test_nxos_vrf_af_route_target_default_direction_present_current_non_existing( + self, + ): + set_module_args( + dict( + vrf="vrf1", + afi="ipv4", + route_targets=[{"rt": "65000:1000", "state": "present"}], + ), + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "vrf context vrf1", + "address-family ipv4 unicast", + "route-target import 65000:1000", + "route-target export 65000:1000", + ], + ) + + def test_nxos_vrf_af_route_target_import_present_current_existing(self): + set_module_args( + dict( + vrf="vrf21", + afi="ipv4", + route_targets=[ + { + "rt": "65000:1000", + "direction": "import", + "state": "present", + }, + ], + ), + ) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_vrf_af_route_target_default_direction_present_current_existing( + self, + ): + set_module_args( + dict( + vrf="vrf21", + afi="ipv4", + route_targets=[{"rt": "65000:1000", "state": "present"}], + ), + ) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_vrf_af_route_target_multi_import_present_current_non_existing( + self, + ): + set_module_args( + dict( + vrf="vrf1", + afi="ipv4", + route_targets=[ + { + "rt": "65000:1000", + "direction": "import", + "state": "present", + }, + { + "rt": "65001:1000", + "direction": "import", + "state": "present", + }, + { + "rt": "65002:1000", + "direction": "import", + "state": "present", + }, + ], + ), + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "vrf context vrf1", + "address-family ipv4 unicast", + "route-target import 65000:1000", + "route-target import 65001:1000", + "route-target import 65002:1000", + ], + ) + + def test_nxos_vrf_af_route_target_multi_import_present_current_existing( + self, + ): + set_module_args( + dict( + vrf="vrf21", + afi="ipv4", + route_targets=[ + { + "rt": "65000:1000", + "direction": "import", + "state": "present", + }, + { + "rt": "65001:1000", + "direction": "import", + "state": "present", + }, + { + "rt": "65002:1000", + "direction": "import", + "state": "present", + }, + ], + ), + ) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_vrf_af_route_target_import_absent_current_non_existing(self): + set_module_args( + dict( + vrf="vrf1", + afi="ipv4", + route_targets=[ + { + "rt": "65000:1000", + "direction": "import", + "state": "absent", + }, + ], + ), + ) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_vrf_af_route_target_import_absent_current_existing(self): + set_module_args( + dict( + vrf="vrf21", + afi="ipv4", + route_targets=[ + { + "rt": "65000:1000", + "direction": "import", + "state": "absent", + }, + ], + ), + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "vrf context vrf21", + "address-family ipv4 unicast", + "no route-target import 65000:1000", + ], + ) + + def test_nxos_vrf_af_route_target_multi_import_absent_current_non_existing( + self, + ): + set_module_args( + dict( + vrf="vrf1", + afi="ipv4", + route_targets=[ + { + "rt": "65000:1000", + "direction": "import", + "state": "absent", + }, + { + "rt": "65001:1000", + "direction": "import", + "state": "absent", + }, + { + "rt": "65002:1000", + "direction": "import", + "state": "absent", + }, + ], + ), + ) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_vrf_af_route_target_multi_import_absent_current_existing( + self, + ): + set_module_args( + dict( + vrf="vrf21", + afi="ipv4", + route_targets=[ + { + "rt": "65000:1000", + "direction": "import", + "state": "absent", + }, + { + "rt": "65001:1000", + "direction": "import", + "state": "absent", + }, + { + "rt": "65002:1000", + "direction": "import", + "state": "absent", + }, + ], + ), + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "vrf context vrf21", + "address-family ipv4 unicast", + "no route-target import 65000:1000", + "no route-target import 65001:1000", + "no route-target import 65002:1000", + ], + ) + + def test_nxos_vrf_af_route_target_multi_import_absent_current_mix(self): + set_module_args( + dict( + vrf="vrf21", + afi="ipv4", + route_targets=[ + { + "rt": "65000:1000", + "direction": "import", + "state": "present", + }, + { + "rt": "65001:1000", + "direction": "import", + "state": "present", + }, + { + "rt": "65002:1000", + "direction": "import", + "state": "absent", + }, + { + "rt": "65003:1000", + "direction": "import", + "state": "present", + }, + { + "rt": "65004:1000", + "direction": "import", + "state": "absent", + }, + ], + ), + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "vrf context vrf21", + "address-family ipv4 unicast", + "no route-target import 65002:1000", + "route-target import 65003:1000", + ], + ) + + def test_nxos_vrf_af_route_target_export_present_current_non_existing( + self, + ): + set_module_args( + dict( + vrf="vrf1", + afi="ipv4", + route_targets=[ + { + "rt": "65000:1000", + "direction": "export", + "state": "present", + }, + ], + ), + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "vrf context vrf1", + "address-family ipv4 unicast", + "route-target export 65000:1000", + ], + ) + + def test_nxos_vrf_af_route_target_export_present_current_existing(self): + set_module_args( + dict( + vrf="vrf21", + afi="ipv4", + route_targets=[ + { + "rt": "65000:1000", + "direction": "export", + "state": "present", + }, + ], + ), + ) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_vrf_af_route_target_multi_export_present_current_non_existing( + self, + ): + set_module_args( + dict( + vrf="vrf1", + afi="ipv4", + route_targets=[ + { + "rt": "65000:1000", + "direction": "export", + "state": "present", + }, + { + "rt": "65001:1000", + "direction": "export", + "state": "present", + }, + { + "rt": "65002:1000", + "direction": "export", + "state": "present", + }, + ], + ), + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "vrf context vrf1", + "address-family ipv4 unicast", + "route-target export 65000:1000", + "route-target export 65001:1000", + "route-target export 65002:1000", + ], + ) + + def test_nxos_vrf_af_route_target_multi_export_present_current_existing( + self, + ): + set_module_args( + dict( + vrf="vrf21", + afi="ipv4", + route_targets=[ + { + "rt": "65000:1000", + "direction": "export", + "state": "present", + }, + { + "rt": "65001:1000", + "direction": "export", + "state": "present", + }, + { + "rt": "65002:1000", + "direction": "export", + "state": "present", + }, + ], + ), + ) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_vrf_af_route_target_export_absent_current_non_existing(self): + set_module_args( + dict( + vrf="vrf1", + afi="ipv4", + route_targets=[ + { + "rt": "65000:1000", + "direction": "export", + "state": "absent", + }, + ], + ), + ) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_vrf_af_route_target_export_absent_current_existing(self): + set_module_args( + dict( + vrf="vrf21", + afi="ipv4", + route_targets=[ + { + "rt": "65000:1000", + "direction": "export", + "state": "absent", + }, + ], + ), + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "vrf context vrf21", + "address-family ipv4 unicast", + "no route-target export 65000:1000", + ], + ) + + def test_nxos_vrf_af_route_target_multi_export_absent_current_non_existing( + self, + ): + set_module_args( + dict( + vrf="vrf1", + afi="ipv4", + route_targets=[ + { + "rt": "65000:1000", + "direction": "export", + "state": "absent", + }, + { + "rt": "65001:1000", + "direction": "export", + "state": "absent", + }, + { + "rt": "65002:1000", + "direction": "export", + "state": "absent", + }, + ], + ), + ) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_vrf_af_route_target_multi_export_absent_current_existing( + self, + ): + set_module_args( + dict( + vrf="vrf21", + afi="ipv4", + route_targets=[ + { + "rt": "65000:1000", + "direction": "export", + "state": "absent", + }, + { + "rt": "65001:1000", + "direction": "export", + "state": "absent", + }, + { + "rt": "65002:1000", + "direction": "export", + "state": "absent", + }, + ], + ), + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "vrf context vrf21", + "address-family ipv4 unicast", + "no route-target export 65000:1000", + "no route-target export 65001:1000", + "no route-target export 65002:1000", + ], + ) + + def test_nxos_vrf_af_route_target_multi_export_absent_current_mix(self): + set_module_args( + dict( + vrf="vrf21", + afi="ipv4", + route_targets=[ + { + "rt": "65000:1000", + "direction": "export", + "state": "present", + }, + { + "rt": "65001:1000", + "direction": "export", + "state": "present", + }, + { + "rt": "65002:1000", + "direction": "export", + "state": "absent", + }, + { + "rt": "65003:1000", + "direction": "export", + "state": "present", + }, + { + "rt": "65004:1000", + "direction": "export", + "state": "absent", + }, + ], + ), + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "vrf context vrf21", + "address-family ipv4 unicast", + "no route-target export 65002:1000", + "route-target export 65003:1000", + ], + ) + + def test_nxos_vrf_af_route_target_both_present_current_non_existing(self): + set_module_args( + dict( + vrf="vrf1", + afi="ipv4", + route_targets=[ + { + "rt": "65000:1000", + "direction": "both", + "state": "present", + }, + ], + ), + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "vrf context vrf1", + "address-family ipv4 unicast", + "route-target import 65000:1000", + "route-target export 65000:1000", + ], + ) + + def test_nxos_vrf_af_route_target_both_present_current_existing(self): + set_module_args( + dict( + vrf="vrf21", + afi="ipv4", + route_targets=[ + { + "rt": "65000:1000", + "direction": "both", + "state": "present", + }, + ], + ), + ) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_vrf_af_route_target_multi_both_present_current_non_existing( + self, + ): + set_module_args( + dict( + vrf="vrf1", + afi="ipv4", + route_targets=[ + { + "rt": "65000:1000", + "direction": "both", + "state": "present", + }, + { + "rt": "65001:1000", + "direction": "both", + "state": "present", + }, + { + "rt": "65002:1000", + "direction": "both", + "state": "present", + }, + ], + ), + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "vrf context vrf1", + "address-family ipv4 unicast", + "route-target import 65000:1000", + "route-target export 65000:1000", + "route-target import 65001:1000", + "route-target export 65001:1000", + "route-target import 65002:1000", + "route-target export 65002:1000", + ], + ) + + def test_nxos_vrf_af_route_target_multi_both_present_current_existing( + self, + ): + set_module_args( + dict( + vrf="vrf21", + afi="ipv4", + route_targets=[ + { + "rt": "65000:1000", + "direction": "both", + "state": "present", + }, + { + "rt": "65001:1000", + "direction": "both", + "state": "present", + }, + { + "rt": "65002:1000", + "direction": "both", + "state": "present", + }, + ], + ), + ) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_vrf_af_route_target_both_absent_current_non_existing(self): + set_module_args( + dict( + vrf="vrf1", + afi="ipv4", + route_targets=[ + { + "rt": "65000:1000", + "direction": "both", + "state": "absent", + }, + ], + ), + ) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_vrf_af_route_target_both_absent_current_existing(self): + set_module_args( + dict( + vrf="vrf21", + afi="ipv4", + route_targets=[ + { + "rt": "65000:1000", + "direction": "both", + "state": "absent", + }, + ], + ), + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "vrf context vrf21", + "address-family ipv4 unicast", + "no route-target import 65000:1000", + "no route-target export 65000:1000", + ], + ) + + def test_nxos_vrf_af_route_target_multi_both_absent_current_non_existing( + self, + ): + set_module_args( + dict( + vrf="vrf1", + afi="ipv4", + route_targets=[ + { + "rt": "65000:1000", + "direction": "both", + "state": "absent", + }, + { + "rt": "65001:1000", + "direction": "both", + "state": "absent", + }, + { + "rt": "65002:1000", + "direction": "both", + "state": "absent", + }, + ], + ), + ) + result = self.execute_module(changed=False) + self.assertEqual(result["commands"], []) + + def test_nxos_vrf_af_route_target_multi_both_absent_current_existing(self): + set_module_args( + dict( + vrf="vrf21", + afi="ipv4", + route_targets=[ + { + "rt": "65000:1000", + "direction": "both", + "state": "absent", + }, + { + "rt": "65001:1000", + "direction": "both", + "state": "absent", + }, + { + "rt": "65002:1000", + "direction": "both", + "state": "absent", + }, + ], + ), + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "vrf context vrf21", + "address-family ipv4 unicast", + "no route-target import 65000:1000", + "no route-target export 65000:1000", + "no route-target import 65001:1000", + "no route-target export 65001:1000", + "no route-target import 65002:1000", + "no route-target export 65002:1000", + ], + ) + + def test_nxos_vrf_af_route_target_multi_both_absent_current_mix(self): + set_module_args( + dict( + vrf="vrf21", + afi="ipv4", + route_targets=[ + { + "rt": "65000:1000", + "direction": "both", + "state": "present", + }, + { + "rt": "65001:1000", + "direction": "both", + "state": "present", + }, + { + "rt": "65002:1000", + "direction": "both", + "state": "absent", + }, + { + "rt": "65003:1000", + "direction": "both", + "state": "present", + }, + { + "rt": "65004:1000", + "direction": "both", + "state": "absent", + }, + ], + ), + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "vrf context vrf21", + "address-family ipv4 unicast", + "no route-target import 65002:1000", + "no route-target export 65002:1000", + "route-target import 65003:1000", + "route-target export 65003:1000", + ], + ) + + def test_nxos_vrf_af_route_target_multi_both_current_only_import_or_export( + self, + ): + set_module_args( + dict( + vrf="vrf31", + afi="ipv4", + route_targets=[ + { + "rt": "65000:1000", + "direction": "both", + "state": "present", + }, + { + "rt": "65001:1000", + "direction": "both", + "state": "present", + }, + { + "rt": "65002:1000", + "direction": "both", + "state": "absent", + }, + { + "rt": "65003:1000", + "direction": "both", + "state": "absent", + }, + ], + ), + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "vrf context vrf31", + "address-family ipv4 unicast", + "route-target export 65000:1000", + "route-target import 65001:1000", + "no route-target import 65002:1000", + "no route-target export 65003:1000", + ], + ) + + def test_nxos_vrf_af_route_target_multi_direction_current_only_import_or_export( + self, + ): + set_module_args( + dict( + vrf="vrf31", + afi="ipv4", + route_targets=[ + { + "rt": "65000:1000", + "direction": "both", + "state": "present", + }, + {"rt": "65001:1000", "state": "present"}, + { + "rt": "65002:1000", + "direction": "export", + "state": "absent", + }, + { + "rt": "65003:1000", + "direction": "export", + "state": "absent", + }, + ], + ), + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "vrf context vrf31", + "address-family ipv4 unicast", + "route-target export 65000:1000", + "route-target import 65001:1000", + "no route-target export 65003:1000", + ], + ) + + def test_nxos_vrf_af_auto_evpn_route_target_and_manual_route_target(self): + set_module_args( + dict( + vrf="vrf1", + afi="ipv4", + route_target_both_auto_evpn=True, + route_targets=[ + { + "rt": "65000:1000", + "direction": "both", + "state": "present", + }, + ], + ), + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "vrf context vrf1", + "address-family ipv4 unicast", + "route-target both auto evpn", + "route-target import 65000:1000", + "route-target export 65000:1000", + ], + ) + + def test_nxos_vrf_af_auto_evpn_route_target_and_manual_route_targets_with_absent_vrf( + self, + ): + set_module_args( + dict( + vrf="vrf1", + afi="ipv4", + state="absent", + route_target_both_auto_evpn=True, + route_targets=[ + { + "rt": "65000:1000", + "direction": "both", + "state": "present", + }, + ], + ), + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + ["vrf context vrf1", "no address-family ipv4 unicast"], + ) + + def test_nxos_vrf_af_both_auto_N9K(self): + self.get_capabilities.return_value = {"device_info": {"network_os_platform": "N9K-C9300v"}} + set_module_args( + dict( + vrf="v2000", + afi="ipv4", + route_targets=[{"rt": "auto", "direction": "both", "state": "present"}], + ), + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "vrf context v2000", + "address-family ipv4 unicast", + "route-target both auto", + ], + ) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_vxlan_vtep.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_vxlan_vtep.py new file mode 100644 index 00000000..68c499fe --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_vxlan_vtep.py @@ -0,0 +1,102 @@ +# (c) 2016 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from ansible_collections.cisco.nxos.plugins.modules import nxos_vxlan_vtep +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, load_fixture, set_module_args + + +class TestNxosVxlanVtepVniModule(TestNxosModule): + module = nxos_vxlan_vtep + + def setUp(self): + super(TestNxosVxlanVtepVniModule, self).setUp() + + self.mock_load_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_vxlan_vtep.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_get_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_vxlan_vtep.get_config", + ) + self.get_config = self.mock_get_config.start() + + def tearDown(self): + super(TestNxosVxlanVtepVniModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, device=""): + self.get_config.return_value = load_fixture("nxos_vxlan_vtep", "config.cfg") + self.load_config.return_value = None + + def test_nxos_vxlan_vtep(self): + set_module_args(dict(interface="nve1", description="simple description")) + self.execute_module( + changed=True, + commands=[ + "interface nve1", + "terminal dont-ask", + "description simple description", + ], + ) + + def test_nxos_vxlan_vtep_present_no_change(self): + set_module_args(dict(interface="nve1")) + self.execute_module(changed=False, commands=[]) + + def test_nxos_vxlan_vtep_absent(self): + set_module_args(dict(interface="nve1", state="absent")) + self.execute_module(changed=True, commands=["no interface nve1"]) + + def test_nxos_vxlan_vtep_absent_no_change(self): + set_module_args(dict(interface="nve2", state="absent")) + self.execute_module(changed=False, commands=[]) + + def test_nxos_vxlan_vtep_multisite(self): + set_module_args( + dict( + interface="nve1", + multisite_border_gateway_interface="Loopback10", + ), + ) + self.execute_module( + changed=True, + commands=[ + "interface nve1", + "terminal dont-ask", + "multisite border-gateway interface loopback10", + ], + ) + + def test_nxos_vxlan_vtep_multisite_exists(self): + set_module_args( + dict( + interface="nve1", + multisite_border_gateway_interface="Loopback1", + ), + ) + self.execute_module(changed=False, commands=[]) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_vxlan_vtep_vni.py b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_vxlan_vtep_vni.py new file mode 100644 index 00000000..c6dc6e8d --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/network/nxos/test_nxos_vxlan_vtep_vni.py @@ -0,0 +1,112 @@ +# (c) 2016 Red Hat Inc. +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. + +# Make coding more python3-ish + +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +from ansible_collections.cisco.nxos.plugins.modules import nxos_vxlan_vtep_vni +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + +from .nxos_module import TestNxosModule, load_fixture, set_module_args + + +class TestNxosVxlanVtepVniModule(TestNxosModule): + module = nxos_vxlan_vtep_vni + + def setUp(self): + super(TestNxosVxlanVtepVniModule, self).setUp() + + self.mock_load_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_vxlan_vtep_vni.load_config", + ) + self.load_config = self.mock_load_config.start() + + self.mock_get_config = patch( + "ansible_collections.cisco.nxos.plugins.modules.nxos_vxlan_vtep_vni.get_config", + ) + self.get_config = self.mock_get_config.start() + + def tearDown(self): + super(TestNxosVxlanVtepVniModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, device=""): + self.get_config.return_value = load_fixture("nxos_vxlan_vtep_vni", "config.cfg") + self.load_config.return_value = None + + def test_nxos_vxlan_vtep_vni_present_no_change(self): + set_module_args(dict(interface="nve1", vni=6000)) + self.execute_module(changed=False, commands=[]) + + def test_nxos_vxlan_vtep_vni(self): + set_module_args(dict(interface="nve1", vni=5000)) + self.execute_module(changed=True, commands=["interface nve1", "member vni 5000"]) + + def test_nxos_vxlan_vtep_vni_absent(self): + set_module_args(dict(interface="nve1", vni=6000, state="absent")) + self.execute_module(changed=True, commands=["interface nve1", "no member vni 6000"]) + + def test_nxos_vxlan_vtep_vni_absent_no_change(self): + set_module_args(dict(interface="nve2", vni=6000, state="absent")) + self.execute_module(changed=False, commands=[]) + + def test_nxos_vxlan_vtep_vni_multi_ingress_repl(self): + set_module_args( + dict( + interface="nve1", + vni=5000, + multisite_ingress_replication="enable", + ), + ) + commands = [ + "interface nve1", + "member vni 5000", + "multisite ingress-replication", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_vxlan_vtep_vni_multi_ingress_repl_opt(self): + set_module_args( + dict( + interface="nve1", + vni=5000, + multisite_ingress_replication="optimized", + ), + ) + commands = [ + "interface nve1", + "member vni 5000", + "multisite ingress-replication optimized", + ] + result = self.execute_module(changed=True) + self.assertEqual(set(result["commands"]), set(commands)) + + def test_nxos_vxlan_vtep_vni_multi_ingress_repl_opt_exists(self): + set_module_args( + dict( + interface="nve1", + vni=6000, + multisite_ingress_replication="optimized", + ), + ) + self.execute_module(changed=False, commands=[]) diff --git a/ansible_collections/cisco/nxos/tests/unit/modules/utils.py b/ansible_collections/cisco/nxos/tests/unit/modules/utils.py new file mode 100644 index 00000000..cd3b7b05 --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/modules/utils.py @@ -0,0 +1,55 @@ +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type +import json + +from ansible.module_utils import basic +from ansible.module_utils._text import to_bytes + +from ansible_collections.cisco.nxos.tests.unit.compat import unittest +from ansible_collections.cisco.nxos.tests.unit.compat.mock import patch + + +def set_module_args(args): + if "_ansible_remote_tmp" not in args: + args["_ansible_remote_tmp"] = "/tmp" + if "_ansible_keep_remote_files" not in args: + args["_ansible_keep_remote_files"] = False + + args = json.dumps({"ANSIBLE_MODULE_ARGS": args}) + basic._ANSIBLE_ARGS = to_bytes(args) + + +class AnsibleExitJson(Exception): + pass + + +class AnsibleFailJson(Exception): + pass + + +def exit_json(*args, **kwargs): + if "changed" not in kwargs: + kwargs["changed"] = False + raise AnsibleExitJson(kwargs) + + +def fail_json(*args, **kwargs): + kwargs["failed"] = True + raise AnsibleFailJson(kwargs) + + +class ModuleTestCase(unittest.TestCase): + def setUp(self): + self.mock_module = patch.multiple( + basic.AnsibleModule, + exit_json=exit_json, + fail_json=fail_json, + ) + self.mock_module.start() + self.mock_sleep = patch("time.sleep") + self.mock_sleep.start() + set_module_args({}) + self.addCleanup(self.mock_module.stop) + self.addCleanup(self.mock_sleep.stop) diff --git a/ansible_collections/cisco/nxos/tests/unit/requirements.txt b/ansible_collections/cisco/nxos/tests/unit/requirements.txt new file mode 100644 index 00000000..a9772bea --- /dev/null +++ b/ansible_collections/cisco/nxos/tests/unit/requirements.txt @@ -0,0 +1,42 @@ +boto3 +placebo +pycrypto +passlib +pypsrp +python-memcached +pytz +pyvmomi +redis +requests +setuptools > 0.6 # pytest-xdist installed via requirements does not work with very old setuptools (sanity_ok) +unittest2 ; python_version < '2.7' +importlib ; python_version < '2.7' +netaddr +ipaddress +netapp-lib +solidfire-sdk-python + +# requirements for F5 specific modules +f5-sdk ; python_version >= '2.7' +f5-icontrol-rest ; python_version >= '2.7' +deepdiff + +# requirement for Fortinet specific modules +pyFMG + +# requirement for aci_rest module +xmljson + +# requirement for winrm connection plugin tests +pexpect + +# requirement for the linode module +linode-python # APIv3 +linode_api4 ; python_version > '2.6' # APIv4 + +# requirement for the gitlab module +python-gitlab +httmock + +# requirment for kubevirt modules +openshift ; python_version >= '2.7' |