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/asa/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/asa/tests')
115 files changed, 5760 insertions, 0 deletions
diff --git a/ansible_collections/cisco/asa/tests/.gitignore b/ansible_collections/cisco/asa/tests/.gitignore new file mode 100644 index 00000000..ea1472ec --- /dev/null +++ b/ansible_collections/cisco/asa/tests/.gitignore @@ -0,0 +1 @@ +output/ diff --git a/ansible_collections/cisco/asa/tests/integration/network-integration.cfg b/ansible_collections/cisco/asa/tests/integration/network-integration.cfg new file mode 100644 index 00000000..d12c1efe --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/network-integration.cfg @@ -0,0 +1,4 @@ +[persistent_connection] +command_timeout = 100 +connect_timeout = 100 +connect_retry_timeout = 100 diff --git a/ansible_collections/cisco/asa/tests/integration/target-prefixes.network b/ansible_collections/cisco/asa/tests/integration/target-prefixes.network new file mode 100644 index 00000000..50b13099 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/target-prefixes.network @@ -0,0 +1 @@ +asa
\ No newline at end of file diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/defaults/main.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/defaults/main.yaml new file mode 100644 index 00000000..852a6bee --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: '[^_].*' +test_items: [] diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/meta/main.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/meta/main.yaml new file mode 100644 index 00000000..23d65c7e --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/meta/main.yaml @@ -0,0 +1,2 @@ +--- +dependencies: [] diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tasks/cli.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tasks/cli.yaml new file mode 100644 index 00000000..88efed30 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tasks/cli.yaml @@ -0,0 +1,30 @@ +--- +- name: Print all available facts + ansible.builtin.debug: + var: ansible_facts + +- name: Print ansible_host + ansible.builtin.debug: + var: ansible_host + +- name: Collect all cli test cases + ansible.builtin.find: + paths: '{{ role_path }}/tests/cli' + patterns: '{{ testcase }}.yaml' + use_regex: true + register: test_cases + delegate_to: localhost + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + delegate_to: localhost + +- name: Run test case (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: '{{ test_case_to_run }}' + vars: + ansible_connection: ansible.netcommon.network_cli + with_items: '{{ test_items }}' + loop_control: + loop_var: test_case_to_run + tags: connection_network_cli diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tasks/main.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tasks/main.yaml new file mode 100644 index 00000000..19f69723 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tasks/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Include tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/_parsed.cfg b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/_parsed.cfg new file mode 100644 index 00000000..1dabc77c --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/_parsed.cfg @@ -0,0 +1,5 @@ +access-list test_access; 2 elements; name hash: 0xaf1b712e +access-list test_access line 1 extended deny tcp 192.0.2.0 255.255.255.0 192.0.3.0 255.255.255.0 eq www log default +access-list test_access line 2 extended deny igrp 198.51.100.0 255.255.255.0 198.51.110.0 255.255.255.0 log errors +access-list test_R1_traffic; 1 elements; name hash: 0xaf40d3c2 +access-list test_R1_traffic line 1 extended deny tcp 2001:db8:0:3::/64 eq www 2001:fc8:0:4::/64 eq telnet inactive
\ No newline at end of file diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/_populate_config.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/_populate_config.yaml new file mode 100644 index 00000000..dafe55db --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/_populate_config.yaml @@ -0,0 +1,62 @@ +--- +- name: Populate Config + cisco.asa.asa_acls: &id001 + config: + acls: + - name: test_access + acl_type: extended + aces: + - grant: deny + line: 1 + protocol_options: + tcp: true + source: + address: 192.0.2.0 + netmask: 255.255.255.0 + destination: + address: 192.0.3.0 + netmask: 255.255.255.0 + port_protocol: + eq: www + log: default + - grant: deny + line: 2 + protocol_options: + igrp: true + source: + address: 198.51.100.0 + netmask: 255.255.255.0 + destination: + address: 198.51.110.0 + netmask: 255.255.255.0 + log: errors + - name: test_global_access + acl_type: extended + aces: + - grant: deny + line: 1 + protocol_options: + tcp: true + source: + any: true + destination: + any: true + port_protocol: + eq: www + log: errors + - name: test_R1_traffic + aces: + - grant: deny + line: 1 + protocol_options: + tcp: true + source: + address: 2001:db8:0:3::/64 + port_protocol: + eq: www + destination: + address: 2001:fc8:0:4::/64 + port_protocol: + eq: telnet + inactive: true + state: merged diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/_populate_network_og.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/_populate_network_og.yaml new file mode 100644 index 00000000..74e21f61 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/_populate_network_og.yaml @@ -0,0 +1,21 @@ +--- +- name: Populate Network Object-group + cisco.asa.asa_ogs: + config: + - object_type: network + object_groups: + - name: test_og_network + network_object: + host: + - 192.0.2.1 + - 192.0.2.2 + address: + - 192.0.2.0 255.255.255.0 + - 198.51.100.0 255.255.255.0 + - name: test_network_og + network_object: + host: + - 192.0.3.1 + ipv6_address: + - 2001:db8:3::/64 + state: merged diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/_remove_config.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/_remove_config.yaml new file mode 100644 index 00000000..f2d64eab --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/_remove_config.yaml @@ -0,0 +1,4 @@ +--- +- name: Remove Config + cisco.asa.asa_acls: + state: deleted diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/_remove_og_config.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/_remove_og_config.yaml new file mode 100644 index 00000000..50921c3b --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/_remove_og_config.yaml @@ -0,0 +1,4 @@ +--- +- name: Remove configured Object group + cisco.asa.asa_ogs: + state: deleted diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/deleted.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/deleted.yaml new file mode 100644 index 00000000..14a2e8ea --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/deleted.yaml @@ -0,0 +1,64 @@ +--- +- ansible.builtin.debug: + msg: Start Deleted integration state for asa_acls ansible_connection={{ ansible_connection + }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + + - name: Delete attributes of provided configured ACLs + register: result + cisco.asa.asa_acls: &id001 + config: + acls: + - name: test_access + - name: test_global_access + state: deleted + + - assert: + that: + - result.commands|length == 3 + - result.changed == true + - result.commands|symmetric_difference(deleted.commands) == [] + + - name: Delete attributes of all configured interfaces (IDEMPOTENT) + register: result + cisco.asa.asa_acls: *id001 + + - name: Assert that the previous delete task was idempotent + assert: + that: + - result.commands|length == 0 + - result.changed == false + + - include_tasks: _remove_config.yaml + + - include_tasks: _populate_config.yaml + + - name: Delete all off ACLs configured + register: result + cisco.asa.asa_acls: &id002 + state: deleted + + - assert: + that: + - result.commands|length == 4 + - result.changed == true + - result.commands|symmetric_difference(delete_all.commands) == [] + + - name: Delete ACL attributes of provided configured interfaces based on AFI + (IDEMPOTENT) + register: result + cisco.asa.asa_acls: *id002 + + - name: Assert that the previous delete task was idempotent + assert: + that: + - result.commands|length == 0 + - result.changed == false + always: + + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/empty_config.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/empty_config.yaml new file mode 100644 index 00000000..648ca571 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/empty_config.yaml @@ -0,0 +1,59 @@ +--- +- ansible.builtin.debug: + msg: START asa_acls empty_config.yaml integration tests on connection={{ ansible_connection + }} + +- name: Merged with empty config should give appropriate error message + register: result + ignore_errors: true + cisco.asa.asa_acls: + config: + state: merged + +- assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty config should give appropriate error message + register: result + ignore_errors: true + cisco.asa.asa_acls: + config: + state: replaced + +- assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Overridden with empty config should give appropriate error message + register: result + ignore_errors: true + cisco.asa.asa_acls: + config: + state: overridden + +- assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Rendered with empty config should give appropriate error message + register: result + ignore_errors: true + cisco.asa.asa_acls: + config: + state: rendered + +- assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' + +- name: Parsed with empty config should give appropriate error message + register: result + ignore_errors: true + cisco.asa.asa_acls: + running_config: + state: parsed + +- assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state parsed' diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/gathered.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/gathered.yaml new file mode 100644 index 00000000..e86ea474 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/gathered.yaml @@ -0,0 +1,24 @@ +--- +- ansible.builtin.debug: + msg: START asa_acls gathered integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + + - name: Gather the provided configuration with the exisiting running configuration + register: result + cisco.asa.asa_acls: + config: + state: gathered + + - assert: + that: + - gathered['config']['acls'] | symmetric_difference(result.gathered.acls) == [] + - result['changed'] == false + always: + + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/merged.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/merged.yaml new file mode 100644 index 00000000..6d129cfb --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/merged.yaml @@ -0,0 +1,130 @@ +--- +- ansible.builtin.debug: + msg: START Merged asa_acls state for integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.include_tasks: _remove_config.yaml +- ansible.builtin.include_tasks: _populate_network_og.yaml + +- block: + + - name: Merge provided configuration with device configuration + register: result + cisco.asa.asa_acls: &id001 + config: + acls: + - name: test_access + acl_type: extended + aces: + - grant: deny + line: 1 + protocol_options: + tcp: true + source: + address: 192.0.2.0 + netmask: 255.255.255.0 + destination: + address: 192.0.3.0 + netmask: 255.255.255.0 + port_protocol: + eq: www + log: default + - grant: deny + line: 2 + protocol: icmp + protocol_options: + icmp: + alternate_address: true + source: + address: 198.51.100.0 + netmask: 255.255.255.0 + destination: + address: 198.51.110.0 + netmask: 255.255.255.0 + log: errors + - grant: deny + line: 3 + protocol: tcp + protocol_options: + tcp: true + source: + host: 198.51.110.0 + destination: + any: true + port_protocol: + eq: www + log: default + - grant: deny + line: 4 + protocol: tcp + protocol_options: + tcp: true + source: + object_group: test_og_network + destination: + object_group: test_network_og + port_protocol: + eq: www + log: default + - name: test_global_access + acl_type: extended + aces: + - grant: deny + line: 1 + protocol_options: + tcp: true + source: + any: true + destination: + any: true + port_protocol: + eq: www + log: errors + - grant: deny + line: 2 + protocol_options: + tcp: true + source: + interface: management + destination: + interface: management + port_protocol: + eq: www + log: warnings + - name: test_R1_traffic + acl_type: extended + aces: + - grant: deny + line: 1 + protocol_options: + tcp: true + source: + address: 2001:db8:0:3::/64 + port_protocol: + eq: www + destination: + address: 2001:fc8:0:4::/64 + port_protocol: + eq: telnet + inactive: true + state: merged + + - assert: + that: + - result.commands|length == 7 + - result.changed == true + - result.commands|symmetric_difference(merged.commands) == [] + + - name: Merge provided configuration with device configuration (IDEMPOTENT) + register: result + cisco.asa.asa_acls: *id001 + + - name: Assert that the previous task was idempotent + assert: + that: + - result.commands|length == 0 + - result['changed'] == false + always: + + - ansible.builtin.include_tasks: _remove_config.yaml + - ansible.builtin.include_tasks: _remove_og_config.yaml diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/overridden.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/overridden.yaml new file mode 100644 index 00000000..7f229b78 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/overridden.yaml @@ -0,0 +1,66 @@ +--- +- ansible.builtin.debug: + msg: START Overridden asa_acls state for integration tests on connection={{ + ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml +- ansible.builtin.include_tasks: _populate_network_og.yaml +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + + - name: Override device configuration of all interfaces with provided configuration + register: result + cisco.asa.asa_acls: &id001 + config: + acls: + - name: test_access + acl_type: extended + aces: + - grant: deny + line: 1 + protocol_options: + tcp: true + source: + address: 192.0.4.0 + netmask: 255.255.255.0 + port_protocol: + eq: telnet + destination: + address: 192.0.5.0 + netmask: 255.255.255.0 + port_protocol: + eq: www + - grant: deny + line: 2 + protocol_options: + tcp: true + source: + object_group: test_og_network + destination: + object_group: test_network_og + port_protocol: + eq: www + log: default + state: overridden + + - assert: + that: + - result.commands|length == 6 + - result.changed == true + - result.commands|symmetric_difference(overridden.commands) == [] + + - name: Override device configuration of all interfaces with provided configuration + (IDEMPOTENT) + register: result + cisco.asa.asa_acls: *id001 + + - name: Assert that task was idempotent + assert: + that: + - result.commands|length == 0 + - result['changed'] == false + always: + + - ansible.builtin.include_tasks: _remove_config.yaml + - ansible.builtin.include_tasks: _remove_og_config.yaml diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/parsed.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/parsed.yaml new file mode 100644 index 00000000..6b5b1203 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/parsed.yaml @@ -0,0 +1,16 @@ +--- +- ansible.builtin.debug: + msg: START asa_acls parsed integration tests on connection={{ ansible_connection + }} + +- name: Parse the commands for provided configuration + become: true + register: result + cisco.asa.asa_acls: + running_config: "{{ lookup('file', '_parsed.cfg') }}" + state: parsed + +- assert: + that: + - result.changed == false + - parsed['config']['acls']|symmetric_difference(result.parsed.acls) == [] diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/rendered.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/rendered.yaml new file mode 100644 index 00000000..49a36585 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/rendered.yaml @@ -0,0 +1,112 @@ +--- +- ansible.builtin.debug: + msg: Start asa_acls rendered integration tests ansible_connection={{ ansible_connection + }} + +- block: + + - name: Rendered the provided configuration with the exisiting running configuration + register: result + cisco.asa.asa_acls: + config: + acls: + - name: test_access + acl_type: extended + aces: + - grant: deny + line: 1 + protocol_options: + tcp: true + source: + address: 192.0.2.0 + netmask: 255.255.255.0 + destination: + address: 192.0.3.0 + netmask: 255.255.255.0 + port_protocol: + eq: www + log: default + - grant: deny + line: 2 + protocol: icmp + protocol_options: + icmp: + alternate_address: true + source: + address: 198.51.100.0 + netmask: 255.255.255.0 + destination: + address: 198.51.110.0 + netmask: 255.255.255.0 + log: errors + - grant: deny + line: 3 + protocol: tcp + protocol_options: + tcp: true + source: + host: 198.51.110.0 + destination: + any: true + port_protocol: + eq: www + log: default + - grant: deny + line: 4 + protocol: tcp + protocol_options: + tcp: true + source: + object_group: test_og_network + destination: + object_group: test_network_og + port_protocol: + eq: www + log: default + - name: test_global_access + acl_type: extended + aces: + - grant: deny + line: 1 + protocol_options: + tcp: true + source: + any: true + destination: + any: true + port_protocol: + eq: www + log: errors + - grant: deny + line: 2 + protocol_options: + tcp: true + source: + interface: management + destination: + interface: management + port_protocol: + eq: www + log: warnings + - name: test_R1_traffic + acl_type: extended + aces: + - grant: deny + line: 1 + protocol_options: + tcp: true + source: + address: 2001:db8:0:3::/64 + port_protocol: + eq: www + destination: + address: 2001:fc8:0:4::/64 + port_protocol: + eq: telnet + inactive: true + state: rendered + + - assert: + that: + - result.changed == false + - result.rendered|symmetric_difference(merged.commands) == [] diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/replaced.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/replaced.yaml new file mode 100644 index 00000000..1fd21fb2 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/replaced.yaml @@ -0,0 +1,83 @@ +--- +- ansible.builtin.debug: + msg: START Replaced asa_acls state for integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.include_tasks: _remove_config.yaml +- ansible.builtin.include_tasks: _populate_network_og.yaml +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + + - name: Replaces device configuration of listed interfaces with provided configuration + register: result + cisco.asa.asa_acls: &id001 + config: + acls: + - name: test_access + acl_type: extended + aces: + - grant: deny + line: 1 + protocol: tcp + protocol_options: + tcp: true + source: + address: 192.0.3.0 + netmask: 255.255.255.0 + destination: + address: 192.0.4.0 + netmask: 255.255.255.0 + port_protocol: + eq: www + log: default + - grant: deny + line: 2 + protocol_options: + tcp: true + source: + object_group: test_og_network + destination: + object_group: test_network_og + port_protocol: + eq: www + log: default + - name: test_global_access + acl_type: extended + aces: + - grant: deny + line: 1 + protocol_options: + tcp: true + source: + address: 192.0.4.0 + netmask: 255.255.255.0 + port_protocol: + eq: telnet + destination: + address: 192.0.5.0 + netmask: 255.255.255.0 + port_protocol: + eq: www + state: replaced + + - assert: + that: + - result.commands|length == 6 + - result.changed == true + - result.commands|symmetric_difference(replaced.commands) == [] + + - name: Replaces device configuration of listed interfaces with provided configuration + (IDEMPOTENT) + register: result + cisco.asa.asa_acls: *id001 + + - name: Assert that task was idempotent + assert: + that: + - result.commands|length == 0 + - result['changed'] == false + always: + + - ansible.builtin.include_tasks: _remove_config.yaml + - ansible.builtin.include_tasks: _remove_og_config.yaml diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/rtt.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/rtt.yaml new file mode 100644 index 00000000..31502a3a --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/tests/cli/rtt.yaml @@ -0,0 +1,139 @@ +--- +- ansible.builtin.debug: + msg: START asa_acls round trip integration tests on connection={{ ansible_connection + }} + +- ansible.builtin.include_tasks: _remove_config.yaml +- ansible.builtin.include_tasks: _populate_network_og.yaml +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + + - name: Apply the provided configuration (base config) + register: base_config + cisco.asa.asa_acls: + config: + acls: + - name: test_access + acl_type: extended + aces: + - grant: deny + line: 1 + protocol_options: + tcp: true + source: + address: 192.0.2.0 + netmask: 255.255.255.0 + destination: + address: 192.0.3.0 + netmask: 255.255.255.0 + port_protocol: + eq: www + log: default + - grant: deny + line: 2 + protocol_options: + igrp: true + source: + address: 198.51.100.0 + netmask: 255.255.255.0 + destination: + address: 198.51.110.0 + netmask: 255.255.255.0 + log: errors + - name: test_global_access + acl_type: extended + aces: + - grant: deny + line: 1 + protocol_options: + tcp: true + source: + any: true + destination: + any: true + port_protocol: + eq: www + log: errors + - name: test_R1_traffic + acl_type: extended + aces: + - grant: deny + line: 1 + protocol_options: + tcp: true + source: + address: 2001:db8:0:3::/64 + port_protocol: + eq: www + destination: + address: 2001:fc8:0:4::/64 + port_protocol: + eq: telnet + inactive: true + state: merged + + - name: Gather ACLs facts + cisco.asa.asa_facts: + gather_subset: + - '!all' + - '!min' + gather_network_resources: + - acls + + - name: Apply the configuration which need to be reverted + register: result + cisco.asa.asa_acls: + config: + acls: + - name: test_access + acl_type: extended + aces: + - grant: deny + line: 1 + protocol_options: + tcp: true + source: + address: 192.0.4.0 + netmask: 255.255.255.0 + port_protocol: + eq: telnet + destination: + address: 192.0.5.0 + netmask: 255.255.255.0 + port_protocol: + eq: www + - grant: deny + line: 2 + protocol_options: + tcp: true + source: + object_group: test_og_network + destination: + object_group: test_network_og + port_protocol: + eq: www + log: default + state: overridden + + - assert: + that: + - result.commands|length == 6 + - result.changed == true + - result.commands|symmetric_difference(overridden.commands) == [] + + - name: Revert back to base config using facts round trip + register: revert + cisco.asa.asa_acls: + config: "{{ ansible_facts['network_resources']['acls'] }}" + state: overridden + + - assert: + that: + - revert.commands|length == 6 + - revert.changed == true + - revert.commands|symmetric_difference(rtt.commands) == [] + always: + + - ansible.builtin.include_tasks: _remove_config.yaml + - ansible.builtin.include_tasks: _remove_og_config.yaml diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/vars/main.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/vars/main.yaml new file mode 100644 index 00000000..281cb8d6 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_acls/vars/main.yaml @@ -0,0 +1,158 @@ +--- +deleted: + commands: + - no access-list test_global_access line 1 extended deny tcp any any eq www log errors + - no access-list test_access line 2 extended deny igrp 198.51.100.0 255.255.255.0 198.51.110.0 255.255.255.0 log errors + - no access-list test_access line 1 extended deny tcp 192.0.2.0 255.255.255.0 192.0.3.0 255.255.255.0 eq www log default +delete_all: + commands: + - no access-list test_R1_traffic line 1 extended deny tcp 2001:db8:0:3::/64 eq www 2001:fc8:0:4::/64 eq telnet inactive + - no access-list test_global_access line 1 extended deny tcp any any eq www log errors + - no access-list test_access line 2 extended deny igrp 198.51.100.0 255.255.255.0 198.51.110.0 255.255.255.0 log errors + - no access-list test_access line 1 extended deny tcp 192.0.2.0 255.255.255.0 192.0.3.0 255.255.255.0 eq www log default +merged: + commands: + - access-list test_access line 1 extended deny tcp 192.0.2.0 255.255.255.0 192.0.3.0 255.255.255.0 eq www log default + - access-list test_access line 2 extended deny icmp 198.51.100.0 255.255.255.0 198.51.110.0 255.255.255.0 alternate-address log errors + - access-list test_access line 3 extended deny tcp host 198.51.110.0 any eq www log default + - access-list test_access line 4 extended deny tcp object-group test_og_network object-group test_network_og eq www log default + - access-list test_global_access line 1 extended deny tcp any any eq www log errors + - access-list test_global_access line 2 extended deny tcp interface management interface management eq www log warnings + - access-list test_R1_traffic line 1 extended deny tcp 2001:db8:0:3::/64 eq www 2001:fc8:0:4::/64 eq telnet inactive +replaced: + commands: + - no access-list test_global_access line 1 extended deny tcp any any eq www log errors + - no access-list test_access line 2 extended deny igrp 198.51.100.0 255.255.255.0 198.51.110.0 255.255.255.0 log errors + - no access-list test_access line 1 extended deny tcp 192.0.2.0 255.255.255.0 192.0.3.0 255.255.255.0 eq www log default + - access-list test_access line 1 extended deny tcp 192.0.3.0 255.255.255.0 192.0.4.0 255.255.255.0 eq www log default + - access-list test_access line 2 extended deny tcp object-group test_og_network object-group test_network_og eq www log default + - access-list test_global_access line 1 extended deny tcp 192.0.4.0 255.255.255.0 eq telnet 192.0.5.0 255.255.255.0 eq www +overridden: + commands: + - no access-list test_R1_traffic line 1 extended deny tcp 2001:db8:0:3::/64 eq www 2001:fc8:0:4::/64 eq telnet inactive + - no access-list test_global_access line 1 extended deny tcp any any eq www log errors + - no access-list test_access line 2 extended deny igrp 198.51.100.0 255.255.255.0 198.51.110.0 255.255.255.0 log errors + - no access-list test_access line 1 extended deny tcp 192.0.2.0 255.255.255.0 192.0.3.0 255.255.255.0 eq www log default + - access-list test_access line 1 extended deny tcp 192.0.4.0 255.255.255.0 eq telnet 192.0.5.0 255.255.255.0 eq www + - access-list test_access line 2 extended deny tcp object-group test_og_network object-group test_network_og eq www log default +gathered: + config: + acls: + - aces: + - destination: + address: 192.0.3.0 + netmask: 255.255.255.0 + port_protocol: + eq: www + grant: deny + line: 1 + log: default + protocol: tcp + protocol_options: + tcp: true + source: + address: 192.0.2.0 + netmask: 255.255.255.0 + - destination: + address: 198.51.110.0 + netmask: 255.255.255.0 + grant: deny + line: 2 + log: errors + protocol: igrp + protocol_options: + igrp: true + source: + address: 198.51.100.0 + netmask: 255.255.255.0 + acl_type: extended + name: test_access + - aces: + - destination: + any: true + port_protocol: + eq: www + grant: deny + line: 1 + log: errors + protocol: tcp + protocol_options: + tcp: true + source: + any: true + acl_type: extended + name: test_global_access + - aces: + - destination: + address: 2001:fc8:0:4::/64 + port_protocol: + eq: telnet + grant: deny + inactive: true + line: 1 + protocol: tcp + protocol_options: + tcp: true + source: + address: 2001:db8:0:3::/64 + port_protocol: + eq: www + acl_type: extended + name: test_R1_traffic +parsed: + config: + acls: + - aces: + - destination: + address: 192.0.3.0 + netmask: 255.255.255.0 + port_protocol: + eq: www + grant: deny + line: 1 + log: default + protocol: tcp + protocol_options: + tcp: true + source: + address: 192.0.2.0 + netmask: 255.255.255.0 + - destination: + address: 198.51.110.0 + netmask: 255.255.255.0 + grant: deny + line: 2 + log: errors + protocol: igrp + protocol_options: + igrp: true + source: + address: 198.51.100.0 + netmask: 255.255.255.0 + acl_type: extended + name: test_access + - aces: + - destination: + address: 2001:fc8:0:4::/64 + port_protocol: + eq: telnet + grant: deny + inactive: true + line: 1 + protocol: tcp + protocol_options: + tcp: true + source: + address: 2001:db8:0:3::/64 + port_protocol: + eq: www + acl_type: extended + name: test_R1_traffic +rtt: + commands: + - no access-list test_access line 2 extended deny tcp object-group test_og_network object-group test_network_og eq www log default + - no access-list test_access line 1 extended deny tcp 192.0.4.0 255.255.255.0 eq telnet 192.0.5.0 255.255.255.0 eq www + - access-list test_access line 1 extended deny tcp 192.0.2.0 255.255.255.0 192.0.3.0 255.255.255.0 eq www log default + - access-list test_access line 2 extended deny igrp 198.51.100.0 255.255.255.0 198.51.110.0 255.255.255.0 log errors + - access-list test_global_access line 1 extended deny tcp any any eq www log errors + - access-list test_R1_traffic line 1 extended deny tcp 2001:db8:0:3::/64 eq www 2001:fc8:0:4::/64 eq telnet inactive diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_command/defaults/main.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_command/defaults/main.yaml new file mode 100644 index 00000000..a845c24b --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_command/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: '*' +test_items: [] diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_command/tasks/cli.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_command/tasks/cli.yaml new file mode 100644 index 00000000..351a178c --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_command/tasks/cli.yaml @@ -0,0 +1,19 @@ +--- +- name: Collect all cli test cases + ansible.builtin.find: + paths: '{{ role_path }}/tests/cli' + patterns: '{{ testcase }}.yaml' + register: test_cases + +- 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 }}' + vars: + ansible_connection: ansible.netcommon.network_cli + with_items: '{{ test_items }}' + loop_control: + loop_var: test_case_to_run + tags: connection_network_cli diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_command/tasks/main.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_command/tasks/main.yaml new file mode 100644 index 00000000..19f69723 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_command/tasks/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Include tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_command/tests/cli/bad_operator.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_command/tests/cli/bad_operator.yaml new file mode 100644 index 00000000..79e824f6 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_command/tests/cli/bad_operator.yaml @@ -0,0 +1,22 @@ +--- +- ansible.builtin.debug: + msg: "START cli/bad_operator.yaml" + +- name: test bad operator + register: result + ignore_errors: true + cisco.asa.asa_command: + commands: + - show version + - show interfaces GigabitEthernet 0/0 + wait_for: + + - result[0] contains 'Description: Foo' + +- assert: + that: + - result.failed == true + - result.msg is defined + +- ansible.builtin.debug: + msg: "END cli/bad_operator.yaml" diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_command/tests/cli/contains.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_command/tests/cli/contains.yaml new file mode 100644 index 00000000..78cd59f4 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_command/tests/cli/contains.yaml @@ -0,0 +1,21 @@ +--- +- ansible.builtin.debug: + msg: "START cli/contains.yaml" + +- name: test contains operator + register: result + cisco.asa.asa_command: + commands: + - show version + - show interface + wait_for: + - result[0] contains 'Cisco Adaptive Security Appliance Software Version' + - result[1] contains 'Hardware' + +- assert: + that: + - result.changed == false + - result.stdout is defined + +- ansible.builtin.debug: + msg: "END cli/contains.yaml" diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_command/tests/cli/invalid.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_command/tests/cli/invalid.yaml new file mode 100644 index 00000000..ae5575de --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_command/tests/cli/invalid.yaml @@ -0,0 +1,30 @@ +--- +- ansible.builtin.debug: + msg: "START cli/invalid.yaml" + +- name: run invalid command + register: result + ignore_errors: true + cisco.asa.asa_command: + commands: + - show foo + +- assert: + that: + - result.failed + +- name: run commands that include invalid command + register: result + ignore_errors: true + cisco.asa.asa_command: + commands: + - show version + - show foo + +- assert: + that: + - result.failed + ignore_errors: true + +- ansible.builtin.debug: + msg: "END cli/invalid.yaml" diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_command/tests/cli/output.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_command/tests/cli/output.yaml new file mode 100644 index 00000000..81d00ad9 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_command/tests/cli/output.yaml @@ -0,0 +1,30 @@ +--- +- ansible.builtin.debug: + msg: "START cli/output.yaml" + +- name: get output for single command + register: result + cisco.asa.asa_command: + commands: + - show version + +- assert: + that: + - result.changed == false + - result.stdout is defined + +- name: get output for multiple commands + register: result + cisco.asa.asa_command: + commands: + - show version + - show interface + +- assert: + that: + - result.changed == false + - result.stdout is defined + - result.stdout | length == 2 + +- ansible.builtin.debug: + msg: "END cli/output.yaml" diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_command/tests/cli/timeout.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_command/tests/cli/timeout.yaml new file mode 100644 index 00000000..41af98e2 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_command/tests/cli/timeout.yaml @@ -0,0 +1,20 @@ +--- +- ansible.builtin.debug: + msg: "START cli/timeout.yaml" + +- name: test bad condition + register: result + ignore_errors: true + cisco.asa.asa_command: + commands: + - show version + wait_for: + - result[0] contains bad_value_string + +- assert: + that: + - result.failed == true + - result.msg is defined + +- ansible.builtin.debug: + msg: "END cli/timeout.yaml" diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_config/defaults/main.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/defaults/main.yaml new file mode 100644 index 00000000..a845c24b --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: '*' +test_items: [] diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tasks/cli.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tasks/cli.yaml new file mode 100644 index 00000000..351a178c --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tasks/cli.yaml @@ -0,0 +1,19 @@ +--- +- name: Collect all cli test cases + ansible.builtin.find: + paths: '{{ role_path }}/tests/cli' + patterns: '{{ testcase }}.yaml' + register: test_cases + +- 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 }}' + vars: + ansible_connection: ansible.netcommon.network_cli + with_items: '{{ test_items }}' + loop_control: + loop_var: test_case_to_run + tags: connection_network_cli diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tasks/main.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tasks/main.yaml new file mode 100644 index 00000000..ca453cc3 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tasks/main.yaml @@ -0,0 +1,9 @@ +--- +- name: Include tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli + +- name: Include tasks + ansible.builtin.include_tasks: redirection.yaml + when: ansible_version.full is version('2.10.0', '>=') diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tasks/redirection.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tasks/redirection.yaml new file mode 100644 index 00000000..b3ac11c6 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tasks/redirection.yaml @@ -0,0 +1,19 @@ +--- +- name: Collect all cli test cases + ansible.builtin.find: + paths: '{{ role_path }}/tests/redirection' + patterns: '{{ testcase }}.yaml' + register: test_cases + +- 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 }}' + vars: + ansible_connection: ansible.netcommon.network_cli + with_items: '{{ test_items }}' + loop_control: + loop_var: test_case_to_run + tags: connection_network_cli diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_config/templates/basic/config.j2 b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/templates/basic/config.j2 new file mode 100644 index 00000000..779b731e --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/templates/basic/config.j2 @@ -0,0 +1,3 @@ +object-group network OG-ANSIBLE-TEMPLATE + description this is a test + network-object host 192.168.99.12 diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_config/templates/defaults/config.j2 b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/templates/defaults/config.j2 new file mode 100644 index 00000000..762e73de --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/templates/defaults/config.j2 @@ -0,0 +1,4 @@ +object-group network OG-ANSIBLE-TEMPLATE-DEFAULT + description this is a test + network-object 10.0.0.0 255.255.255.0 + network-object 10.1.0.0 255.255.255.0 diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/backup.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/backup.yaml new file mode 100644 index 00000000..1047d425 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/backup.yaml @@ -0,0 +1,52 @@ +--- +- ansible.builtin.debug: + msg: "START cli/backup.yaml" + +- name: setup + ignore_errors: true + cisco.asa.asa_config: + commands: + - no object-group network OG-ANSIBLE-TEMPLATE + +- 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: configure device with config + register: result + cisco.asa.asa_config: + src: basic/config.j2 + backup: true + +- assert: + that: + - result.changed == true + - result.updates is defined + +- name: collect any backup files + ansible.builtin.find: + paths: '{{ role_path }}/backup' + pattern: '{{ inventory_hostname_short }}_config*' + register: backup_files + connection: local + +- assert: + that: + - backup_files.files is defined + +- name: teardown + cisco.asa.asa_config: + commands: + - no object-group network OG-ANSIBLE-TEMPLATE + +- ansible.builtin.debug: + msg: "END cli/backup.yaml" diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/basic.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/basic.yaml new file mode 100644 index 00000000..13a39df5 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/basic.yaml @@ -0,0 +1,37 @@ +--- +- ansible.builtin.debug: + msg: "START cli/basic.yaml" + +- name: setup + ignore_errors: true + cisco.asa.asa_config: + commands: + - no object-group network OG-ANSIBLE-TEMPLATE + +- name: configure device with config + register: result + cisco.asa.asa_config: + src: basic/config.j2 + +- assert: + that: + - result.changed == true + - result.updates is defined + +- name: check device with config + register: result + cisco.asa.asa_config: + src: basic/config.j2 + +- assert: + that: + - result.changed == false + - result.updates is not defined + +- name: teardown + cisco.asa.asa_config: + commands: + - no object-group network OG-ANSIBLE-TEMPLATE + +- ansible.builtin.debug: + msg: "END cli/basic.yaml" diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/defaults.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/defaults.yaml new file mode 100644 index 00000000..8645d71f --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/defaults.yaml @@ -0,0 +1,45 @@ +--- +- ansible.builtin.debug: + msg: "START cli/defaults.yaml" + +- name: setup + ignore_errors: true + cisco.asa.asa_config: + commands: + - no object-group network OG-ANSIBLE-TEMPLATE-DEFAULT + +- name: configure device with defaults included + register: result + cisco.asa.asa_config: + src: defaults/config.j2 + defaults: true + +- ansible.builtin.debug: + var: result + +- assert: + that: + - result.changed == true + - result.updates is defined + +- name: check device with defaults included + register: result + cisco.asa.asa_config: + src: defaults/config.j2 + defaults: true + +- ansible.builtin.debug: + var: result + +- assert: + that: + - result.changed == false + - result.updates is not defined + +- name: teardown + cisco.asa.asa_config: + commands: + - no object-group network OG-ANSIBLE-TEMPLATE-DEFAULT + +- ansible.builtin.debug: + msg: "END cli/defaults.yaml" diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/force.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/force.yaml new file mode 100644 index 00000000..4042eca6 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/force.yaml @@ -0,0 +1,39 @@ +--- +- ansible.builtin.debug: + msg: "START cli/force.yaml" + +- name: setup + ignore_errors: true + cisco.asa.asa_config: + commands: + - no object-group network OG-ANSIBLE-TEMPLATE-DEFAULT + +- name: configure device with config + register: result + cisco.asa.asa_config: + src: basic/config.j2 + match: none + +- assert: + that: + - result.changed == true + - result.updates is defined + +- name: check device with config + register: result + cisco.asa.asa_config: + src: basic/config.j2 + match: none + +- assert: + that: + - result.changed == true + - result.updates is defined + +- name: teardown + cisco.asa.asa_config: + commands: + - no object-group network OG-ANSIBLE-TEMPLATE-DEFAULT + +- ansible.builtin.debug: + msg: "END cli/force.yaml" diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/more_system.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/more_system.yaml new file mode 100644 index 00000000..e90e5c84 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/more_system.yaml @@ -0,0 +1,36 @@ +--- +- ansible.builtin.debug: + msg: "START cli/more_system.yaml" + +- name: Prepare tunnel-group + cisco.asa.asa_config: + before: tunnel-group 192.0.2.1 type ipsec-l2l + lines: + - tunnel-group 192.0.2.1 ipsec-attributes + +- name: Setup tunnel-group + cisco.asa.asa_config: + parents: tunnel-group 192.0.2.1 ipsec-attributes + lines: + - ikev1 pre-shared-key abc123 + passwords: true + +- name: Test idempotency + register: result + cisco.asa.asa_config: + parents: tunnel-group 192.0.2.1 ipsec-attributes + lines: + - ikev1 pre-shared-key abc123 + passwords: true + +- assert: + that: + - result.changed == false + +- name: teardown + cisco.asa.asa_config: + lines: + - clear configure tunnel-group 192.0.2.1 + +- ansible.builtin.debug: + msg: "END cli/more_system.yaml" diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/removal_error.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/removal_error.yaml new file mode 100644 index 00000000..3bcd41bd --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/removal_error.yaml @@ -0,0 +1,41 @@ +--- +- ansible.builtin.debug: + msg: "START cli/removal_error.yaml" + +- name: setup + ignore_errors: true + cisco.asa.asa_config: + commands: + - no object-group network OGA-GOOGLE-DNS + +- name: configure test object-group + register: result + cisco.asa.asa_config: + parents: object-group network OGA-GOOGLE-DNS + lines: network-object host 8.8.8.8 + +- name: configure test access-list + cisco.asa.asa_config: + lines: access-list ANSIBLE-DNS extended permit udp any object-group OGA-GOOGLE-DNS + eq domain + +- name: try to remove object-group (should fail) + ignore_errors: true + register: result + cisco.asa.asa_config: + commands: + - no object-group network OGA-GOOGLE-DNS + +- name: Last command should fail + assert: + that: + - result.failed == true + +- name: teardown + cisco.asa.asa_config: + commands: + - clear configure access-list ANSIBLE-DNS + - no object-group network OGA-GOOGLE-DNS + +- ansible.builtin.debug: + msg: "END cli/removal_error.yaml" diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/save_when.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/save_when.yaml new file mode 100644 index 00000000..a48f54b3 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/save_when.yaml @@ -0,0 +1,49 @@ +--- +- ansible.builtin.debug: + msg: "START cli/save.yaml on connection={{ ansible_connection }}" + +- name: setup for save when TC + cisco.asa.asa_config: + commands: + - no description + parents: + - interface Management0/0 + save_when: modified + +- name: save should always run + register: result + cisco.asa.asa_config: + save_when: always + +- assert: + that: + - result.changed == true + +- name: delete config (setup) + register: result + cisco.asa.asa_config: + replace: line + lines: + - no banner motd test_motd + save_when: modified + +- name: save should run when changed + register: result + cisco.asa.asa_config: + replace: line + lines: + - banner motd test_motd + save_when: modified + +- assert: + that: + - result.changed == true + +- name: teardown + register: result + cisco.asa.asa_config: + lines: + - no banner motd test_motd + +- ansible.builtin.debug: + msg: "END cli/save.yaml on connection={{ ansible_connection }}" diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/sublevel.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/sublevel.yaml new file mode 100644 index 00000000..a910b0ab --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/sublevel.yaml @@ -0,0 +1,42 @@ +--- +- ansible.builtin.debug: + msg: "START cli/sublevel.yaml" + +- name: setup test + cisco.asa.asa_config: + lines: + - no object-group network OG-ANSIBLE-SUBLEVEL + +- name: configure sub level command + register: result + cisco.asa.asa_config: + lines: + - network-object host 192.168.10.1 + parents: + - object-group network OG-ANSIBLE-SUBLEVEL + +- assert: + that: + - result.changed == true + - "'object-group network OG-ANSIBLE-SUBLEVEL' in result.updates" + - "'network-object host 192.168.10.1' in result.updates" + +- name: configure sub level command idempotent check + register: result + cisco.asa.asa_config: + lines: + - network-object host 192.168.10.1 + parents: + - object-group network OG-ANSIBLE-SUBLEVEL + +- assert: + that: + - result.changed == false + +- name: teardown + cisco.asa.asa_config: + lines: + - no object-group network OG-ANSIBLE-SUBLEVEL + +- ansible.builtin.debug: + msg: "END cli/sublevel.yaml" diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/sublevel_block.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/sublevel_block.yaml new file mode 100644 index 00000000..7659413d --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/sublevel_block.yaml @@ -0,0 +1,64 @@ +--- +- ansible.builtin.debug: + msg: "START cli/sublevel_block.yaml" + +- name: setup + register: object_group + cisco.asa.asa_command: + commands: + - show run object-group + +- name: setup + cisco.asa.asa_config: + lines: + - no object-group network OG-ANSIBLE + match: none + +- name: configure sub level command using block replace + register: result + cisco.asa.asa_config: + lines: + - network-object 192.168.10.0 255.255.255.0 + - network-object 192.168.20.0 255.255.255.0 + - network-object 192.168.30.0 255.255.255.0 + - network-object 192.168.40.0 255.255.255.0 + parents: + - object-group network OG-ANSIBLE + replace: block + after: + - exit + +- assert: + that: + - result.changed == true + - "'object-group network OG-ANSIBLE' in result.updates" + - "'network-object 192.168.10.0 255.255.255.0' in result.updates" + - "'network-object 192.168.20.0 255.255.255.0' in result.updates" + - "'network-object 192.168.30.0 255.255.255.0' in result.updates" + - "'network-object 192.168.40.0 255.255.255.0' in result.updates" + +- name: check sub level command using block replace + register: result + cisco.asa.asa_config: + lines: + - network-object 192.168.10.0 255.255.255.0 + - network-object 192.168.20.0 255.255.255.0 + - network-object 192.168.30.0 255.255.255.0 + - network-object 192.168.40.0 255.255.255.0 + parents: + - object-group network OG-ANSIBLE + replace: block + after: + - exit + +- assert: + that: + - result.changed == false + +- name: teardown + cisco.asa.asa_config: + lines: + - no object-group network OG-ANSIBLE + +- ansible.builtin.debug: + msg: "END cli/sublevel_block.yaml" diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/sublevel_exact.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/sublevel_exact.yaml new file mode 100644 index 00000000..85417720 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/sublevel_exact.yaml @@ -0,0 +1,69 @@ +--- +- ansible.builtin.debug: + msg: "START cli/sublevel_exact.yaml" + +- name: setup + cisco.asa.asa_config: + lines: + - network-object 192.168.10.0 255.255.255.0 + - network-object 192.168.20.0 255.255.255.0 + - network-object 192.168.30.0 255.255.255.0 + - network-object 192.168.40.0 255.255.255.0 + - network-object 192.168.50.0 255.255.255.0 + parents: + - object-group network OG-ANSIBLE-EXACT + before: + - no object-group network OG-ANSIBLE-EXACT + after: + - exit + +- name: configure sub level command using exact match + register: result + cisco.asa.asa_config: + lines: + - network-object 192.168.10.0 255.255.255.0 + - network-object 192.168.20.0 255.255.255.0 + - network-object 192.168.30.0 255.255.255.0 + - network-object 192.168.40.0 255.255.255.0 + parents: + - object-group network OG-ANSIBLE-EXACT + after: + - exit + match: exact + +- assert: + that: + - result.changed == true + - "'object-group network OG-ANSIBLE-EXACT' in result.updates" + - "'network-object 192.168.10.0 255.255.255.0' in result.updates" + - "'network-object 192.168.20.0 255.255.255.0' in result.updates" + - "'network-object 192.168.30.0 255.255.255.0' in result.updates" + - "'network-object 192.168.40.0 255.255.255.0' in result.updates" + - "'network-object 192.168.50.0 255.255.255.0' not in result.updates" + +- name: check sub level command using exact match + register: result + cisco.asa.asa_config: + lines: + - network-object 192.168.10.0 255.255.255.0 + - network-object 192.168.20.0 255.255.255.0 + - network-object 192.168.30.0 255.255.255.0 + - network-object 192.168.40.0 255.255.255.0 + - network-object 192.168.50.0 255.255.255.0 + parents: + - object-group network OG-ANSIBLE-EXACT + after: + - exit + match: exact + +- assert: + that: + - result.changed == false + +- name: teardown + cisco.asa.asa_config: + lines: + - no object-group network OG-ANSIBLE-EXACT + +- ansible.builtin.debug: + msg: "END cli/sublevel_exact.yaml" diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/sublevel_strict.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/sublevel_strict.yaml new file mode 100644 index 00000000..d384f82f --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/sublevel_strict.yaml @@ -0,0 +1,65 @@ +--- +- ansible.builtin.debug: + msg: "START cli/sublevel_strict.yaml" + +- name: setup + cisco.asa.asa_config: + lines: + - network-object 192.168.10.0 255.255.255.0 + - network-object 192.168.20.0 255.255.255.0 + - network-object 192.168.30.0 255.255.255.0 + - network-object 192.168.40.0 255.255.255.0 + - network-object 192.168.50.0 255.255.255.0 + parents: + - object-group network OG-ANSIBLE-STRICT + before: + - no object-group network OG-ANSIBLE-STRICT + after: + - exit + +- name: configure sub level command using strict match + register: result + cisco.asa.asa_config: + lines: + - network-object 192.168.10.0 255.255.255.0 + - network-object 192.168.20.0 255.255.255.0 + - network-object 192.168.30.0 255.255.255.0 + - network-object 192.168.40.0 255.255.255.0 + parents: + - object-group network OG-ANSIBLE-STRICT + match: strict + +- assert: + that: + - result.changed == false + +- name: check sub level command using strict match + register: result + cisco.asa.asa_config: + lines: + - network-object 192.168.10.0 255.255.255.0 + - network-object 192.168.30.0 255.255.255.0 + - network-object 192.168.30.0 255.255.255.0 + parents: + - object-group network OG-ANSIBLE-STRICT + after: + - exit + match: strict + +- assert: + that: + - result.changed == true + - "'object-group network OG-ANSIBLE-STRICT' in result.updates" + - "'network-object 192.168.10.0 255.255.255.0' not in result.updates" + - "'network-object 192.168.30.0 255.255.255.0' in result.updates" + - "'network-object 192.168.30.0 255.255.255.0' in result.updates" + - "'network-object 192.168.40.0 255.255.255.0' not in result.updates" + - "'network-object 192.168.50.0 255.255.255.0' not in result.updates" + +- name: teardown + cisco.asa.asa_config: + lines: + - no object-group network OG-ANSIBLE-STRICT + +- ansible.builtin.debug: + msg: "END cli/sublevel_strict.yaml" diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/sublevel_strict_mul_parents.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/sublevel_strict_mul_parents.yaml new file mode 100644 index 00000000..7a83586e --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/sublevel_strict_mul_parents.yaml @@ -0,0 +1,72 @@ +--- +- ansible.builtin.debug: + msg: "START cli/sublevel_strict_mul_parents.yaml on connection={{ ansible_connection}}" + +- name: setup + cisco.asa.asa_config: + lines: + - class-map c1 + - match default-inspection-traffic + - policy-map p1 + - class c1 + match: none + +- name: configure sub level command using strict match + register: result + cisco.asa.asa_config: + lines: + - inspect ftp + - inspect tftp + parents: + - policy-map p1 + - class c1 + match: strict + +- assert: + that: + - result.changed == true + - "'inspect ftp' in result.updates" + - "'inspect tftp' in result.updates" + +- name: change sub level command order and config with strict match + register: result + cisco.asa.asa_config: + lines: + - inspect tftp + - inspect ftp + parents: + - policy-map p1 + - class c1 + match: strict + +- assert: + that: + - result.changed == true + - "'inspect ftp' in result.updates" + - "'inspect tftp' in result.updates" + +- name: Config sub level command with strict match (Idempotency) + register: result + cisco.asa.asa_config: + lines: + - inspect ftp + - inspect tftp + parents: + - policy-map p1 + - class c1 + match: strict + +- assert: + that: + - result.changed == false + +- name: teardown + cisco.asa.asa_config: + lines: + - no policy-map p1 + - no class-map c1 + match: strict + +- ansible.builtin.debug: + msg: "END cli/sublevel_strict_mul_parents.yaml on connection={{ ansible_connection + }}" diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/toplevel.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/toplevel.yaml new file mode 100644 index 00000000..0d0ee49e --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/toplevel.yaml @@ -0,0 +1,37 @@ +--- +- ansible.builtin.debug: + msg: "START cli/toplevel.yaml" + +- name: setup + cisco.asa.asa_config: + lines: + - hostname firewall + +- name: configure top level command + register: result + cisco.asa.asa_config: + lines: + - hostname foo + +- assert: + that: + - result.changed == true + - "'hostname foo' in result.updates" + +- name: configure top level command idempotent check + register: result + cisco.asa.asa_config: + lines: + - hostname foo + +- assert: + that: + - result.changed == false + +- name: teardown + cisco.asa.asa_config: + lines: + - hostname {{ inventory_hostname_short }} + +- ansible.builtin.debug: + msg: "END cli/toplevel.yaml" diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/toplevel_after.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/toplevel_after.yaml new file mode 100644 index 00000000..196834da --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/toplevel_after.yaml @@ -0,0 +1,44 @@ +--- +- ansible.builtin.debug: + msg: "START cli/toplevel_after.yaml" + +- name: setup + cisco.asa.asa_config: + lines: + - snmp-server contact ansible + - hostname firewall + +- name: configure top level command with before + register: result + cisco.asa.asa_config: + lines: + - hostname foo + after: + - snmp-server contact bar + +- 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.asa.asa_config: + lines: + - hostname foo + after: + - snmp-server contact foo + +- assert: + that: + - result.changed == false + +- name: teardown + cisco.asa.asa_config: + lines: + - no snmp-server contact + - hostname {{ inventory_hostname_short }} + +- ansible.builtin.debug: + msg: "END cli/toplevel_after.yaml" diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/toplevel_before.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/toplevel_before.yaml new file mode 100644 index 00000000..98ed0438 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/toplevel_before.yaml @@ -0,0 +1,44 @@ +--- +- ansible.builtin.debug: + msg: "START cli/toplevel_before.yaml" + +- name: setup + cisco.asa.asa_config: + lines: + - snmp-server contact ansible + - hostname firewall + +- name: configure top level command with before + register: result + cisco.asa.asa_config: + lines: + - hostname foo + before: + - snmp-server contact bar + +- 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.asa.asa_config: + lines: + - hostname foo + before: + - snmp-server contact foo + +- assert: + that: + - result.changed == false + +- name: teardown + cisco.asa.asa_config: + lines: + - no snmp-server contact + - hostname {{ inventory_hostname_short }} + +- ansible.builtin.debug: + msg: "END cli/toplevel_before.yaml" diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/toplevel_nonidempotent.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/toplevel_nonidempotent.yaml new file mode 100644 index 00000000..305c359c --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/cli/toplevel_nonidempotent.yaml @@ -0,0 +1,38 @@ +--- +- ansible.builtin.debug: + msg: "START cli/toplevel_nonidempotent.yaml" + +- name: setup + cisco.asa.asa_config: + backup: true + +- name: configure top level command + register: result + cisco.asa.asa_config: + lines: + - hostname foo + match: strict + +- assert: + that: + - result.changed == true + - "'hostname foo' in result.updates" + +- name: configure top level command idempotent check + register: result + cisco.asa.asa_config: + lines: + - hostname foo + match: strict + +- assert: + that: + - result.changed == true + +- name: teardown + cisco.asa.asa_config: + lines: + - hostname {{ inventory_hostname_short }} + +- ansible.builtin.debug: + msg: "END cli/toplevel_nonidempotent.yaml" diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/redirection/shortname.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/redirection/shortname.yaml new file mode 100644 index 00000000..b22d3e08 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_config/tests/redirection/shortname.yaml @@ -0,0 +1,38 @@ +--- +- ansible.builtin.debug: + msg: "START redirection/shortname.yaml on connection={{ ansible_connection }}" + +- name: Use src with module alias + register: result + cisco.asa.config: + src: basic/config.j2 + +- assert: + that: + # make sure that the template content was read and not the path + - result.failed == false + +- name: use module alias to take configuration backup + register: result + cisco.asa.config: + backup: true + backup_options: + filename: backup_with_alias.cfg + dir_path: '{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}' + +- assert: + that: + - result.changed == true + +- name: check if the backup file exist + ansible.builtin.find: + paths: '{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}/backup_with_alias.cfg' + register: backup_file + connection: local + +- assert: + that: + - backup_file.files is defined + +- ansible.builtin.debug: + msg: "END redirection/shortname.yaml on connection={{ ansible_connection }}" diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_facts/defaults/main.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_facts/defaults/main.yaml new file mode 100644 index 00000000..a845c24b --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_facts/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: '*' +test_items: [] diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_facts/tasks/cli.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_facts/tasks/cli.yaml new file mode 100644 index 00000000..7ace05a5 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_facts/tasks/cli.yaml @@ -0,0 +1,18 @@ +--- +- name: Collect all cli test cases + ansible.builtin.find: + paths: '{{ role_path }}/tests/cli' + 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 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 + tags: connection_network_cli diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_facts/tasks/main.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_facts/tasks/main.yaml new file mode 100644 index 00000000..19f69723 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_facts/tasks/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Include tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_facts/tests/cli/all_facts.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_facts/tests/cli/all_facts.yaml new file mode 100644 index 00000000..9aa8a8b1 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_facts/tests/cli/all_facts.yaml @@ -0,0 +1,27 @@ +--- +- ansible.builtin.debug: + msg: "START cli/all_facts.yaml on connection={{ ansible_connection }}" + +- name: test getting all facts + register: result + cisco.asa.asa_facts: + gather_subset: + - all + +- 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" + - result.ansible_facts.ansible_net_filesystems is defined + - result.ansible_facts.ansible_net_memfree_mb > 1 + - result.ansible_facts.ansible_net_memtotal_mb > 1 + +- assert: + that: '{{ item.value.spacetotal_kb }} > {{ item.value.spacefree_kb }}' + loop: "{{ lookup('dict', result.ansible_facts.ansible_net_filesystems_info, wantlist=True)\ + \ }}" + +- ansible.builtin.debug: + msg: "END cli/all_facts.yaml on connection={{ ansible_connection }}" diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_facts/tests/cli/default_facts.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_facts/tests/cli/default_facts.yaml new file mode 100644 index 00000000..aa850176 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_facts/tests/cli/default_facts.yaml @@ -0,0 +1,26 @@ +--- +- ansible.builtin.debug: + msg: "START cli/default_facts.yaml on connection={{ ansible_connection }}" + +- name: test getting default facts + register: result + cisco.asa.asa_facts: + +- assert: + that: + - result.changed == false + - "'hardware' in result.ansible_facts.ansible_net_gather_subset" + - "'default' in result.ansible_facts.ansible_net_gather_subset" + - result.ansible_facts.ansible_net_filesystems is defined + - "'config' not in result.ansible_facts.ansible_net_gather_subset" + - result.ansible_facts.ansible_net_filesystems is defined + - result.ansible_facts.ansible_net_memtotal_mb > 10 + - result.ansible_facts.ansible_net_config is not defined + +- assert: + that: '{{ item.value.spacetotal_kb }} > {{ item.value.spacefree_kb }}' + loop: "{{ lookup('dict', result.ansible_facts.ansible_net_filesystems_info, wantlist=True)\ + \ }}" + +- ansible.builtin.debug: + msg: "END cli/default.yaml on connection={{ ansible_connection }}" diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_facts/tests/cli/invalid_subset.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_facts/tests/cli/invalid_subset.yaml new file mode 100644 index 00000000..7b528230 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_facts/tests/cli/invalid_subset.yaml @@ -0,0 +1,36 @@ +--- +- ansible.builtin.debug: + msg: "START cli/invalid_subset.yaml on connection={{ ansible_connection + }}" + +- name: test invalid subset (foobar) + register: result + ignore_errors: true + cisco.asa.asa_facts: + gather_subset: + - foobar + +- assert: + that: + - result.changed == false + - result.failed == true + - result.msg == 'Subset must be one of [config, default, hardware], + got foobar' + +- name: test subset specified multiple times + register: result + ignore_errors: true + cisco.asa.asa_facts: + gather_subset: + - '!hardware' + - hardware + +- assert: + that: + - result.changed == false + - result.failed == true + - result.msg == 'Bad subset' + ignore_errors: true + +- ansible.builtin.debug: + msg: "END cli/invalid_subset.yaml on connection={{ ansible_connection }}" diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_facts/tests/cli/not_hardware.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_facts/tests/cli/not_hardware.yaml new file mode 100644 index 00000000..4b5d5e64 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_facts/tests/cli/not_hardware.yaml @@ -0,0 +1,23 @@ +--- +- ansible.builtin.debug: + msg: "START cli/not_hardware_facts.yaml on connection={{ ansible_connection + }}" + +- name: test not hardware + register: result + cisco.asa.asa_facts: + gather_subset: + - '!hardware' + +- assert: + that: + - result.changed == false + - "'config' in result.ansible_facts.ansible_net_gather_subset" + - "'default' 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 + - result.ansible_facts.ansible_net_filesystems_info is not defined + +- ansible.builtin.debug: + msg: "END cli/not_hardware_facts.yaml on connection={{ ansible_connection + }}" diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/defaults/main.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/defaults/main.yaml new file mode 100644 index 00000000..852a6bee --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: '[^_].*' +test_items: [] diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tasks/cli.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tasks/cli.yaml new file mode 100644 index 00000000..31591418 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tasks/cli.yaml @@ -0,0 +1,22 @@ +--- +- name: Collect all cli test cases + ansible.builtin.find: + paths: '{{ role_path }}/tests/cli' + patterns: '{{ testcase }}.yaml' + use_regex: true + register: test_cases + delegate_to: localhost + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + delegate_to: localhost + +- name: Run test case (connection=ansible.netcommon.network_cli) + ansible.builtin.include_tasks: '{{ test_case_to_run }}' + vars: + ansible_connection: ansible.netcommon.network_cli + with_items: '{{ test_items }}' + loop_control: + loop_var: test_case_to_run + tags: connection_network_cli diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tasks/main.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tasks/main.yaml new file mode 100644 index 00000000..19f69723 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tasks/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Include tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/_parsed.cfg b/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/_parsed.cfg new file mode 100644 index 00000000..ead97272 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/_parsed.cfg @@ -0,0 +1,8 @@ +object-group network test_og_network + description test_og_network + network-object host 192.0.2.1 + network-object 192.0.2.0 255.255.255.0 +object-group network test_network_og + network-object 2001:db8:3::/64 +object-group service test_og_service + service-object tcp-udp
\ No newline at end of file diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/_populate_config.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/_populate_config.yaml new file mode 100644 index 00000000..ec02e549 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/_populate_config.yaml @@ -0,0 +1,45 @@ +--- +- name: Populate Config + cisco.asa.asa_ogs: + config: + - object_type: network + object_groups: + - name: test_og_network + description: test_og_network + network_object: + host: + - 192.0.2.1 + - 192.0.2.2 + address: + - 192.0.2.0 255.255.255.0 + - 198.51.100.0 255.255.255.0 + - name: test_network_og + description: test_network_og + network_object: + host: + - 192.0.3.1 + - 192.0.3.2 + ipv6_address: + - 2001:db8:3::/64 + - object_type: security + object_groups: + - name: test_og_security + description: test_security + security_group: + sec_name: + - test_1 + - test_2 + tag: + - 10 + - 20 + - object_type: user + object_groups: + - name: test_og_user + description: test_user + user_object: + user: + - name: new_user_1 + domain: LOCAL + - name: new_user_2 + domain: LOCAL + state: merged diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/_remove_config.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/_remove_config.yaml new file mode 100644 index 00000000..53a5bb95 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/_remove_config.yaml @@ -0,0 +1,4 @@ +--- +- name: Remove Config + cisco.asa.asa_ogs: + state: deleted diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/deleted.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/deleted.yaml new file mode 100644 index 00000000..5e7293a3 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/deleted.yaml @@ -0,0 +1,61 @@ +--- +- ansible.builtin.debug: + msg: Start asa_ogs deleted integration tests ansible_connection={{ + ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml + +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + + - name: Delete given module attributes + register: result + cisco.asa.asa_ogs: &id001 + config: + - object_type: network + object_groups: + - name: test_og_network + - object_type: security + object_groups: + - name: test_og_security + state: deleted + + - assert: + that: + - result.commands|length == 2 + - result.changed == true + - result.commands|symmetric_difference(deleted.commands) == [] + + - name: Delete given module attributes (IDEMPOTENT) + register: result + cisco.asa.asa_ogs: *id001 + + - assert: + that: + - result.changed == false + + - ansible.builtin.include_tasks: _populate_config.yaml + + - name: Delete ALL configured module attributes + register: result + cisco.asa.asa_ogs: + state: deleted + + - assert: + that: + - result.commands|length == 4 + - result.changed == true + - result.commands|symmetric_difference(delete_all.commands) == [] + + - name: Delete ALL configured module attributes (IDEMPOTENT) + register: result + cisco.asa.asa_ogs: + state: deleted + + - assert: + that: + - result.changed == false + always: + + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/empty_config.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/empty_config.yaml new file mode 100644 index 00000000..14c2e9ef --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/empty_config.yaml @@ -0,0 +1,60 @@ +--- +- ansible.builtin.debug: + msg: START asa_ogs empty_config.yaml integration tests on connection={{ + ansible_connection }} + +- name: Merged with empty config should give appropriate error message + register: result + ignore_errors: true + cisco.asa.asa_ogs: + config: + state: merged + +- assert: + that: + - result.msg == 'value of config parameter must not be empty for state merged' + +- name: Replaced with empty config should give appropriate error message + register: result + ignore_errors: true + cisco.asa.asa_ogs: + config: + state: replaced + +- assert: + that: + - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Overridden with empty config should give appropriate error message + register: result + ignore_errors: true + cisco.asa.asa_ogs: + config: + state: overridden + +- assert: + that: + - result.msg == 'value of config parameter must not be empty for state overridden' + +- name: Rendered with empty config should give appropriate error message + register: result + ignore_errors: true + cisco.asa.asa_ogs: + config: + state: rendered + +- assert: + that: + - result.msg == 'value of config parameter must not be empty for state rendered' + +- name: Parsed with empty config should give appropriate error message + register: result + ignore_errors: true + cisco.asa.asa_ogs: + running_config: + state: parsed + +- assert: + that: + - result.msg == 'value of running_config parameter must not be empty for state + parsed' diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/gathered.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/gathered.yaml new file mode 100644 index 00000000..82d8be40 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/gathered.yaml @@ -0,0 +1,63 @@ +--- +- ansible.builtin.debug: + msg: "START asa_ogs gathered integration tests on connection={{ ansible_connection + }}" + +- ansible.builtin.include_tasks: _remove_config.yaml + +- block: + + - name: Populate Config for Gather facts + cisco.asa.asa_ogs: + config: + - object_type: network + object_groups: + - name: test_og_network + description: test_og_network + network_object: + host: + - 192.0.2.1 + address: + - 192.0.2.0 255.255.255.0 + - name: test_network_og + description: test_network_og + network_object: + host: + - 192.0.3.1 + ipv6_address: + - 2001:db8:3::/64 + - object_type: security + object_groups: + - name: test_og_security + description: test_security + security_group: + sec_name: + - test_1 + tag: + - 10 + - object_type: user + object_groups: + - name: test_og_user + description: test_user + user_object: + user: + - name: new_user_1 + domain: LOCAL + - name: new_user_2 + domain: LOCAL + state: merged + + - name: Gather the provided configuration with the exisiting running configuration + register: result + cisco.asa.asa_ogs: + config: + state: gathered + + - name: Assert + assert: + that: + - gathered['config'] | symmetric_difference(result.gathered) == [] + - result['changed'] == false + always: + + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/merged.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/merged.yaml new file mode 100644 index 00000000..76d4e716 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/merged.yaml @@ -0,0 +1,73 @@ +--- +- ansible.builtin.debug: + msg: "Start asa_ogs merged integration tests ansible_connection={{ + ansible_connection }}" + +- ansible.builtin.include_tasks: _remove_config.yaml + +- block: + + - name: Merge the provided configuration with the exisiting running configuration + register: result + cisco.asa.asa_ogs: &id001 + config: + - object_type: network + object_groups: + - name: test_og_network + description: test_og_network + network_object: + host: + - 192.0.2.1 + - 192.0.2.2 + address: + - 192.0.2.0 255.255.255.0 + - 198.51.100.0 255.255.255.0 + - name: test_network_og + description: test_network_og + network_object: + host: + - 192.0.3.1 + - 192.0.3.2 + ipv6_address: + - 2001:db8:3::/64 + - object_type: security + object_groups: + - name: test_og_security + description: test_security + security_group: + sec_name: + - test_1 + - test_2 + tag: + - 10 + - 20 + - object_type: user + object_groups: + - name: test_og_user + description: test_user + user_object: + user: + - name: new_user_1 + domain: LOCAL + - name: new_user_2 + domain: LOCAL + state: merged + + - assert: + that: + - result.commands|length == 21 + - result.changed == true + - result.commands|symmetric_difference(merged.commands) == [] + + - name: Merge the provided configuration with the exisiting running configuration + (IDEMPOTENT) + register: result + cisco.asa.asa_ogs: *id001 + + - assert: + that: + - result.commands|length == 0 + - result.changed == false + always: + + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/overridden.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/overridden.yaml new file mode 100644 index 00000000..8e4cf9b3 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/overridden.yaml @@ -0,0 +1,52 @@ +--- +- ansible.builtin.debug: + msg: Start asa_ogs overridden integration tests ansible_connection={{ + ansible_connection }} + +- ansible.builtin.include_tasks: _remove_config.yaml +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + + - name: Overridden module attributes of given object-group + become: true + register: result + cisco.asa.asa_ogs: &id001 + config: + - object_type: network + object_groups: + - name: test_og_network + description: test_og_network_override + network_object: + host: + - 192.0.3.1 + address: + - 192.0.3.0 255.255.255.0 + - object_type: protocol + object_groups: + - name: test_og_protocol + description: test_og_protocol + protocol_object: + protocol: + - tcp + - udp + state: overridden + + - assert: + that: + - result.commands|length == 15 + - result.changed == true + - result.commands|symmetric_difference(overridden.commands) == [] + + - name: Overridden module attributes of given object-group (IDEMPOTENT) + become: true + register: result + cisco.asa.asa_ogs: *id001 + + - assert: + that: + - result.commands|length == 0 + - result.changed == false + always: + + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/parsed.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/parsed.yaml new file mode 100644 index 00000000..44016659 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/parsed.yaml @@ -0,0 +1,16 @@ +--- +- ansible.builtin.debug: + msg: "START asa_ogs parsed integration tests on connection={{ ansible_connection + }}" + +- name: Parse the commands for provided configuration + become: true + register: result + cisco.asa.asa_ogs: + running_config: "{{ lookup('file', '_parsed.cfg') }}" + state: parsed + +- assert: + that: + - result.changed == false + - parsed['config']|symmetric_difference(result.parsed) == [] diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/rendered.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/rendered.yaml new file mode 100644 index 00000000..980c5213 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/rendered.yaml @@ -0,0 +1,58 @@ +--- +- ansible.builtin.debug: + msg: "Start asa_ogs rendered integration tests ansible_connection={{ + ansible_connection }}" + +- block: + + - name: Render the commands for provided configuration + become: true + register: result + cisco.asa.asa_ogs: + config: + - object_type: network + object_groups: + - name: test_og_network + description: test_og_network + network_object: + host: + - 192.0.2.1 + - 192.0.2.2 + address: + - 192.0.2.0 255.255.255.0 + - 198.51.100.0 255.255.255.0 + - name: test_network_og + description: test_network_og + network_object: + host: + - 192.0.3.1 + - 192.0.3.2 + ipv6_address: + - 2001:db8:3::/64 + - object_type: security + object_groups: + - name: test_og_security + description: test_security + security_group: + sec_name: + - test_1 + - test_2 + tag: + - 10 + - 20 + - object_type: user + object_groups: + - name: test_og_user + description: test_user + user_object: + user: + - name: new_user_1 + domain: LOCAL + - name: new_user_2 + domain: LOCAL + state: rendered + + - assert: + that: + - result.changed == false + - result.rendered|symmetric_difference(merged.commands) == [] diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/replaced.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/replaced.yaml new file mode 100644 index 00000000..37728bf1 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/replaced.yaml @@ -0,0 +1,52 @@ +--- +- ansible.builtin.debug: + msg: "Start asa_ogs replced integration tests ansible_connection={{ + ansible_connection }}" + +- ansible.builtin.include_tasks: _remove_config.yaml +- ansible.builtin.include_tasks: _populate_config.yaml + +- block: + + - name: Replace module attributes of given object-group + become: true + register: result + cisco.asa.asa_ogs: &id001 + config: + - object_type: network + object_groups: + - name: test_og_network + description: test_og_network_replace + network_object: + host: + - 192.0.3.1 + address: + - 192.0.3.0 255.255.255.0 + - object_type: protocol + object_groups: + - name: test_og_protocol + description: test_og_protocol + protocol_object: + protocol: + - tcp + - udp + state: replaced + + - assert: + that: + - result.commands|length == 12 + - result.changed == true + - result.commands|symmetric_difference(replaced.commands) == [] + + - name: Replace module attributes of given object-group (IDEMPOTENT) + become: true + register: result + cisco.asa.asa_ogs: *id001 + + - assert: + that: + - result.commands|length == 0 + - result.changed == false + always: + + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/rtt.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/rtt.yaml new file mode 100644 index 00000000..9549a2e5 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/tests/cli/rtt.yaml @@ -0,0 +1,106 @@ +--- +- ansible.builtin.debug: + msg: "START asa_ogs 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.asa.asa_ogs: + config: + - object_type: network + object_groups: + - name: test_og_network + description: test_og_network + network_object: + host: + - 192.0.2.1 + - 192.0.2.2 + address: + - 192.0.2.0 255.255.255.0 + - 198.51.100.0 255.255.255.0 + - name: test_network_og + description: test_network_og + network_object: + host: + - 192.0.3.1 + - 192.0.3.2 + ipv6_address: + - 2001:db8:3::/64 + - object_type: security + object_groups: + - name: test_og_security + description: test_security + security_group: + sec_name: + - test_1 + - test_2 + tag: + - 10 + - 20 + - object_type: user + object_groups: + - name: test_og_user + description: test_user + user_object: + user: + - name: new_user_1 + domain: LOCAL + - name: new_user_2 + domain: LOCAL + state: merged + + - name: Gather Object group facts + cisco.asa.asa_facts: + gather_subset: + - '!all' + - '!min' + gather_network_resources: + - ogs + + - name: Apply the provided configuration (config to be reverted) + register: result + cisco.asa.asa_ogs: + config: + - object_type: network + object_groups: + - name: test_og_network + description: test_og_network_override + network_object: + host: + - 192.0.3.1 + address: + - 192.0.3.0 255.255.255.0 + - object_type: protocol + object_groups: + - name: test_og_protocol + description: test_og_protocol + protocol_object: + protocol: + - tcp + - udp + state: overridden + + - assert: + that: + - result.commands|length == 15 + - result.changed == true + - result.commands|symmetric_difference(overridden.commands) == [] + + - name: Revert back to base config using facts round trip + register: revert + cisco.asa.asa_ogs: + config: "{{ ansible_facts['network_resources']['ogs'] }}" + state: overridden + + - assert: + that: + - revert.commands|length == 24 + - revert.changed == true + - revert.commands|symmetric_difference(rtt.commands) == [] + always: + + - ansible.builtin.include_tasks: _remove_config.yaml diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/vars/main.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/vars/main.yaml new file mode 100644 index 00000000..b5a8e30f --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_ogs/vars/main.yaml @@ -0,0 +1,148 @@ +--- +deleted: + commands: + - no object-group network test_og_network + - no object-group security test_og_security +delete_all: + commands: + - no object-group network test_og_network + - no object-group network test_network_og + - no object-group security test_og_security + - no object-group user test_og_user +merged: + commands: + - object-group security test_og_security + - description test_security + - security-group name test_1 + - security-group name test_2 + - security-group tag 10 + - security-group tag 20 + - object-group network test_og_network + - description test_og_network + - network-object 192.0.2.0 255.255.255.0 + - network-object 198.51.100.0 255.255.255.0 + - network-object host 192.0.2.1 + - network-object host 192.0.2.2 + - object-group network test_network_og + - description test_network_og + - network-object host 192.0.3.1 + - network-object host 192.0.3.2 + - network-object 2001:db8:3::/64 + - object-group user test_og_user + - description test_user + - user LOCAL\new_user_1 + - user LOCAL\new_user_2 +replaced: + commands: + - object-group protocol test_og_protocol + - description test_og_protocol + - protocol tcp + - protocol udp + - object-group network test_og_network + - description test_og_network_replace + - no network-object 192.0.2.0 255.255.255.0 + - no network-object 198.51.100.0 255.255.255.0 + - network-object 192.0.3.0 255.255.255.0 + - no network-object host 192.0.2.1 + - no network-object host 192.0.2.2 + - network-object host 192.0.3.1 +overridden: + commands: + - no object-group security test_og_security + - no object-group user test_og_user + - object-group protocol test_og_protocol + - description test_og_protocol + - protocol tcp + - protocol udp + - object-group network test_og_network + - description test_og_network_override + - no network-object 192.0.2.0 255.255.255.0 + - no network-object 198.51.100.0 255.255.255.0 + - network-object 192.0.3.0 255.255.255.0 + - no network-object host 192.0.2.1 + - no network-object host 192.0.2.2 + - network-object host 192.0.3.1 + - no object-group network test_network_og +gathered: + config: + - object_groups: + - description: test_network_og + name: test_network_og + network_object: + host: + - 192.0.3.1 + ipv6_address: + - 2001:db8:3::/64 + - description: test_og_network + name: test_og_network + network_object: + address: + - 192.0.2.0 255.255.255.0 + host: + - 192.0.2.1 + object_type: network + - object_groups: + - description: test_security + name: test_og_security + security_group: + sec_name: + - test_1 + tag: + - "10" + object_type: security + - object_groups: + - description: test_user + name: test_og_user + user_object: + user: + - domain: LOCAL + name: new_user_1 + - domain: LOCAL + name: new_user_2 + object_type: user +parsed: + config: + - object_groups: + - name: test_network_og + network_object: + ipv6_address: + - 2001:db8:3::/64 + - description: test_og_network + name: test_og_network + network_object: + address: + - 192.0.2.0 255.255.255.0 + host: + - 192.0.2.1 + object_type: network + - object_groups: + - name: test_og_service + services_object: + - protocol: tcp-udp + object_type: service +rtt: + commands: + - no object-group protocol test_og_protocol + - object-group security test_og_security + - description test_security + - security-group name test_2 + - security-group name test_1 + - security-group tag 10 + - security-group tag 20 + - object-group network test_og_network + - description test_og_network + - no network-object 192.0.3.0 255.255.255.0 + - network-object 192.0.2.0 255.255.255.0 + - network-object 198.51.100.0 255.255.255.0 + - no network-object host 192.0.3.1 + - network-object host 192.0.2.1 + - network-object host 192.0.2.2 + - object-group network test_network_og + - description test_network_og + - network-object host 192.0.3.1 + - network-object host 192.0.3.2 + - network-object 2001:db8:3::/64 + - object-group user test_og_user + - description test_user + - user LOCAL\new_user_1 + - user LOCAL\new_user_2 diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_smoke/defaults/main.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_smoke/defaults/main.yaml new file mode 100644 index 00000000..852a6bee --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_smoke/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: '[^_].*' +test_items: [] diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_smoke/tasks/cli.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_smoke/tasks/cli.yaml new file mode 100644 index 00000000..bec00fe7 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_smoke/tasks/cli.yaml @@ -0,0 +1,23 @@ +--- +- name: Collect all cli test cases + ansible.builtin.find: + paths: '{{ role_path }}/tests' + patterns: '{{ testcase }}.yaml' + use_regex: true + register: test_cases + delegate_to: localhost + +- name: Set test_items + ansible.builtin.set_fact: + test_items: "{{ test_cases.files | map(attribute='path') | list }}" + delegate_to: localhost + +- name: Run test case (connection=network_cli) + ansible.builtin.include_tasks: '{{ test_case_to_run }}' + vars: + ansible_connection: network_cli + ansible_network_single_user_mode: true + with_items: '{{ test_items }}' + loop_control: + loop_var: test_case_to_run + tags: connection_network_cli diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_smoke/tasks/main.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_smoke/tasks/main.yaml new file mode 100644 index 00000000..19f69723 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_smoke/tasks/main.yaml @@ -0,0 +1,5 @@ +--- +- name: Include tasks + ansible.builtin.include_tasks: cli.yaml + tags: + - cli diff --git a/ansible_collections/cisco/asa/tests/integration/targets/asa_smoke/tests/caching.yaml b/ansible_collections/cisco/asa/tests/integration/targets/asa_smoke/tests/caching.yaml new file mode 100644 index 00000000..31d0b056 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/integration/targets/asa_smoke/tests/caching.yaml @@ -0,0 +1,102 @@ +--- +- block: + - ansible.builtin.debug: + msg: "START connection={{ ansible_connection }} caching.yaml" + + - set_fact: + merged: + - object-group security test_og_security + - description test_security + - security-group name test_1 + - security-group name test_2 + - security-group tag 10 + - security-group tag 20 + - object-group network test_og_network + - description test_og_network + - network-object 192.0.2.0 255.255.255.0 + - network-object 198.51.100.0 255.255.255.0 + - network-object host 192.0.2.1 + - network-object host 192.0.2.2 + - object-group network test_network_og + - description test_network_og + - network-object host 192.0.3.1 + - network-object host 192.0.3.2 + - network-object 2001:db8:3::/64 + - object-group user test_og_user + - description test_user + - user LOCAL\new_user_1 + - user LOCAL\new_user_2 + + - name: Remove OG Config + cisco.asa.asa_ogs: + state: deleted + ignore_errors: true + + - name: Merge the provided configuration with the exisiting running configuration + cisco.asa.asa_ogs: &id001 + config: + - object_type: network + object_groups: + - name: test_og_network + description: test_og_network + network_object: + host: + - 192.0.2.1 + - 192.0.2.2 + address: + - 192.0.2.0 255.255.255.0 + - 198.51.100.0 255.255.255.0 + - name: test_network_og + description: test_network_og + network_object: + host: + - 192.0.3.1 + - 192.0.3.2 + ipv6_address: + - 2001:db8:3::/64 + - object_type: security + object_groups: + - name: test_og_security + description: test_security + security_group: + sec_name: + - test_1 + - test_2 + tag: + - 10 + - 20 + - object_type: user + object_groups: + - name: test_og_user + description: test_user + user_object: + user: + - name: new_user_1 + domain: LOCAL + - name: new_user_2 + domain: LOCAL + state: merged + register: result + + - assert: + that: + - result.commands|length == 21 + - result.changed == true + - result.commands|symmetric_difference(merged) == [] + + - name: Merge the provided configuration with the exisiting running configuration + (IDEMPOTENT) + register: result + cisco.asa.asa_ogs: *id001 + + - assert: + that: + - result.commands|length == 0 + - result.changed == false + + always: + - name: Remove OG Config + cisco.asa.asa_ogs: + state: deleted + ignore_errors: true + when: ansible_connection == "network_cli" and ansible_network_single_user_mode|d(False) diff --git a/ansible_collections/cisco/asa/tests/sanity/ignore-2.10.txt b/ansible_collections/cisco/asa/tests/sanity/ignore-2.10.txt new file mode 100644 index 00000000..65598cad --- /dev/null +++ b/ansible_collections/cisco/asa/tests/sanity/ignore-2.10.txt @@ -0,0 +1,7 @@ +plugins/terminal/asa.py compile-2.6!skip +plugins/terminal/asa.py compile-2.7!skip +plugins/action/asa.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` +plugins/module_utils/network/asa/config/acls/acls.py compile-2.6!skip +plugins/module_utils/network/asa/config/ogs/ogs.py compile-2.6!skip +plugins/module_utils/network/asa/config/acls/acls.py import-2.6!skip +plugins/module_utils/network/asa/config/ogs/ogs.py import-2.6!skip diff --git a/ansible_collections/cisco/asa/tests/sanity/ignore-2.11.txt b/ansible_collections/cisco/asa/tests/sanity/ignore-2.11.txt new file mode 100644 index 00000000..5f802771 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/sanity/ignore-2.11.txt @@ -0,0 +1,8 @@ +plugins/terminal/asa.py compile-2.6!skip +plugins/terminal/asa.py compile-2.7!skip +plugins/terminal/asa.py import-2.7!skip +plugins/action/asa.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` +plugins/module_utils/network/asa/config/acls/acls.py compile-2.6!skip +plugins/module_utils/network/asa/config/ogs/ogs.py compile-2.6!skip +plugins/module_utils/network/asa/config/acls/acls.py import-2.6!skip +plugins/module_utils/network/asa/config/ogs/ogs.py import-2.6!skip diff --git a/ansible_collections/cisco/asa/tests/sanity/ignore-2.12.txt b/ansible_collections/cisco/asa/tests/sanity/ignore-2.12.txt new file mode 100644 index 00000000..85ed7df5 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/sanity/ignore-2.12.txt @@ -0,0 +1,5 @@ +plugins/action/asa.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` +plugins/module_utils/network/asa/config/acls/acls.py compile-2.6!skip +plugins/module_utils/network/asa/config/ogs/ogs.py compile-2.6!skip +plugins/module_utils/network/asa/config/acls/acls.py import-2.6!skip +plugins/module_utils/network/asa/config/ogs/ogs.py import-2.6!skip diff --git a/ansible_collections/cisco/asa/tests/sanity/ignore-2.13.txt b/ansible_collections/cisco/asa/tests/sanity/ignore-2.13.txt new file mode 100644 index 00000000..3d2a4f58 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/sanity/ignore-2.13.txt @@ -0,0 +1 @@ +plugins/action/asa.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` diff --git a/ansible_collections/cisco/asa/tests/sanity/ignore-2.14.txt b/ansible_collections/cisco/asa/tests/sanity/ignore-2.14.txt new file mode 100644 index 00000000..3d2a4f58 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/sanity/ignore-2.14.txt @@ -0,0 +1 @@ +plugins/action/asa.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` diff --git a/ansible_collections/cisco/asa/tests/sanity/ignore-2.15.txt b/ansible_collections/cisco/asa/tests/sanity/ignore-2.15.txt new file mode 100644 index 00000000..3d2a4f58 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/sanity/ignore-2.15.txt @@ -0,0 +1 @@ +plugins/action/asa.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` diff --git a/ansible_collections/cisco/asa/tests/sanity/ignore-2.9.txt b/ansible_collections/cisco/asa/tests/sanity/ignore-2.9.txt new file mode 100644 index 00000000..65598cad --- /dev/null +++ b/ansible_collections/cisco/asa/tests/sanity/ignore-2.9.txt @@ -0,0 +1,7 @@ +plugins/terminal/asa.py compile-2.6!skip +plugins/terminal/asa.py compile-2.7!skip +plugins/action/asa.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` +plugins/module_utils/network/asa/config/acls/acls.py compile-2.6!skip +plugins/module_utils/network/asa/config/ogs/ogs.py compile-2.6!skip +plugins/module_utils/network/asa/config/acls/acls.py import-2.6!skip +plugins/module_utils/network/asa/config/ogs/ogs.py import-2.6!skip diff --git a/ansible_collections/cisco/asa/tests/unit/__init__.py b/ansible_collections/cisco/asa/tests/unit/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/asa/tests/unit/__init__.py diff --git a/ansible_collections/cisco/asa/tests/unit/compat/__init__.py b/ansible_collections/cisco/asa/tests/unit/compat/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/asa/tests/unit/compat/__init__.py diff --git a/ansible_collections/cisco/asa/tests/unit/compat/builtins.py b/ansible_collections/cisco/asa/tests/unit/compat/builtins.py new file mode 100644 index 00000000..bfc8adfb --- /dev/null +++ b/ansible_collections/cisco/asa/tests/unit/compat/builtins.py @@ -0,0 +1,34 @@ +# (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 for python2.7 +# + +# One unittest needs to import builtins via __import__() so we need to have +# the string that represents it +try: + import __builtin__ +except ImportError: + BUILTINS = "builtins" +else: + BUILTINS = "__builtin__" diff --git a/ansible_collections/cisco/asa/tests/unit/compat/mock.py b/ansible_collections/cisco/asa/tests/unit/compat/mock.py new file mode 100644 index 00000000..2ea98a17 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/unit/compat/mock.py @@ -0,0 +1,128 @@ +# pylint: skip-file +# (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/asa/tests/unit/compat/unittest.py b/ansible_collections/cisco/asa/tests/unit/compat/unittest.py new file mode 100644 index 00000000..df3379b8 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/unit/compat/unittest.py @@ -0,0 +1,39 @@ +# (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/asa/tests/unit/mock/__init__.py b/ansible_collections/cisco/asa/tests/unit/mock/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/asa/tests/unit/mock/__init__.py diff --git a/ansible_collections/cisco/asa/tests/unit/mock/loader.py b/ansible_collections/cisco/asa/tests/unit/mock/loader.py new file mode 100644 index 00000000..c1382bb5 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/unit/mock/loader.py @@ -0,0 +1,116 @@ +# (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.parsing.dataloader import DataLoader +from ansible.module_utils._text import to_bytes, to_text + + +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, file_name): + path = to_text(file_name) + if path in self._file_mapping: + return to_bytes(self._file_mapping[file_name]), False + else: + raise AnsibleParserError("file not found: %s" % file_name) + + 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/asa/tests/unit/mock/path.py b/ansible_collections/cisco/asa/tests/unit/mock/path.py new file mode 100644 index 00000000..3bd0cdee --- /dev/null +++ b/ansible_collections/cisco/asa/tests/unit/mock/path.py @@ -0,0 +1,10 @@ +from __future__ import absolute_import, division, print_function + +__metaclass__ = type +from ansible_collections.cisco.asa.tests.unit.compat.mock import MagicMock +from ansible.utils.path import unfrackpath + + +mock_unfrackpath_noop = MagicMock( + spec_set=unfrackpath, side_effect=lambda x, *args, **kwargs: x +) diff --git a/ansible_collections/cisco/asa/tests/unit/mock/procenv.py b/ansible_collections/cisco/asa/tests/unit/mock/procenv.py new file mode 100644 index 00000000..e02cae04 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/unit/mock/procenv.py @@ -0,0 +1,94 @@ +# (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 sys +import json + +from contextlib import contextmanager +from io import BytesIO, StringIO +from ansible_collections.cisco.asa.tests.unit.compat import unittest +from ansible.module_utils.six import PY3 +from ansible.module_utils._text import to_bytes + + +@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/asa/tests/unit/mock/vault_helper.py b/ansible_collections/cisco/asa/tests/unit/mock/vault_helper.py new file mode 100644 index 00000000..b34ae134 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/unit/mock/vault_helper.py @@ -0,0 +1,42 @@ +# 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/asa/tests/unit/mock/yaml_helper.py b/ansible_collections/cisco/asa/tests/unit/mock/yaml_helper.py new file mode 100644 index 00000000..5df30aae --- /dev/null +++ b/ansible_collections/cisco/asa/tests/unit/mock/yaml_helper.py @@ -0,0 +1,167 @@ +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.loader import AnsibleLoader +from ansible.parsing.yaml.dumper import AnsibleDumper + + +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/asa/tests/unit/modules/__init__.py b/ansible_collections/cisco/asa/tests/unit/modules/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/asa/tests/unit/modules/__init__.py diff --git a/ansible_collections/cisco/asa/tests/unit/modules/conftest.py b/ansible_collections/cisco/asa/tests/unit/modules/conftest.py new file mode 100644 index 00000000..e19a1e04 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/unit/modules/conftest.py @@ -0,0 +1,40 @@ +# 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.six import string_types +from ansible.module_utils._text import to_bytes +from ansible.module_utils.common._collections_compat import MutableMapping + + +@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/asa/tests/unit/modules/network/__init__.py b/ansible_collections/cisco/asa/tests/unit/modules/network/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/asa/tests/unit/modules/network/__init__.py diff --git a/ansible_collections/cisco/asa/tests/unit/modules/network/asa/__init__.py b/ansible_collections/cisco/asa/tests/unit/modules/network/asa/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/asa/tests/unit/modules/network/asa/__init__.py diff --git a/ansible_collections/cisco/asa/tests/unit/modules/network/asa/asa_module.py b/ansible_collections/cisco/asa/tests/unit/modules/network/asa/asa_module.py new file mode 100644 index 00000000..b86ebbb1 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/unit/modules/network/asa/asa_module.py @@ -0,0 +1,93 @@ +# -*- coding: utf-8 -*- + +# (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) + +# Make coding more python3-ish +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +import os +import json + +from ansible_collections.cisco.asa.tests.unit.modules.utils import ( + AnsibleExitJson, + AnsibleFailJson, + ModuleTestCase, +) + + +fixture_path = os.path.join(os.path.dirname(__file__), "fixtures") +fixture_data = {} + + +def load_fixture(name): + path = os.path.join(fixture_path, 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 TestAsaModule(ModuleTestCase): + def execute_module( + self, + failed=False, + changed=False, + commands=None, + sort=True, + defaults=False, + ): + + self.load_fixtures(commands) + + 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: + 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): + pass diff --git a/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/__init__.py b/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/__init__.py diff --git a/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/asa_acls_config.cfg b/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/asa_acls_config.cfg new file mode 100644 index 00000000..cb1bd0b2 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/asa_acls_config.cfg @@ -0,0 +1,24 @@ +access-list cached ACL log flows: total 0, denied 0 (deny-flow-max 4096) + alert-interval 300 +access-list test_global_access; 1 elements; name hash: 0xaa83124c +access-list test_global_access line 1 extended deny tcp any any eq www log errors interval 300 (hitcnt=0) 0x849e9e8f +access-list test_global_access line 2 remark test global remark +access-list test_access; 2 elements; name hash: 0x96b5d78b +access-list test_access line 1 extended deny tcp 192.0.2.0 255.255.255.0 192.0.3.0 255.255.255.0 eq www log default (hitcnt=0) 0xdc46eb6e +access-list test_access line 2 extended deny igrp 198.51.100.0 255.255.255.0 198.51.110.0 255.255.255.0 log errors interval 300 (hitcnt=0) 0x831d8948 +access-list test_access line 3 extended permit ip host 192.0.2.2 any interval 300 (hitcnt=0) 0x831d897d +access-list test_R1_traffic; 1 elements; name hash: 0x2c20a0c +access-list test_R1_traffic line 1 extended deny tcp 2001:db8:0:3::/64 eq www 2001:fc8:0:4::/64 eq telnet inactive (hitcnt=0) (inactive) 0x11821a52 +access-list test_R1_traffic line 2 extended permit ip host 2001:db8::1 any6 (hitcnt=0) 0x82a59c34 +access-list ansible_test; 1 elements; name hash: 0x1b2b1138 +access-list ansible_test line 1 remark HostA +access-list ansible_test line 2 extended deny ip host 192.0.5.1 any4 +access-list management_in; 2 elements; name hash: 0x4acd1688 +access-list management_in line 1 extended permit tcp host 198.51.100.5 range 49152 65535 198.51.100.0 255.255.255.0 eq 100 (hitcnt=0) 0x53ec762f +access-list management_in line 2 extended permit tcp 198.51.101.0 255.255.255.0 object-group ALLSERV.12 eq 9389 (hitcnt=0) 0xc8881c8c + access-list management_in line 2 extended permit tcp 198.51.101.0 255.255.255.0 1.1.1.1 1.1.1.1 eq 9389 (hitcnt=0) 0xd39d4f42 +access-list management_in line 3 extended permit ip any4 host 192.0.2.1 +access-list MyACL; 10 elements; name hash: 0x436611e8 +access-list MyACL line 1 extended permit tcp object-group O-Environments any object-group O-Windows-TCP (hitcnt=0) 0x61fe98bb + access-list MyACL line 1 extended permit tcp 10.20.30.0 255.255.255.0 any eq 3389 (hitcnt=0) 0x69856097 + access-list MyACL line 1 extended permit tcp 10.20.31.0 255.255.255.0 any eq 3389 (hitcnt=0) 0xca48629c
\ No newline at end of file diff --git a/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/asa_facts_dir b/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/asa_facts_dir new file mode 100644 index 00000000..cd8caa3f --- /dev/null +++ b/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/asa_facts_dir @@ -0,0 +1,10 @@ + +Directory of disk0:/ + +11 drwx 4096 04:49:48 May 16 2019 smart-log +7 -rwx 0 05:56:43 Nov 22 2019 use_ttyS0 +8 drwx 4096 04:45:10 May 16 2019 log +13 drwx 4096 04:49:52 May 16 2019 coredumpinfo + +1 file(s) total size: 0 bytes +8571076608 bytes total (8549351424 bytes free/99% free)
\ No newline at end of file diff --git a/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/asa_facts_show_memory b/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/asa_facts_show_memory new file mode 100644 index 00000000..13bea8cb --- /dev/null +++ b/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/asa_facts_show_memory @@ -0,0 +1,14 @@ +Free memory: 7176970240 bytes (84%) +Used memory: 2590688668 bytes (16%) +------------- ------------------ +Total memory: 8589934592 bytes (100%) + +Virtual platform memory +----------------------- +Provisioned 8192 MB +Allowed 4096 MB + +Note: Free memory is the free system memory. Additional memory may + be available from memory pools internal to the firewall process. + Use 'show memory detail' to see this information, but use it + with care since it may cause CPU hogs and packet loss under load.
\ No newline at end of file diff --git a/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/asa_facts_show_version b/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/asa_facts_show_version new file mode 100644 index 00000000..d652d7be --- /dev/null +++ b/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/asa_facts_show_version @@ -0,0 +1,50 @@ + +Cisco Adaptive Security Appliance Software Version 9.10(1)11 +Firepower Extensible Operating System Version 2.4(1.227) +Device Manager Version 7.10(1) + +Compiled on Thu 21-Feb-19 14:10 PST by builders +System image file is "boot:/asa9101-11-smp-k8.bin" +Config file at boot was "startup-config" + +ciscoasa up 21 days 7 hours + +Hardware: ASAv, 8192 MB RAM, CPU Xeon E5 series 2300 MHz, 1 CPU (2 cores) +Model Id: ASAv10 +Internal ATA Compact Flash, 10240MB +Slot 1: ATA Compact Flash, 10240MB +BIOS Flash Firmware Hub @ 0x0, 0KB + + + 0: Ext: Management0/0 : address is 02ac.8ef2.59aa, irq 0 + 1: Ext: GigabitEthernet0/0 : address is 024e.1f85.94da, irq 0 + +License mode: AWS Licensing +License state: LICENSED + +Licensed features for this platform: +Maximum VLANs : 50 +Inside Hosts : Unlimited +Failover : Active/Standby +Encryption-DES : Enabled +Encryption-3DES-AES : Enabled +Security Contexts : 0 +Carrier : Enabled +AnyConnect Premium Peers : 250 +AnyConnect Essentials : Disabled +Other VPN Peers : 250 +Total VPN Peers : 250 +AnyConnect for Mobile : Enabled +AnyConnect for Cisco VPN Phone : Enabled +Advanced Endpoint Assessment : Enabled +Shared License : Disabled +Total TLS Proxy Sessions : 498 +Botnet Traffic Filter : Enabled +Cluster : Disabled + +Serial Number: 9AWFX1S46VQ + +Image type : Release +Key version : A + +Configuration last modified by enable_15 at 06:41:15.559 UTC Fri Nov 22 2019
\ No newline at end of file diff --git a/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/asa_og_config.cfg b/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/asa_og_config.cfg new file mode 100644 index 00000000..27f22120 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/asa_og_config.cfg @@ -0,0 +1,5 @@ +object-group network test_nets +description ansible_test object-group description +network-object host 8.8.8.8 +network-object 192.168.0.0 255.255.0.0 +group-object awx_lon diff --git a/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/asa_ogs_config.cfg b/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/asa_ogs_config.cfg new file mode 100644 index 00000000..e5368f03 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/asa_ogs_config.cfg @@ -0,0 +1,32 @@ +object-group network ANSIBLE_TEST + network-object object TEST1 + network-object object TEST2 +object-group network test_og_network + description test_og_network + network-object host 192.0.2.1 + network-object host 2001:db8::1 + network-object 192.0.2.0 255.255.255.0 +object-group network group_network_obj + group-object ANSIBLE_TEST +object-group service sg-skype_ports + service-object tcp-udp destination range sip 5061 +object-group service 3300 tcp + port-object eq 3300 +object-group service test_og_service + service-object ipinip + service-object tcp-udp + service-object tcp destination range 100 200 + service-object tcp source eq 1234 destination gt nfs +object-group service O-UNIX-TCP tcp + port-object eq https + port-object range 100 400 +object-group user test_user_obj + description test_user + user-group domain\\test1 + user-group domain\\test2 + user LOCAL\test1 +object-group user group_user_obj + group-object test_user_obj +object-group protocol test_protocol + protocol-object 16 +object-group network bug_test_obj
\ No newline at end of file diff --git a/ansible_collections/cisco/asa/tests/unit/modules/network/asa/test_asa_acls.py b/ansible_collections/cisco/asa/tests/unit/modules/network/asa/test_asa_acls.py new file mode 100644 index 00000000..cb025614 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/unit/modules/network/asa/test_asa_acls.py @@ -0,0 +1,873 @@ +# +# (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 + +import sys + +import pytest + +# These tests and/or the module under test are unstable on Python 3.5. +# See: https://app.shippable.com/github/ansible/ansible/runs/161331/15/tests +# This is most likely due to CPython 3.5 not maintaining dict insertion order. +pytestmark = pytest.mark.skipif( + sys.version_info[:2] == (3, 5), + reason="Tests and/or module are unstable on Python 3.5.", +) + +from ansible_collections.cisco.asa.tests.unit.compat.mock import patch +from ansible_collections.cisco.asa.plugins.modules import asa_acls +from ansible_collections.cisco.asa.tests.unit.modules.utils import ( + set_module_args, +) +from .asa_module import TestAsaModule, load_fixture + + +class TestAsaAclsModule(TestAsaModule): + module = asa_acls + + def setUp(self): + super(TestAsaAclsModule, 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.rm_base.resource_module_base." + "get_resource_connection" + ) + self.get_resource_connection_facts = ( + self.mock_get_resource_connection_facts.start() + ) + + self.mock_edit_config = patch( + "ansible_collections.cisco.asa.plugins.module_utils.network.asa.providers.providers.CliProvider.edit_config" + ) + self.edit_config = self.mock_edit_config.start() + + self.mock_execute_show_command = patch( + "ansible_collections.cisco.asa.plugins.module_utils.network.asa.facts.acls.acls." + "AclsFacts.get_acls_config" + ) + self.execute_show_command = self.mock_execute_show_command.start() + + def tearDown(self): + super(TestAsaAclsModule, 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): + def load_from_file(*args, **kwargs): + return load_fixture("asa_acls_config.cfg") + + self.execute_show_command.side_effect = load_from_file + + def test_asa_acls_merged(self): + set_module_args( + dict( + config=dict( + acls=[ + dict( + aces=[ + dict( + destination=dict( + object_group="test_network_og", + port_protocol=dict(eq="www"), + ), + grant="deny", + line=2, + log="default", + protocol="tcp", + protocol_options=dict(tcp="true"), + source=dict( + object_group="test_og_network" + ), + ) + ], + acl_type="extended", + name="test_global_access", + ), + dict( + aces=[ + dict( + destination=dict( + any="true", + service_object_group="O-UNIX-TCP", + ), + grant="permit", + line=2, + protocol="tcp", + protocol_options=dict(tcp="true"), + source=dict(object_group="O-Environments"), + ), + ], + acl_type="extended", + name="MyACL", + ), + ] + ), + state="merged", + ) + ) + result = self.execute_module(changed=True) + commands = [ + "access-list test_global_access line 2 extended deny tcp object-group test_og_network object-group test_network_og eq www log default", + "access-list MyACL line 2 extended permit tcp object-group O-Environments any object-group O-UNIX-TCP", + ] + self.assertEqual(result["commands"], commands) + + def test_asa_acls_merged_idempotent(self): + set_module_args( + dict( + config=dict( + acls=[ + dict( + aces=[ + dict(line=1, remark="HostA"), + dict( + destination=dict(any4=True), + grant="deny", + line=2, + protocol="ip", + protocol_options=dict(ip="true"), + source=dict(host="192.0.5.1"), + ), + ], + acl_type="extended", + name="ansible_test", + ), + dict( + aces=[ + dict( + destination=dict( + any="true", + port_protocol=dict(eq="www"), + ), + grant="deny", + line=1, + log="errors", + protocol="tcp", + protocol_options=dict(tcp="true"), + source=dict(any="true"), + ), + dict(line=2, remark="test global remark"), + ], + acl_type="extended", + name="test_global_access", + ), + dict( + aces=[ + dict( + destination=dict( + address="192.0.3.0", + netmask="255.255.255.0", + port_protocol=dict(eq="www"), + ), + grant="deny", + line=1, + log="default", + protocol="tcp", + protocol_options=dict(tcp="true"), + source=dict( + address="192.0.2.0", + netmask="255.255.255.0", + ), + ), + dict( + destination=dict( + address="198.51.110.0", + netmask="255.255.255.0", + ), + grant="deny", + line=2, + log="errors", + protocol="igrp", + protocol_options=dict(igrp="true"), + source=dict( + address="198.51.100.0", + netmask="255.255.255.0", + ), + ), + dict( + destination=dict(any="true"), + grant="permit", + line=3, + protocol="ip", + protocol_options=dict(ip="true"), + source=dict(host="192.0.2.2"), + ), + ], + acl_type="extended", + name="test_access", + ), + dict( + aces=[ + dict( + destination=dict( + address="198.51.100.0", + netmask="255.255.255.0", + port_protocol=dict(eq="100"), + ), + grant="permit", + line=1, + protocol="tcp", + protocol_options=dict(tcp="true"), + source=dict( + host="198.51.100.5", + port_protocol=dict( + range=dict(end=65535, start=49152) + ), + ), + ), + dict( + destination=dict( + object_group="ALLSERV.12", + port_protocol=dict(eq="9389"), + ), + grant="permit", + line=2, + protocol="tcp", + protocol_options=dict(tcp="true"), + source=dict( + address="198.51.101.0", + netmask="255.255.255.0", + ), + ), + dict( + destination=dict(host="192.0.2.1"), + grant="permit", + line=3, + protocol="ip", + protocol_options=dict(ip="true"), + source=dict(any4=True), + ), + ], + acl_type="extended", + name="management_in", + ), + dict( + aces=[ + dict( + destination=dict( + any="true", + service_object_group="O-Windows-TCP", + ), + grant="permit", + line=1, + protocol="tcp", + protocol_options=dict(tcp="true"), + source=dict(object_group="O-Environments"), + ), + ], + acl_type="extended", + name="MyACL", + ), + dict( + aces=[ + dict( + destination=dict( + address="2001:fc8:0:4::/64", + port_protocol=dict(eq="telnet"), + ), + grant="deny", + inactive="true", + line=1, + protocol="tcp", + protocol_options=dict(tcp="true"), + source=dict( + address="2001:db8:0:3::/64", + port_protocol=dict(eq="www"), + ), + ), + dict( + destination=dict(any6=True), + grant="permit", + line=2, + protocol="ip", + protocol_options=dict(ip=True), + source=dict(host="2001:db8::1"), + ), + ], + acl_type="extended", + name="test_R1_traffic", + ), + ] + ), + state="merged", + ) + ) + self.execute_module(changed=False, commands=[], sort=True) + + def test_asa_acls_replaced(self): + set_module_args( + dict( + config=dict( + acls=[ + dict( + name="test_access", + acl_type="extended", + aces=[ + dict( + destination=dict( + address="198.51.102.0", + netmask="255.255.255.0", + ), + grant="deny", + line=1, + log="default", + protocol="igrp", + protocol_options=dict(igrp="true"), + source=dict( + address="198.51.101.0", + netmask="255.255.255.0", + ), + time_range="temp", + ) + ], + ), + dict( + aces=[ + dict(line=1, remark="HostA0"), + dict( + destination=dict(any4=True), + grant="deny", + line=2, + protocol="ip", + protocol_options=dict(ip="true"), + source=dict(host="192.0.5.1"), + ), + ], + acl_type="extended", + name="ansible_test", + ), + ] + ), + state="replaced", + ) + ) + result = self.execute_module(changed=True) + commands = [ + "no access-list ansible_test line 1 remark HostA", + "no access-list test_access line 3 extended permit ip host 192.0.2.2 any", + "no access-list test_access line 2 extended deny igrp 198.51.100.0 255.255.255.0 198.51.110.0 255.255.255.0 log errors", + "no access-list test_access line 1 extended deny tcp 192.0.2.0 255.255.255.0 192.0.3.0 255.255.255.0 eq www log default", + "access-list test_access line 1 extended deny igrp 198.51.101.0 255.255.255.0 198.51.102.0 255.255.255.0 log default time-range temp", + "access-list ansible_test line 1 remark HostA0", + ] + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_asa_acls_replaced_idempotent(self): + set_module_args( + dict( + config=dict( + acls=[ + dict( + aces=[ + dict(line=1, remark="HostA"), + dict( + destination=dict(any4=True), + grant="deny", + line=2, + protocol="ip", + protocol_options=dict(ip="true"), + source=dict(host="192.0.5.1"), + ), + ], + acl_type="extended", + name="ansible_test", + ), + dict( + aces=[ + dict( + destination=dict( + any="true", + port_protocol=dict(eq="www"), + ), + grant="deny", + line=1, + log="errors", + protocol="tcp", + protocol_options=dict(tcp="true"), + source=dict(any="true"), + ), + dict(line=2, remark="test global remark"), + ], + acl_type="extended", + name="test_global_access", + ), + dict( + aces=[ + dict( + destination=dict( + address="192.0.3.0", + netmask="255.255.255.0", + port_protocol=dict(eq="www"), + ), + grant="deny", + line=1, + log="default", + protocol="tcp", + protocol_options=dict(tcp="true"), + source=dict( + address="192.0.2.0", + netmask="255.255.255.0", + ), + ), + dict( + destination=dict( + address="198.51.110.0", + netmask="255.255.255.0", + ), + grant="deny", + line=2, + log="errors", + protocol="igrp", + protocol_options=dict(igrp="true"), + source=dict( + address="198.51.100.0", + netmask="255.255.255.0", + ), + ), + dict( + destination=dict(any="true"), + grant="permit", + line=3, + protocol="ip", + protocol_options=dict(ip="true"), + source=dict(host="192.0.2.2"), + ), + ], + acl_type="extended", + name="test_access", + ), + dict( + aces=[ + dict( + destination=dict( + address="198.51.100.0", + netmask="255.255.255.0", + port_protocol=dict(eq="100"), + ), + grant="permit", + line=1, + protocol="tcp", + protocol_options=dict(tcp="true"), + source=dict( + host="198.51.100.5", + port_protocol=dict( + range=dict(end=65535, start=49152) + ), + ), + ), + dict( + destination=dict( + object_group="ALLSERV.12", + port_protocol=dict(eq="9389"), + ), + grant="permit", + line=2, + protocol="tcp", + protocol_options=dict(tcp="true"), + source=dict( + address="198.51.101.0", + netmask="255.255.255.0", + ), + ), + dict( + destination=dict(host="192.0.2.1"), + grant="permit", + line=3, + protocol="ip", + protocol_options=dict(ip="true"), + source=dict(any4=True), + ), + ], + acl_type="extended", + name="management_in", + ), + dict( + aces=[ + dict( + destination=dict( + any="true", + service_object_group="O-Windows-TCP", + ), + grant="permit", + line=1, + protocol="tcp", + protocol_options=dict(tcp="true"), + source=dict(object_group="O-Environments"), + ), + ], + acl_type="extended", + name="MyACL", + ), + dict( + aces=[ + dict( + destination=dict( + address="2001:fc8:0:4::/64", + port_protocol=dict(eq="telnet"), + ), + grant="deny", + inactive="true", + line=1, + protocol="tcp", + protocol_options=dict(tcp="true"), + source=dict( + address="2001:db8:0:3::/64", + port_protocol=dict(eq="www"), + ), + ), + dict( + destination=dict(any6=True), + grant="permit", + line=2, + protocol="ip", + protocol_options=dict(ip=True), + source=dict(host="2001:db8::1"), + ), + ], + acl_type="extended", + name="test_R1_traffic", + ), + ] + ), + state="replaced", + ) + ) + self.execute_module(changed=False, commands=[], sort=True) + + def test_asa_acls_overridden(self): + set_module_args( + dict( + config=dict( + acls=[ + dict( + name="test_global_access", + acl_type="extended", + aces=[ + dict( + destination=dict( + address="198.51.110.0", + netmask="255.255.255.0", + port_protocol=dict(eq="www"), + ), + grant="deny", + line=1, + log="errors", + protocol="tcp", + protocol_options=dict(tcp="true"), + source=dict( + address="198.51.100.0", + netmask="255.255.255.0", + ), + ) + ], + ) + ] + ), + state="overridden", + ) + ) + result = self.execute_module(changed=True) + commands = [ + "no access-list test_global_access line 2 remark test global remark", + "no access-list test_global_access line 1 extended deny tcp any any eq www log errors", + "no access-list ansible_test line 2 extended deny ip host 192.0.5.1 any4", + "no access-list ansible_test line 1 remark HostA", + "no access-list test_access line 3 extended permit ip host 192.0.2.2 any", + "no access-list test_access line 2 extended deny igrp 198.51.100.0 255.255.255.0 198.51.110.0 255.255.255.0 log errors", + "no access-list test_access line 1 extended deny tcp 192.0.2.0 255.255.255.0 192.0.3.0 255.255.255.0 eq www log default", + "no access-list management_in line 3 extended permit ip any4 host 192.0.2.1", + "no access-list management_in line 2 extended permit tcp 198.51.101.0 255.255.255.0 object-group ALLSERV.12 eq 9389", + "no access-list management_in line 1 extended permit tcp host 198.51.100.5 range 49152 65535 198.51.100.0 255.255.255.0 eq 100", + "no access-list MyACL line 1 extended permit tcp object-group O-Environments any object-group O-Windows-TCP", + "no access-list test_R1_traffic line 2 extended permit ip host 2001:db8::1 any6", + "no access-list test_R1_traffic line 1 extended deny tcp 2001:db8:0:3::/64 eq www 2001:fc8:0:4::/64 eq telnet inactive", + "access-list test_global_access line 1 extended deny tcp 198.51.100.0 255.255.255.0 198.51.110.0 255.255.255.0 eq www log errors", + ] + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_asa_acls_overridden_idempotent(self): + set_module_args( + dict( + config=dict( + acls=[ + dict( + aces=[ + dict(line=1, remark="HostA"), + dict( + destination=dict(any4=True), + grant="deny", + line=2, + protocol="ip", + protocol_options=dict(ip="true"), + source=dict(host="192.0.5.1"), + ), + ], + acl_type="extended", + name="ansible_test", + ), + dict( + aces=[ + dict( + destination=dict( + any="true", + port_protocol=dict(eq="www"), + ), + grant="deny", + line=1, + log="errors", + protocol="tcp", + protocol_options=dict(tcp="true"), + source=dict(any="true"), + ), + dict(line=2, remark="test global remark"), + ], + acl_type="extended", + name="test_global_access", + ), + dict( + aces=[ + dict( + destination=dict( + address="192.0.3.0", + netmask="255.255.255.0", + port_protocol=dict(eq="www"), + ), + grant="deny", + line=1, + log="default", + protocol="tcp", + protocol_options=dict(tcp="true"), + source=dict( + address="192.0.2.0", + netmask="255.255.255.0", + ), + ), + dict( + destination=dict( + address="198.51.110.0", + netmask="255.255.255.0", + ), + grant="deny", + line=2, + log="errors", + protocol="igrp", + protocol_options=dict(igrp="true"), + source=dict( + address="198.51.100.0", + netmask="255.255.255.0", + ), + ), + dict( + destination=dict(any="true"), + grant="permit", + line=3, + protocol="ip", + protocol_options=dict(ip="true"), + source=dict(host="192.0.2.2"), + ), + ], + acl_type="extended", + name="test_access", + ), + dict( + aces=[ + dict( + destination=dict( + address="198.51.100.0", + netmask="255.255.255.0", + port_protocol=dict(eq="100"), + ), + grant="permit", + line=1, + protocol="tcp", + protocol_options=dict(tcp="true"), + source=dict( + host="198.51.100.5", + port_protocol=dict( + range=dict(end=65535, start=49152) + ), + ), + ), + dict( + destination=dict( + object_group="ALLSERV.12", + port_protocol=dict(eq="9389"), + ), + grant="permit", + line=2, + protocol="tcp", + protocol_options=dict(tcp="true"), + source=dict( + address="198.51.101.0", + netmask="255.255.255.0", + ), + ), + dict( + destination=dict(host="192.0.2.1"), + grant="permit", + line=3, + protocol="ip", + protocol_options=dict(ip="true"), + source=dict(any4=True), + ), + ], + acl_type="extended", + name="management_in", + ), + dict( + aces=[ + dict( + destination=dict( + any="true", + service_object_group="O-Windows-TCP", + ), + grant="permit", + line=1, + protocol="tcp", + protocol_options=dict(tcp="true"), + source=dict(object_group="O-Environments"), + ), + ], + acl_type="extended", + name="MyACL", + ), + dict( + aces=[ + dict( + destination=dict( + address="2001:fc8:0:4::/64", + port_protocol=dict(eq="telnet"), + ), + grant="deny", + inactive="true", + line=1, + protocol="tcp", + protocol_options=dict(tcp="true"), + source=dict( + address="2001:db8:0:3::/64", + port_protocol=dict(eq="www"), + ), + ), + dict( + destination=dict(any6=True), + grant="permit", + line=2, + protocol="ip", + protocol_options=dict(ip=True), + source=dict(host="2001:db8::1"), + ), + ], + acl_type="extended", + name="test_R1_traffic", + ), + ] + ), + state="overridden", + ) + ) + self.execute_module(changed=False, commands=[], sort=True) + + def test_asa_acls_delete_by_acl(self): + set_module_args( + dict( + config=dict( + acls=[ + dict(name="test_global_access"), + dict(name="test_R1_traffic"), + ] + ), + state="deleted", + ) + ) + result = self.execute_module(changed=True) + commands = [ + "no access-list test_R1_traffic line 2 extended permit ip host 2001:db8::1 any6", + "no access-list test_R1_traffic line 1 extended deny tcp 2001:db8:0:3::/64 eq www 2001:fc8:0:4::/64 eq telnet inactive", + "no access-list test_global_access line 2 remark test global remark", + "no access-list test_global_access line 1 extended deny tcp any any eq www log errors", + ] + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_asa_acls_deleted_all(self): + set_module_args(dict(state="deleted")) + result = self.execute_module(changed=True) + commands = [ + "no access-list test_R1_traffic line 2 extended permit ip host 2001:db8::1 any6", + "no access-list test_R1_traffic line 1 extended deny tcp 2001:db8:0:3::/64 eq www 2001:fc8:0:4::/64 eq telnet inactive", + "no access-list test_access line 3 extended permit ip host 192.0.2.2 any", + "no access-list test_access line 2 extended deny igrp 198.51.100.0 255.255.255.0 198.51.110.0 255.255.255.0 log errors", + "no access-list test_access line 1 extended deny tcp 192.0.2.0 255.255.255.0 192.0.3.0 255.255.255.0 eq www log default", + "no access-list management_in line 3 extended permit ip any4 host 192.0.2.1", + "no access-list management_in line 2 extended permit tcp 198.51.101.0 255.255.255.0 object-group ALLSERV.12 eq 9389", + "no access-list management_in line 1 extended permit tcp host 198.51.100.5 range 49152 65535 198.51.100.0 255.255.255.0 eq 100", + "no access-list MyACL line 1 extended permit tcp object-group O-Environments any object-group O-Windows-TCP", + "no access-list test_global_access line 2 remark test global remark", + "no access-list test_global_access line 1 extended deny tcp any any eq www log errors", + "no access-list ansible_test line 2 extended deny ip host 192.0.5.1 any4", + "no access-list ansible_test line 1 remark HostA", + ] + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_asa_acls_rendered(self): + set_module_args( + dict( + config=dict( + acls=[ + dict( + name="test_access", + acl_type="extended", + aces=[ + dict( + destination=dict( + address="192.0.3.0", + netmask="255.255.255.0", + ), + grant="deny", + line=1, + log="default", + protocol="tcp", + protocol_options=dict(tcp="true"), + source=dict( + address="192.0.2.0", + netmask="255.255.255.0", + ), + ) + ], + ) + ] + ), + state="rendered", + ) + ) + commands = [ + "access-list test_access line 1 extended deny tcp 192.0.2.0 255.255.255.0 192.0.3.0 255.255.255.0 log default" + ] + result = self.execute_module(changed=False) + self.assertEqual(result["rendered"], commands) diff --git a/ansible_collections/cisco/asa/tests/unit/modules/network/asa/test_asa_facts.py b/ansible_collections/cisco/asa/tests/unit/modules/network/asa/test_asa_facts.py new file mode 100644 index 00000000..fb41dbed --- /dev/null +++ b/ansible_collections/cisco/asa/tests/unit/modules/network/asa/test_asa_facts.py @@ -0,0 +1,100 @@ +# 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.asa.tests.unit.compat.mock import patch +from ansible_collections.cisco.asa.plugins.modules import asa_facts +from ansible_collections.cisco.asa.tests.unit.modules.utils import ( + set_module_args, +) +from .asa_module import TestAsaModule, load_fixture + + +class TestAsaFactsModule(TestAsaModule): + + module = asa_facts + + def setUp(self): + super(TestAsaFactsModule, self).setUp() + self.mock_run_commands = patch( + "ansible_collections.cisco.asa.plugins.module_utils.network.asa.facts.legacy.base.run_commands" + ) + self.run_commands = self.mock_run_commands.start() + + self.mock_get_resource_connection = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection" + ) + self.get_resource_connection = ( + self.mock_get_resource_connection.start() + ) + + self.mock_get_capabilities = patch( + "ansible_collections.cisco.asa.plugins.module_utils.network.asa.facts.legacy.base.get_capabilities" + ) + self.get_capabilities = self.mock_get_capabilities.start() + self.get_capabilities.return_value = { + "device_info": { + "network_os": "asa", + "network_os_hostname": "ciscoasa", + "network_os_image": "flash0:/vasa-adventerprisek9-m", + "network_os_version": "9.10(1)11", + }, + "network_api": "cliconf", + } + + def tearDown(self): + super(TestAsaFactsModule, self).tearDown() + self.mock_run_commands.stop() + self.mock_get_capabilities.stop() + + def load_fixtures(self, commands=None): + def load_from_file(*args, **kwargs): + commands = kwargs["commands"] + output = list() + + for command in commands: + filename = str(command).split(" | ", 1)[0].replace(" ", "_") + output.append(load_fixture("asa_facts_%s" % filename)) + return output + + self.run_commands.side_effect = load_from_file + + def test_asa_facts_stacked(self): + set_module_args(dict(gather_subset="default")) + result = self.execute_module() + self.assertEqual( + result["ansible_facts"]["ansible_net_serialnum"], "9AWFX1S46VQ" + ) + self.assertEqual(result["ansible_facts"]["ansible_net_system"], "asa") + + def test_asa_facts_filesystems_info(self): + set_module_args(dict(gather_subset="hardware")) + result = self.execute_module() + self.assertEqual( + result["ansible_facts"]["ansible_net_filesystems_info"]["disk0:"][ + "spacetotal_kb" + ], + 8370192.0, + ) + self.assertEqual( + result["ansible_facts"]["ansible_net_filesystems_info"]["disk0:"][ + "spacefree_kb" + ], + 8348976.0, + ) diff --git a/ansible_collections/cisco/asa/tests/unit/modules/network/asa/test_asa_ogs.py b/ansible_collections/cisco/asa/tests/unit/modules/network/asa/test_asa_ogs.py new file mode 100644 index 00000000..5923b6b5 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/unit/modules/network/asa/test_asa_ogs.py @@ -0,0 +1,707 @@ +# +# (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 + +import sys + +import pytest + +# These tests and/or the module under test are unstable on Python 3.5. +# See: https://app.shippable.com/github/ansible/ansible/runs/161331/15/tests +# This is most likely due to CPython 3.5 not maintaining dict insertion order. +pytestmark = pytest.mark.skipif( + sys.version_info[:2] == (3, 5), + reason="Tests and/or module are unstable on Python 3.5.", +) + +from ansible_collections.cisco.asa.tests.unit.compat.mock import patch +from ansible_collections.cisco.asa.plugins.modules import asa_ogs +from ansible_collections.cisco.asa.tests.unit.modules.utils import ( + set_module_args, +) +from .asa_module import TestAsaModule, load_fixture + + +class TestAsaOGsModule(TestAsaModule): + module = asa_ogs + + def setUp(self): + super(TestAsaOGsModule, 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.rm_base.resource_module_base." + "get_resource_connection" + ) + self.get_resource_connection_facts = ( + self.mock_get_resource_connection_facts.start() + ) + + self.mock_edit_config = patch( + "ansible_collections.cisco.asa.plugins.module_utils.network.asa.providers.providers.CliProvider.edit_config" + ) + self.edit_config = self.mock_edit_config.start() + + self.mock_execute_show_command = patch( + "ansible_collections.cisco.asa.plugins.module_utils.network.asa.facts.ogs.ogs." + "OGsFacts.get_og_data" + ) + self.execute_show_command = self.mock_execute_show_command.start() + + def tearDown(self): + super(TestAsaOGsModule, 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, transport="cli"): + def load_from_file(*args, **kwargs): + return load_fixture("asa_ogs_config.cfg") + + self.execute_show_command.side_effect = load_from_file + + def test_asa_ogs_merged(self): + set_module_args( + dict( + config=[ + dict( + object_groups=[ + dict( + group_object=["test_network_og"], + name="group_network_obj", + ), + dict( + name="test_network_og", + description="test network og", + network_object=dict( + host=["192.0.3.1", "192.0.3.2"], + ipv6_address=["2001:db8:0:3::/64"], + ), + ), + dict( + name="ANSIBLE_TEST", + network_object=dict(object=["NEW_TEST"]), + ), + dict( + name="bug_test_obj", + network_object=dict(host=["9.9.9.9"]), + ), + ], + object_type="network", + ), + dict( + object_groups=[ + dict( + name="test_user_obj", + user_object=dict( + user_group=[ + dict( + domain="domain", name="test_merge" + ) + ] + ), + ) + ], + object_type="user", + ), + dict( + object_groups=[ + dict( + name="test_protocol", + protocol_object=dict(protocol=["tcp", "16"]), + ) + ], + object_type="protocol", + ), + dict( + object_groups=[ + dict( + name="test_og_service_src_port_range", + services_object=[ + dict( + source_port=dict( + range=dict(end="200", start="100") + ), + protocol="tcp-udp", + ) + ], + ), + dict( + name="test_og_service_dst_port_range", + services_object=[ + dict( + destination_port=dict( + range=dict(end="400", start="300") + ), + protocol="udp", + ) + ], + ), + dict( + name="allowed.ports.tcp", + port_object=[ + dict(eq="3300"), + dict(range=dict(start="9101", end="9103")), + ], + protocol="tcp", + ), + ], + object_type="service", + ), + ], + state="merged", + ) + ) + result = self.execute_module(changed=True) + commands = [ + "object-group network group_network_obj", + "group-object test_network_og", + "object-group network test_network_og", + "description test network og", + "network-object host 192.0.3.1", + "network-object host 192.0.3.2", + "network-object 2001:db8:0:3::/64", + "object-group network ANSIBLE_TEST", + "network-object object NEW_TEST", + "object-group network bug_test_obj", + "network-object host 9.9.9.9", + "object-group user test_user_obj", + "user-group domain\\\\test_merge", + "object-group protocol test_protocol", + "protocol tcp", + "object-group service test_og_service_src_port_range", + "service-object tcp-udp source range 100 200", + "object-group service test_og_service_dst_port_range", + "service-object udp destination range 300 400", + "object-group service allowed.ports.tcp tcp", + "port-object eq 3300", + "port-object range 9101 9103", + ] + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_asa_ogs_merged_idempotent(self): + set_module_args( + dict( + config=[ + dict( + object_groups=[ + dict( + group_object=["ANSIBLE_TEST"], + name="group_network_obj", + ), + dict( + description="test_og_network", + name="test_og_network", + network_object=dict( + host=["192.0.2.1", "2001:db8::1"], + address=["192.0.2.0 255.255.255.0"], + ), + ), + dict( + name="ANSIBLE_TEST", + network_object=dict(object=["TEST1", "TEST2"]), + ), + dict(name="bug_test_obj"), + ], + object_type="network", + ), + dict( + object_groups=[ + dict( + name="3300", + port_object=[dict(eq="3300")], + protocol="tcp", + ), + dict( + name="O-UNIX-TCP", + port_object=[ + dict(eq="https"), + dict(range=dict(end=400, start=100)), + ], + protocol="tcp", + ), + dict( + name="sg-skype_ports", + services_object=[ + dict( + destination_port=dict( + range=dict(end="5061", start="sip") + ), + protocol="tcp-udp", + ) + ], + ), + dict( + name="test_og_service", + services_object=[ + dict( + destination_port=dict(gt="nfs"), + protocol="tcp", + source_port=dict(eq=1234), + ), + dict( + destination_port=dict( + range=dict(end=200, start=100) + ), + protocol="tcp", + ), + dict(protocol="ipinip"), + dict(protocol="tcp-udp"), + ], + ), + ], + object_type="service", + ), + dict( + object_groups=[ + dict( + group_object=["test_user_obj"], + name="group_user_obj", + ), + dict( + name="test_user_obj", + user_object=dict( + user=[dict(domain="LOCAL", name="test1")], + user_group=[ + dict(domain="domain", name="test1"), + dict(domain="domain", name="test2"), + ], + ), + ), + ], + object_type="user", + ), + dict( + object_groups=[ + dict( + name="test_protocol", + protocol_object=dict(protocol=["16"]), + ) + ], + object_type="protocol", + ), + ], + state="merged", + ) + ) + self.execute_module(changed=False, commands=[], sort=True) + + def test_asa_ogs_replaced(self): + set_module_args( + dict( + config=[ + dict( + object_groups=[ + dict( + name="test_og_network", + description="test_og_network_replace", + network_object=dict( + host=["192.0.3.1"], + address=["192.0.3.0 255.255.255.0"], + ), + ) + ], + object_type="network", + ) + ], + state="replaced", + ) + ) + result = self.execute_module(changed=True) + commands = [ + "object-group network test_og_network", + "description test_og_network_replace", + "no network-object 192.0.2.0 255.255.255.0", + "network-object 192.0.3.0 255.255.255.0", + "no network-object host 192.0.2.1", + "no network-object host 2001:db8::1", + "network-object host 192.0.3.1", + ] + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_asa_ogs_replaced_idempotent(self): + set_module_args( + dict( + config=[ + dict( + object_groups=[ + dict( + group_object=["ANSIBLE_TEST"], + name="group_network_obj", + ), + dict( + description="test_og_network", + name="test_og_network", + network_object=dict( + host=["192.0.2.1", "2001:db8::1"], + address=["192.0.2.0 255.255.255.0"], + ), + ), + dict( + name="ANSIBLE_TEST", + network_object=dict(object=["TEST1", "TEST2"]), + ), + dict(name="bug_test_obj"), + ], + object_type="network", + ), + dict( + object_groups=[ + dict( + name="3300", + port_object=[dict(eq="3300")], + protocol="tcp", + ), + dict( + name="O-UNIX-TCP", + port_object=[ + dict(eq="https"), + dict(range=dict(end=400, start=100)), + ], + protocol="tcp", + ), + dict( + name="sg-skype_ports", + services_object=[ + dict( + destination_port=dict( + range=dict(end="5061", start="sip") + ), + protocol="tcp-udp", + ) + ], + ), + dict( + name="test_og_service", + services_object=[ + dict( + destination_port=dict(gt="nfs"), + protocol="tcp", + source_port=dict(eq=1234), + ), + dict( + destination_port=dict( + range=dict(end=200, start=100) + ), + protocol="tcp", + ), + dict(protocol="ipinip"), + dict(protocol="tcp-udp"), + ], + ), + ], + object_type="service", + ), + dict( + object_groups=[ + dict( + group_object=["test_user_obj"], + name="group_user_obj", + ), + dict( + name="test_user_obj", + user_object=dict( + user=[dict(domain="LOCAL", name="test1")], + user_group=[ + dict(domain="domain", name="test1"), + dict(domain="domain", name="test2"), + ], + ), + ), + ], + object_type="user", + ), + dict( + object_groups=[ + dict( + name="test_protocol", + protocol_object=dict(protocol=["16"]), + ) + ], + object_type="protocol", + ), + ], + state="replaced", + ) + ) + self.execute_module(changed=False, commands=[], sort=True) + + def test_asa_ogs_overridden(self): + set_module_args( + dict( + config=[ + dict( + object_groups=[ + dict( + name="test_og_network", + description="test_og_network_override", + network_object=dict( + host=["192.0.3.1"], + address=["192.0.3.0 255.255.255.0"], + ), + ) + ], + object_type="network", + ) + ], + state="overridden", + ) + ) + result = self.execute_module(changed=True) + commands = [ + "no object-group service test_og_service", + "no object-group service 3300", + "no object-group service sg-skype_ports", + "no object-group service O-UNIX-TCP", + "no object-group network group_network_obj", + "no object-group protocol test_protocol", + "object-group network test_og_network", + "description test_og_network_override", + "no network-object 192.0.2.0 255.255.255.0", + "network-object 192.0.3.0 255.255.255.0", + "no network-object host 192.0.2.1", + "no network-object host 2001:db8::1", + "network-object host 192.0.3.1", + "no object-group network ANSIBLE_TEST", + "no object-group network bug_test_obj", + "no object-group user group_user_obj", + "no object-group user test_user_obj", + ] + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_asa_ogs_overridden_idempotent(self): + set_module_args( + dict( + config=[ + dict( + object_groups=[ + dict( + group_object=["ANSIBLE_TEST"], + name="group_network_obj", + ), + dict( + description="test_og_network", + name="test_og_network", + network_object=dict( + host=["192.0.2.1", "2001:db8::1"], + address=["192.0.2.0 255.255.255.0"], + ), + ), + dict( + name="ANSIBLE_TEST", + network_object=dict(object=["TEST1", "TEST2"]), + ), + dict(name="bug_test_obj"), + ], + object_type="network", + ), + dict( + object_groups=[ + dict( + name="3300", + port_object=[dict(eq="3300")], + protocol="tcp", + ), + dict( + name="O-UNIX-TCP", + port_object=[ + dict(eq="https"), + dict(range=dict(end=400, start=100)), + ], + protocol="tcp", + ), + dict( + name="sg-skype_ports", + services_object=[ + dict( + destination_port=dict( + range=dict(end="5061", start="sip") + ), + protocol="tcp-udp", + ) + ], + ), + dict( + name="test_og_service", + services_object=[ + dict( + destination_port=dict(gt="nfs"), + protocol="tcp", + source_port=dict(eq=1234), + ), + dict( + destination_port=dict( + range=dict(end=200, start=100) + ), + protocol="tcp", + ), + dict(protocol="ipinip"), + dict(protocol="tcp-udp"), + ], + ), + ], + object_type="service", + ), + dict( + object_groups=[ + dict( + group_object=["test_user_obj"], + name="group_user_obj", + ), + dict( + name="test_user_obj", + user_object=dict( + user=[dict(domain="LOCAL", name="test1")], + user_group=[ + dict(domain="domain", name="test1"), + dict(domain="domain", name="test2"), + ], + ), + ), + ], + object_type="user", + ), + dict( + object_groups=[ + dict( + name="test_protocol", + protocol_object=dict(protocol=["16"]), + ) + ], + object_type="protocol", + ), + ], + state="overridden", + ) + ) + self.execute_module(changed=False, commands=[], sort=True) + + def test_asa_ogs_delete_by_name(self): + set_module_args( + dict( + config=[ + dict( + object_groups=[dict(name="test_og_network")], + object_type="network", + ) + ], + state="deleted", + ) + ) + result = self.execute_module(changed=True) + commands = ["no object-group network test_og_network"] + self.assertEqual(result["commands"], commands) + + def test_asa_ogs_deleted_all(self): + set_module_args(dict(state="deleted")) + result = self.execute_module(changed=True) + commands = [ + "no object-group network group_network_obj", + "no object-group network test_og_network", + "no object-group network ANSIBLE_TEST", + "no object-group network bug_test_obj", + "no object-group protocol test_protocol", + "no object-group service 3300", + "no object-group service sg-skype_ports", + "no object-group service test_og_service", + "no object-group service O-UNIX-TCP", + "no object-group user group_user_obj", + "no object-group user test_user_obj", + ] + self.assertEqual(sorted(result["commands"]), sorted(commands)) + + def test_asa_ogs_rendered(self): + set_module_args( + dict( + config=[ + dict( + object_groups=[ + dict( + description="test_og_network", + name="test_og_network", + network_object=dict( + host=["192.0.2.1", "2001:db8::1"], + address=["192.0.2.0 255.255.255.0"], + ), + ) + ], + object_type="network", + ), + dict( + object_groups=[ + dict( + name="test_og_service", + service_object=dict( + protocol=["ipinip", "tcp-udp"] + ), + ), + dict( + name="test_og_service_src_port_range", + services_object=[ + dict( + source_port=dict( + range=dict(end="200", start="100") + ), + protocol="tcp-udp", + ) + ], + ), + dict( + name="test_og_service_dst_port_range", + services_object=[ + dict( + destination_port=dict( + range=dict(end="400", start="300") + ), + protocol="udp", + ) + ], + ), + ], + object_type="service", + ), + ], + state="rendered", + ) + ) + commands = [ + "object-group network test_og_network", + "description test_og_network", + "network-object 192.0.2.0 255.255.255.0", + "network-object host 192.0.2.1", + "network-object host 2001:db8::1", + "object-group service test_og_service", + "service-object ipinip", + "service-object tcp-udp", + "object-group service test_og_service_src_port_range", + "service-object tcp-udp source range 100 200", + "object-group service test_og_service_dst_port_range", + "service-object udp destination range 300 400", + ] + result = self.execute_module(changed=False) + self.assertEqual(sorted(result["rendered"]), sorted(commands)) diff --git a/ansible_collections/cisco/asa/tests/unit/modules/utils.py b/ansible_collections/cisco/asa/tests/unit/modules/utils.py new file mode 100644 index 00000000..9258b663 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/unit/modules/utils.py @@ -0,0 +1,51 @@ +from __future__ import absolute_import, division, print_function + +__metaclass__ = type +import json + +from ansible_collections.cisco.asa.tests.unit.compat import unittest +from ansible_collections.cisco.asa.tests.unit.compat.mock import patch +from ansible.module_utils import basic +from ansible.module_utils._text import to_bytes + + +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/asa/tests/unit/requirements.txt b/ansible_collections/cisco/asa/tests/unit/requirements.txt new file mode 100644 index 00000000..a9772bea --- /dev/null +++ b/ansible_collections/cisco/asa/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' |