diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-14 20:03:01 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-14 20:03:01 +0000 |
commit | a453ac31f3428614cceb99027f8efbdb9258a40b (patch) | |
tree | f61f87408f32a8511cbd91799f9cececb53e0374 /collections-debian-merged/ansible_collections/cisco/asa/tests/unit | |
parent | Initial commit. (diff) | |
download | ansible-a453ac31f3428614cceb99027f8efbdb9258a40b.tar.xz ansible-a453ac31f3428614cceb99027f8efbdb9258a40b.zip |
Adding upstream version 2.10.7+merged+base+2.10.8+dfsg.upstream/2.10.7+merged+base+2.10.8+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'collections-debian-merged/ansible_collections/cisco/asa/tests/unit')
29 files changed, 2100 insertions, 0 deletions
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/__init__.py b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/__init__.py diff --git a/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/compat/__init__.py b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/compat/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/compat/__init__.py diff --git a/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/compat/builtins.py b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/compat/builtins.py new file mode 100644 index 00000000..bfc8adfb --- /dev/null +++ b/collections-debian-merged/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/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/compat/mock.py b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/compat/mock.py new file mode 100644 index 00000000..2ea98a17 --- /dev/null +++ b/collections-debian-merged/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/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/compat/unittest.py b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/compat/unittest.py new file mode 100644 index 00000000..df3379b8 --- /dev/null +++ b/collections-debian-merged/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/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/mock/__init__.py b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/mock/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/mock/__init__.py diff --git a/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/mock/loader.py b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/mock/loader.py new file mode 100644 index 00000000..c21188ee --- /dev/null +++ b/collections-debian-merged/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, path): + path = to_text(path) + if path in self._file_mapping: + return (to_bytes(self._file_mapping[path]), False) + else: + raise AnsibleParserError("file not found: %s" % path) + + def path_exists(self, path): + path = to_text(path) + return path in self._file_mapping or path in self._known_directories + + def is_file(self, path): + path = to_text(path) + return path in self._file_mapping + + def is_directory(self, path): + path = to_text(path) + return path in self._known_directories + + def list_directory(self, path): + ret = [] + path = to_text(path) + for x in list(self._file_mapping.keys()) + self._known_directories: + if x.startswith(path): + if os.path.dirname(x) == path: + ret.append(os.path.basename(x)) + return ret + + def is_executable(self, path): + # FIXME: figure out a way to make paths return true for this + return False + + def _add_known_directory(self, directory): + if directory not in self._known_directories: + self._known_directories.append(directory) + + def _build_known_directories(self): + self._known_directories = [] + for path in self._file_mapping: + dirname = os.path.dirname(path) + while dirname not in ("/", ""): + self._add_known_directory(dirname) + dirname = os.path.dirname(dirname) + + def push(self, path, content): + rebuild_dirs = False + if path not in self._file_mapping: + rebuild_dirs = True + + self._file_mapping[path] = content + + if rebuild_dirs: + self._build_known_directories() + + def pop(self, path): + if path in self._file_mapping: + del self._file_mapping[path] + self._build_known_directories() + + def clear(self): + self._file_mapping = dict() + self._known_directories = [] + + def get_basedir(self): + return os.getcwd() + + def set_vault_secrets(self, vault_secrets): + self._vault_secrets = vault_secrets diff --git a/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/mock/path.py b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/mock/path.py new file mode 100644 index 00000000..3bd0cdee --- /dev/null +++ b/collections-debian-merged/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/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/mock/procenv.py b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/mock/procenv.py new file mode 100644 index 00000000..e02cae04 --- /dev/null +++ b/collections-debian-merged/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/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/mock/vault_helper.py b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/mock/vault_helper.py new file mode 100644 index 00000000..b34ae134 --- /dev/null +++ b/collections-debian-merged/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/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/mock/yaml_helper.py b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/mock/yaml_helper.py new file mode 100644 index 00000000..5df30aae --- /dev/null +++ b/collections-debian-merged/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/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/__init__.py b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/__init__.py diff --git a/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/conftest.py b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/conftest.py new file mode 100644 index 00000000..e19a1e04 --- /dev/null +++ b/collections-debian-merged/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/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/__init__.py b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/__init__.py diff --git a/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/asa/__init__.py b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/asa/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/asa/__init__.py diff --git a/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/asa/asa_module.py b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/asa/asa_module.py new file mode 100644 index 00000000..b86ebbb1 --- /dev/null +++ b/collections-debian-merged/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/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/__init__.py b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/__init__.py diff --git a/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/asa_acls_config.cfg b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/asa_acls_config.cfg new file mode 100644 index 00000000..a40a861f --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/asa_acls_config.cfg @@ -0,0 +1,11 @@ +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
\ No newline at end of file diff --git a/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/asa_facts_dir b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/asa_facts_dir new file mode 100644 index 00000000..cd8caa3f --- /dev/null +++ b/collections-debian-merged/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/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/asa_facts_show_memory b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/asa_facts_show_memory new file mode 100644 index 00000000..13bea8cb --- /dev/null +++ b/collections-debian-merged/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/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/asa_facts_show_version b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/asa_facts_show_version new file mode 100644 index 00000000..d652d7be --- /dev/null +++ b/collections-debian-merged/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/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/asa_og_config.cfg b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/asa_og_config.cfg new file mode 100644 index 00000000..27f22120 --- /dev/null +++ b/collections-debian-merged/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/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/asa_ogs_config.cfg b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/asa_ogs_config.cfg new file mode 100644 index 00000000..6f5025fc --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/asa/fixtures/asa_ogs_config.cfg @@ -0,0 +1,7 @@ +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 service test_og_service + service-object ipinip + service-object tcp-udp
\ No newline at end of file diff --git a/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/asa/test_asa_acls.py b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/asa/test_asa_acls.py new file mode 100644 index 00000000..ef5ea440 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/asa/test_asa_acls.py @@ -0,0 +1,568 @@ +# +# (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.resource_module." + "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", + ) + ] + ), + 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" + ] + self.assertEqual(result["commands"], commands) + + def test_asa_acls_merged_idempotent(self): + set_module_args( + dict( + config=dict( + acls=[ + 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="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"), + ), + ) + ], + 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", + ) + ], + ) + ] + ), + state="replaced", + ) + ) + result = self.execute_module(changed=True) + commands = [ + "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", + ] + self.assertEqual(result["commands"], commands) + + def test_asa_acls_replaced_idempotent(self): + set_module_args( + dict( + config=dict( + acls=[ + 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="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"), + ), + ) + ], + 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 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", + "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(result["commands"], commands) + + def test_asa_acls_overridden_idempotent(self): + set_module_args( + dict( + config=dict( + acls=[ + 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="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"), + ), + ) + ], + 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 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(result["commands"], 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 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 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(result["commands"], 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/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/asa/test_asa_facts.py b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/asa/test_asa_facts.py new file mode 100644 index 00000000..46c3f91c --- /dev/null +++ b/collections-debian-merged/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(" | ")[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/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/asa/test_asa_og.py b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/asa/test_asa_og.py new file mode 100644 index 00000000..938fc291 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/asa/test_asa_og.py @@ -0,0 +1,126 @@ +# -*- 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 + +from ansible_collections.cisco.asa.tests.unit.compat.mock import patch +from ansible_collections.cisco.asa.plugins.modules import asa_og +from ansible_collections.cisco.asa.tests.unit.modules.utils import ( + set_module_args, +) +from .asa_module import TestAsaModule, load_fixture + + +class TestAsaOgModule(TestAsaModule): + + module = asa_og + + def setUp(self): + super(TestAsaOgModule, self).setUp() + + self.mock_get_config = patch( + "ansible_collections.cisco.asa.plugins.modules.asa_og.get_config" + ) + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + "ansible_collections.cisco.asa.plugins.modules.asa_og.load_config" + ) + self.load_config = self.mock_load_config.start() + + self.mock_get_connection = patch( + "ansible_collections.cisco.asa.plugins.module_utils.network.asa.asa.get_connection" + ) + self.get_connection = self.mock_get_connection.start() + + def tearDown(self): + super(TestAsaOgModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None): + self.get_config.return_value = load_fixture( + "asa_og_config.cfg" + ).strip() + self.load_config.return_value = dict(diff=None, session="session") + + def test_asa_og_idempotent(self): + set_module_args( + dict( + name="test_nets", + group_type="network-object", + host_ip=["8.8.8.8"], + ip_mask=["192.168.0.0 255.255.0.0"], + group_object=["awx_lon"], + description="ansible_test object-group description", + state="present", + ) + ) + commands = [] + self.execute_module(changed=False, commands=commands) + + def test_asa_og_add(self): + set_module_args( + dict( + name="test_nets", + group_type="network-object", + host_ip=["8.8.8.8", "8.8.4.4"], + ip_mask=["192.168.0.0 255.255.0.0", "10.0.0.0 255.255.255.0"], + group_object=["awx_lon", "awx_ams"], + description="ansible_test object-group description", + state="present", + ) + ) + commands = [ + "object-group network test_nets", + "network-object host 8.8.4.4", + "network-object 10.0.0.0 255.255.255.0", + "group-object awx_ams", + ] + self.execute_module(changed=True, commands=commands) + + def test_asa_og_replace(self): + set_module_args( + dict( + name="test_nets", + group_type="network-object", + host_ip=["8.8.4.4"], + ip_mask=["10.0.0.0 255.255.255.0"], + group_object=["awx_ams"], + description="ansible_test custom description", + state="replace", + ) + ) + commands = [ + "object-group network test_nets", + "description ansible_test custom description", + "no network-object host 8.8.8.8", + "network-object host 8.8.4.4", + "no network-object 192.168.0.0 255.255.0.0", + "network-object 10.0.0.0 255.255.255.0", + "no group-object awx_lon", + "group-object awx_ams", + ] + self.execute_module(changed=True, commands=commands) + + def test_asa_og_remove(self): + set_module_args( + dict( + name="test_nets", + group_type="network-object", + host_ip=["8.8.8.8"], + group_object=["awx_lon"], + state="absent", + ) + ) + commands = [ + "object-group network test_nets", + "no network-object host 8.8.8.8", + "no group-object awx_lon", + ] + self.execute_module(changed=True, commands=commands) diff --git a/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/asa/test_asa_ogs.py b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/asa/test_asa_ogs.py new file mode 100644 index 00000000..ca5f8ec4 --- /dev/null +++ b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/network/asa/test_asa_ogs.py @@ -0,0 +1,353 @@ +# +# (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.resource_module." + "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( + 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"], + ), + ) + ], + object_type="network", + ) + ], + state="merged", + ) + ) + result = self.execute_module(changed=True) + commands = [ + "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", + ] + self.assertEqual(result["commands"], commands) + + def test_asa_ogs_merged_idempotent(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"], + 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"] + ), + ) + ], + object_type="service", + ), + ], + 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", + "network-object host 192.0.3.1", + ] + self.assertEqual(result["commands"], commands) + + def test_asa_ogs_replaced_idempotent(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"], + 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"] + ), + ) + ], + object_type="service", + ), + ], + 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", + "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", + "network-object host 192.0.3.1", + ] + self.assertEqual(result["commands"], commands) + + def test_asa_ogs_overridden_idempotent(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"], + 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"] + ), + ) + ], + object_type="service", + ), + ], + 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 test_og_network", + "no object-group service test_og_service", + ] + self.assertEqual(result["commands"], 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"], + 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"] + ), + ) + ], + 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", + "object-group service test_og_service", + "service-object ipinip", + "service-object tcp-udp", + ] + result = self.execute_module(changed=False) + self.assertEqual(result["rendered"], commands) diff --git a/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/utils.py b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/modules/utils.py new file mode 100644 index 00000000..9258b663 --- /dev/null +++ b/collections-debian-merged/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/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/requirements.txt b/collections-debian-merged/ansible_collections/cisco/asa/tests/unit/requirements.txt new file mode 100644 index 00000000..a9772bea --- /dev/null +++ b/collections-debian-merged/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' |