diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 12:04:41 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 12:04:41 +0000 |
commit | 975f66f2eebe9dadba04f275774d4ab83f74cf25 (patch) | |
tree | 89bd26a93aaae6a25749145b7e4bca4a1e75b2be /ansible_collections/cisco/asa/tests/unit/modules | |
parent | Initial commit. (diff) | |
download | ansible-975f66f2eebe9dadba04f275774d4ab83f74cf25.tar.xz ansible-975f66f2eebe9dadba04f275774d4ab83f74cf25.zip |
Adding upstream version 7.7.0+dfsg.upstream/7.7.0+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ansible_collections/cisco/asa/tests/unit/modules')
16 files changed, 1988 insertions, 0 deletions
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 000000000..e69de29bb --- /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 000000000..349e71ada --- /dev/null +++ b/ansible_collections/cisco/asa/tests/unit/modules/conftest.py @@ -0,0 +1,34 @@ +# Copyright (c) 2017 Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type + +import json + +import pytest + +from ansible.module_utils._text import to_bytes +from ansible.module_utils.common._collections_compat import MutableMapping +from ansible.module_utils.six import string_types + + +@pytest.fixture +def patch_ansible_module(request, mocker): + if isinstance(request.param, string_types): + args = request.param + elif isinstance(request.param, MutableMapping): + if "ANSIBLE_MODULE_ARGS" not in request.param: + request.param = {"ANSIBLE_MODULE_ARGS": request.param} + if "_ansible_remote_tmp" not in request.param["ANSIBLE_MODULE_ARGS"]: + request.param["ANSIBLE_MODULE_ARGS"]["_ansible_remote_tmp"] = "/tmp" + if "_ansible_keep_remote_files" not in request.param["ANSIBLE_MODULE_ARGS"]: + request.param["ANSIBLE_MODULE_ARGS"]["_ansible_keep_remote_files"] = False + args = json.dumps(request.param) + else: + raise Exception( + "Malformed data to the patch_ansible_module pytest fixture", + ) + + mocker.patch("ansible.module_utils.basic._ANSIBLE_ARGS", to_bytes(args)) diff --git a/ansible_collections/cisco/asa/tests/unit/modules/network/__init__.py b/ansible_collections/cisco/asa/tests/unit/modules/network/__init__.py new file mode 100644 index 000000000..e69de29bb --- /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 000000000..e69de29bb --- /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 000000000..56029cb7c --- /dev/null +++ b/ansible_collections/cisco/asa/tests/unit/modules/network/asa/asa_module.py @@ -0,0 +1,95 @@ +# -*- 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 json +import os + +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 000000000..e69de29bb --- /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 000000000..7a0fb66c7 --- /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 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 000000000..9f2422a80 --- /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) 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 000000000..41b29fb3a --- /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. 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 000000000..98b25306b --- /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 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 000000000..27f221203 --- /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 000000000..adb770874 --- /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 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 000000000..301952255 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/unit/modules/network/asa/test_asa_acls.py @@ -0,0 +1,870 @@ +# +# (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.plugins.modules import asa_acls +from ansible_collections.cisco.asa.tests.unit.compat.mock import patch +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 000000000..75b3d0649 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/unit/modules/network/asa/test_asa_facts.py @@ -0,0 +1,94 @@ +# 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.plugins.modules import asa_facts +from ansible_collections.cisco.asa.tests.unit.compat.mock import patch +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 000000000..15c03fc10 --- /dev/null +++ b/ansible_collections/cisco/asa/tests/unit/modules/network/asa/test_asa_ogs.py @@ -0,0 +1,705 @@ +# +# (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.plugins.modules import asa_ogs +from ansible_collections.cisco.asa.tests.unit.compat.mock import patch +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 000000000..fca92466f --- /dev/null +++ b/ansible_collections/cisco/asa/tests/unit/modules/utils.py @@ -0,0 +1,55 @@ +from __future__ import absolute_import, division, print_function + + +__metaclass__ = type +import json + +from ansible.module_utils import basic +from ansible.module_utils._text import to_bytes + +from ansible_collections.cisco.asa.tests.unit.compat import unittest +from ansible_collections.cisco.asa.tests.unit.compat.mock import patch + + +def set_module_args(args): + if "_ansible_remote_tmp" not in args: + args["_ansible_remote_tmp"] = "/tmp" + if "_ansible_keep_remote_files" not in args: + args["_ansible_keep_remote_files"] = False + + args = json.dumps({"ANSIBLE_MODULE_ARGS": args}) + basic._ANSIBLE_ARGS = to_bytes(args) + + +class AnsibleExitJson(Exception): + pass + + +class AnsibleFailJson(Exception): + pass + + +def exit_json(*args, **kwargs): + if "changed" not in kwargs: + kwargs["changed"] = False + raise AnsibleExitJson(kwargs) + + +def fail_json(*args, **kwargs): + kwargs["failed"] = True + raise AnsibleFailJson(kwargs) + + +class ModuleTestCase(unittest.TestCase): + def setUp(self): + self.mock_module = patch.multiple( + basic.AnsibleModule, + exit_json=exit_json, + fail_json=fail_json, + ) + self.mock_module.start() + self.mock_sleep = patch("time.sleep") + self.mock_sleep.start() + set_module_args({}) + self.addCleanup(self.mock_module.stop) + self.addCleanup(self.mock_sleep.stop) |