summaryrefslogtreecommitdiffstats
path: root/collections-debian-merged/ansible_collections/cisco/asa/plugins
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-14 20:03:01 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-14 20:03:01 +0000
commita453ac31f3428614cceb99027f8efbdb9258a40b (patch)
treef61f87408f32a8511cbd91799f9cececb53e0374 /collections-debian-merged/ansible_collections/cisco/asa/plugins
parentInitial commit. (diff)
downloadansible-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/plugins')
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/action/__init__.py0
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/action/asa.py96
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/cliconf/__init__.py0
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/cliconf/asa.py145
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/doc_fragments/__init__.py0
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/doc_fragments/asa.py102
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/__init__.py0
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/__init__.py0
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/argspec/__init__.py0
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/argspec/acls/__init__.py0
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/argspec/acls/acls.py290
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/argspec/facts/__init__.py0
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/argspec/facts/facts.py27
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/argspec/ogs/__init__.py0
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/argspec/ogs/ogs.py229
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/asa.py194
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/config/__init__.py0
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/config/acls/__init__.py0
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/config/acls/acls.py199
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/config/ogs/__init__.py0
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/config/ogs/ogs.py459
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/facts/__init__.py0
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/facts/acls/__init__.py0
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/facts/acls/acls.py106
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/facts/facts.py67
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/facts/legacy/__init__.py0
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/facts/legacy/base.py186
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/facts/ogs/__init__.py0
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/facts/ogs/ogs.py108
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/providers/__init__.py0
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/providers/module.py73
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/providers/providers.py129
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/rm_templates/acls.py231
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/rm_templates/ogs.py400
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/utils/__init__.py0
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/utils/utils.py330
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/modules/__init__.py0
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/modules/asa_acl.py235
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/modules/asa_acls.py1258
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/modules/asa_command.py197
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/modules/asa_config.py368
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/modules/asa_facts.py209
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/modules/asa_og.py1034
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/modules/asa_ogs.py892
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/terminal/__init__.py0
-rw-r--r--collections-debian-merged/ansible_collections/cisco/asa/plugins/terminal/asa.py76
46 files changed, 7640 insertions, 0 deletions
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/action/__init__.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/action/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/action/__init__.py
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/action/asa.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/action/asa.py
new file mode 100644
index 00000000..0fa543c4
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/action/asa.py
@@ -0,0 +1,96 @@
+#
+# (c) 2016 Red Hat Inc.
+#
+# This file is part of Ansible
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
+#
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+import sys
+import copy
+
+from ansible import constants as C
+from ansible_collections.ansible.netcommon.plugins.action.network import (
+ ActionModule as ActionNetworkModule,
+)
+from ansible_collections.cisco.asa.plugins.module_utils.network.asa.asa import (
+ asa_provider_spec,
+)
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import (
+ load_provider,
+)
+from ansible.utils.display import Display
+
+display = Display()
+
+
+class ActionModule(ActionNetworkModule):
+ def run(self, tmp=None, task_vars=None):
+ del tmp # tmp no longer has any effect
+
+ module_name = self._task.action.split(".")[-1]
+ self._config_module = (
+ True if module_name in ["asa_config", "config"] else False
+ )
+
+ if self._play_context.connection == "local":
+ provider = load_provider(asa_provider_spec, self._task.args)
+ pc = copy.deepcopy(self._play_context)
+ pc.connection = "network_cli"
+ pc.network_os = "asa"
+ pc.remote_addr = provider["host"] or self._play_context.remote_addr
+ pc.port = int(provider["port"] or self._play_context.port or 22)
+ pc.remote_user = (
+ provider["username"] or self._play_context.connection_user
+ )
+ pc.password = provider["password"] or self._play_context.password
+ pc.private_key_file = (
+ provider["ssh_keyfile"] or self._play_context.private_key_file
+ )
+ command_timeout = int(
+ provider["timeout"] or C.PERSISTENT_COMMAND_TIMEOUT
+ )
+ pc.become = provider["authorize"] or False
+ pc.become_pass = provider["auth_pass"]
+ pc.become_method = "enable"
+
+ display.vvv(
+ "using connection plugin %s (was local)" % pc.connection,
+ pc.remote_addr,
+ )
+ connection = self._shared_loader_obj.connection_loader.get(
+ "persistent", pc, sys.stdin, task_uuid=self._task._uuid
+ )
+ connection.set_options(
+ direct={"persistent_command_timeout": command_timeout}
+ )
+
+ socket_path = connection.run()
+
+ display.vvvv("socket_path: %s" % socket_path, pc.remote_addr)
+ if not socket_path:
+ return {
+ "failed": True,
+ "msg": "unable to open shell. Please see: "
+ + "https://docs.ansible.com/ansible/network_debug_troubleshooting.html#unable-to-open-shell",
+ }
+
+ task_vars["ansible_socket"] = socket_path
+
+ result = super(ActionModule, self).run(task_vars=task_vars)
+
+ return result
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/cliconf/__init__.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/cliconf/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/cliconf/__init__.py
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/cliconf/asa.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/cliconf/asa.py
new file mode 100644
index 00000000..d5126356
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/cliconf/asa.py
@@ -0,0 +1,145 @@
+#
+# (c) 2017 Red Hat Inc.
+#
+# This file is part of Ansible
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
+#
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = """
+---
+author: Ansible Security Team
+cliconf: asa
+short_description: Use asa cliconf to run command on Cisco ASA platform
+description:
+- This asa plugin provides low level abstraction apis for sending and receiving CLI
+ commands from Cisco ASA network devices.
+version_added: 1.0.0
+"""
+
+import re
+import json
+
+from itertools import chain
+from ansible.errors import AnsibleConnectionFailure
+from ansible.module_utils._text import to_text
+from ansible.module_utils.common._collections_compat import Mapping
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import (
+ to_list,
+)
+from ansible.plugins.cliconf import CliconfBase, enable_mode
+
+
+class Cliconf(CliconfBase):
+ def get_device_info(self):
+ device_info = {}
+
+ device_info["network_os"] = "asa"
+ reply = self.get("show version")
+ data = to_text(reply, errors="surrogate_or_strict").strip()
+
+ match = re.search(r"Version (\S+)", data)
+ if match:
+ device_info["network_os_version"] = match.group(1)
+
+ match = re.search(r"Firepower .+ Version (\S+)", data)
+ if match:
+ device_info["network_os_firepower_version"] = match.group(1)
+
+ match = re.search(r"Device .+ Version (\S+)", data)
+ if match:
+ device_info["network_os_device_mgr_version"] = match.group(1)
+
+ match = re.search(r"^Model Id:\s+(.+) \(revision", data, re.M)
+ if match:
+ device_info["network_os_model"] = match.group(1)
+
+ match = re.search(r"^(.+) up", data, re.M)
+ if match:
+ device_info["network_os_hostname"] = match.group(1)
+
+ match = re.search(r'image file is "(.+)"', data)
+ if match:
+ device_info["network_os_image"] = match.group(1)
+
+ return device_info
+
+ @enable_mode
+ def get_config(self, source="running", format="text", flags=None):
+ if source not in ("running", "startup"):
+ return self.invalid_params(
+ "fetching configuration from %s is not supported" % source
+ )
+ if source == "running":
+ cmd = "show running-config all"
+ else:
+ cmd = "show startup-config"
+ return self.send_command(cmd)
+
+ @enable_mode
+ def edit_config(self, command):
+ for cmd in chain(["configure terminal"], to_list(command), ["end"]):
+ self.send_command(cmd)
+
+ def get(
+ self,
+ command,
+ prompt=None,
+ answer=None,
+ sendonly=False,
+ newline=True,
+ check_all=False,
+ ):
+ return self.send_command(
+ command=command,
+ prompt=prompt,
+ answer=answer,
+ sendonly=sendonly,
+ newline=newline,
+ check_all=check_all,
+ )
+
+ def get_capabilities(self):
+ result = super(Cliconf, self).get_capabilities()
+ return json.dumps(result)
+
+ def run_commands(self, commands=None, check_rc=True):
+ if commands is None:
+ raise ValueError("'commands' value is required")
+
+ responses = list()
+ for cmd in to_list(commands):
+ if not isinstance(cmd, Mapping):
+ cmd = {"command": cmd}
+
+ output = cmd.pop("output", None)
+ if output:
+ raise ValueError(
+ "'output' value %s is not supported for run_commands"
+ % output
+ )
+
+ try:
+ out = self.send_command(**cmd)
+ except AnsibleConnectionFailure as e:
+ if check_rc:
+ raise
+ out = getattr(e, "err", to_text(e))
+
+ responses.append(out)
+
+ return responses
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/doc_fragments/__init__.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/doc_fragments/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/doc_fragments/__init__.py
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/doc_fragments/asa.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/doc_fragments/asa.py
new file mode 100644
index 00000000..3ce7f396
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/doc_fragments/asa.py
@@ -0,0 +1,102 @@
+# -*- coding: utf-8 -*-
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+# Copyright: (c) 2016, Peter Sprygada <psprygada@ansible.com>
+# Copyright: (c) 2016, Patrick Ogenstad <@ogenstad>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+
+class ModuleDocFragment(object):
+
+ # Standard files documentation fragment
+ DOCUMENTATION = r"""options:
+ authorize:
+ description:
+ - B(Deprecated)
+ - 'Starting with Ansible 2.5 we recommend using C(connection: network_cli) and
+ C(become: yes).'
+ - For more information please see the L(Network Guide, ../network/getting_started/network_differences.html#multiple-communication-protocols).
+ - HORIZONTALLINE
+ - Instructs the module to enter privileged mode on the remote device before sending
+ any commands. If not specified, the device will attempt to execute all commands
+ in non-privileged mode. If the value is not specified in the task, the value
+ of environment variable C(ANSIBLE_NET_AUTHORIZE) will be used instead.
+ type: bool
+ default: false
+ context:
+ description:
+ - Specifies which context to target if you are running in the ASA in multiple
+ context mode. Defaults to the current context you login to.
+ type: str
+ passwords:
+ description:
+ - Specifies which context to target if you are running in the ASA in multiple
+ context mode. Defaults to the current context you login to.
+ type: bool
+ provider:
+ description:
+ - B(Deprecated)
+ - 'Starting with Ansible 2.5 we recommend using C(connection: network_cli).'
+ - For more information please see the L(Network Guide, ../network/getting_started/network_differences.html#multiple-communication-protocols).
+ - HORIZONTALLINE
+ - A dict object containing connection details.
+ type: dict
+ suboptions:
+ host:
+ description:
+ - Specifies the DNS host name or address for connecting to the remote device
+ over the specified transport. The value of host is used as the destination
+ address for the transport.
+ type: str
+ port:
+ description:
+ - Specifies the port to use when building the connection to the remote device.
+ type: int
+ username:
+ description:
+ - Configures the username to use to authenticate the connection to the remote
+ device. This value is used to authenticate the SSH session. If the value
+ is not specified in the task, the value of environment variable C(ANSIBLE_NET_USERNAME)
+ will be used instead.
+ type: str
+ password:
+ description:
+ - Specifies the password to use to authenticate the connection to the remote
+ device. This value is used to authenticate the SSH session. If the value
+ is not specified in the task, the value of environment variable C(ANSIBLE_NET_PASSWORD)
+ will be used instead.
+ type: str
+ ssh_keyfile:
+ description:
+ - Specifies the SSH key to use to authenticate the connection to the remote
+ device. This value is the path to the key used to authenticate the SSH
+ session. If the value is not specified in the task, the value of environment
+ variable C(ANSIBLE_NET_SSH_KEYFILE) will be used instead.
+ type: path
+ authorize:
+ description:
+ - Instructs the module to enter privileged mode on the remote device before
+ sending any commands. If not specified, the device will attempt to execute
+ all commands in non-privileged mode. If the value is not specified in the
+ task, the value of environment variable C(ANSIBLE_NET_AUTHORIZE) will be
+ used instead.
+ type: bool
+ default: false
+ auth_pass:
+ description:
+ - Specifies the password to use if required to enter privileged mode on the
+ remote device. If I(authorize) is false, then this argument does nothing.
+ If the value is not specified in the task, the value of environment variable
+ C(ANSIBLE_NET_AUTH_PASS) will be used instead.
+ type: str
+ timeout:
+ description:
+ - Specifies idle timeout in seconds for the connection, in seconds. Useful
+ if the console freezes before continuing. For example when saving configurations.
+ type: int
+notes:
+- For more information on using Ansible to manage network devices see the :ref:`Ansible
+ Network Guide <network_guide>`
+"""
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/__init__.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/__init__.py
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/__init__.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/__init__.py
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/argspec/__init__.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/argspec/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/argspec/__init__.py
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/argspec/acls/__init__.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/argspec/acls/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/argspec/acls/__init__.py
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/argspec/acls/acls.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/argspec/acls/acls.py
new file mode 100644
index 00000000..3a8b2e52
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/argspec/acls/acls.py
@@ -0,0 +1,290 @@
+# -*- coding: utf-8 -*-
+# Copyright 2019 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+#############################################
+# WARNING #
+#############################################
+#
+# This file is auto generated by the resource
+# module builder playbook.
+#
+# Do not edit this file manually.
+#
+# Changes to this file will be over written
+# by the resource module builder.
+#
+# Changes should be made in the model used to
+# generate this file or in the resource module
+# builder template.
+#
+#############################################
+
+"""
+The arg spec for the asa_acls module
+"""
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+
+class AclsArgs(object):
+ """The arg spec for the asa_acls module
+ """
+
+ def __init__(self, **kwargs):
+ pass
+
+ argument_spec = {
+ "config": {
+ "type": "dict",
+ "options": {
+ "acls": {
+ "elements": "dict",
+ "type": "list",
+ "options": {
+ "name": {"required": True, "type": "str"},
+ "acl_type": {
+ "choices": ["extended", "standard"],
+ "type": "str",
+ },
+ "rename": {"type": "str"},
+ "aces": {
+ "elements": "dict",
+ "type": "list",
+ "options": {
+ "grant": {
+ "choices": ["permit", "deny"],
+ "type": "str",
+ },
+ "line": {"type": "int"},
+ "remark": {"type": "str"},
+ "source": {
+ "type": "dict",
+ "options": {
+ "address": {"type": "str"},
+ "netmask": {"type": "str"},
+ "any": {"type": "bool"},
+ "any4": {"type": "bool"},
+ "any6": {"type": "bool"},
+ "host": {"type": "str"},
+ "interface": {"type": "str"},
+ "object_group": {"type": "str"},
+ "port_protocol": {
+ "type": "dict",
+ "options": {
+ "eq": {"type": "str"},
+ "gt": {"type": "str"},
+ "lt": {"type": "str"},
+ "neq": {"type": "str"},
+ "range": {
+ "type": "dict",
+ "options": {
+ "start": {
+ "type": "int"
+ },
+ "end": {"type": "int"},
+ },
+ },
+ },
+ },
+ },
+ },
+ "destination": {
+ "type": "dict",
+ "options": {
+ "address": {"type": "str"},
+ "netmask": {"type": "str"},
+ "any": {"type": "bool"},
+ "any4": {"type": "bool"},
+ "any6": {"type": "bool"},
+ "host": {"type": "str"},
+ "interface": {"type": "str"},
+ "object_group": {"type": "str"},
+ "port_protocol": {
+ "type": "dict",
+ "options": {
+ "eq": {"type": "str"},
+ "gt": {"type": "str"},
+ "lt": {"type": "str"},
+ "neq": {"type": "str"},
+ "range": {
+ "type": "dict",
+ "options": {
+ "start": {
+ "type": "int"
+ },
+ "end": {"type": "int"},
+ },
+ },
+ },
+ },
+ },
+ },
+ "protocol": {"type": "str"},
+ "protocol_options": {
+ "type": "dict",
+ "options": {
+ "protocol_number": {"type": "int"},
+ "ahp": {"type": "bool"},
+ "eigrp": {"type": "bool"},
+ "esp": {"type": "bool"},
+ "gre": {"type": "bool"},
+ "icmp": {
+ "type": "dict",
+ "options": {
+ "alternate_address": {
+ "type": "bool"
+ },
+ "conversion_error": {
+ "type": "bool"
+ },
+ "echo": {"type": "bool"},
+ "echo_reply": {"type": "bool"},
+ "information_reply": {
+ "type": "bool"
+ },
+ "information_request": {
+ "type": "bool"
+ },
+ "mask_reply": {"type": "bool"},
+ "mask_request": {
+ "type": "bool"
+ },
+ "mobile_redirect": {
+ "type": "bool"
+ },
+ "parameter_problem": {
+ "type": "bool"
+ },
+ "redirect": {"type": "bool"},
+ "router_advertisement": {
+ "type": "bool"
+ },
+ "router_solicitation": {
+ "type": "bool"
+ },
+ "source_quench": {
+ "type": "bool"
+ },
+ "source_route_failed": {
+ "type": "bool"
+ },
+ "time_exceeded": {
+ "type": "bool"
+ },
+ "timestamp_reply": {
+ "type": "bool"
+ },
+ "timestamp_request": {
+ "type": "bool"
+ },
+ "traceroute": {"type": "bool"},
+ "unreachable": {
+ "type": "bool"
+ },
+ },
+ },
+ "icmp6": {
+ "type": "dict",
+ "options": {
+ "echo": {"type": "bool"},
+ "echo_reply": {"type": "bool"},
+ "membership_query": {
+ "type": "bool"
+ },
+ "membership_reduction": {
+ "type": "bool"
+ },
+ "membership_report": {
+ "type": "bool"
+ },
+ "neighbor_advertisement": {
+ "type": "bool"
+ },
+ "neighbor_redirect": {
+ "type": "bool"
+ },
+ "neighbor_solicitation": {
+ "type": "bool"
+ },
+ "packet_too_big": {
+ "type": "bool"
+ },
+ "parameter_problem": {
+ "type": "bool"
+ },
+ "router_advertisement": {
+ "type": "bool"
+ },
+ "router_renumbering": {
+ "type": "bool"
+ },
+ "router_solicitation": {
+ "type": "bool"
+ },
+ "time_exceeded": {
+ "type": "bool"
+ },
+ "unreachable": {
+ "type": "bool"
+ },
+ },
+ },
+ "igmp": {"type": "bool"},
+ "igrp": {"type": "bool"},
+ "ip": {"type": "bool"},
+ "ipinip": {"type": "bool"},
+ "ipsec": {"type": "bool"},
+ "nos": {"type": "bool"},
+ "ospf": {"type": "bool"},
+ "pcp": {"type": "bool"},
+ "pim": {"type": "bool"},
+ "pptp": {"type": "bool"},
+ "sctp": {"type": "bool"},
+ "snp": {"type": "bool"},
+ "tcp": {"type": "bool"},
+ "udp": {"type": "bool"},
+ },
+ },
+ "inactive": {"type": "bool"},
+ "log": {
+ "type": "str",
+ "choices": [
+ "default",
+ "alerts",
+ "critical",
+ "debugging",
+ "disable",
+ "emergencies",
+ "errors",
+ "informational",
+ "interval",
+ "notifications",
+ "warnings",
+ ],
+ },
+ "time_range": {"type": "str"},
+ },
+ },
+ },
+ }
+ },
+ },
+ "running_config": {"type": "str"},
+ "state": {
+ "choices": [
+ "merged",
+ "replaced",
+ "overridden",
+ "deleted",
+ "gathered",
+ "rendered",
+ "parsed",
+ ],
+ "default": "merged",
+ "type": "str",
+ },
+ }
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/argspec/facts/__init__.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/argspec/facts/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/argspec/facts/__init__.py
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/argspec/facts/facts.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/argspec/facts/facts.py
new file mode 100644
index 00000000..e1f0b526
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/argspec/facts/facts.py
@@ -0,0 +1,27 @@
+#
+# -*- coding: utf-8 -*-
+# Copyright 2019 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+"""
+The arg spec for the asa facts module.
+"""
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+
+class FactsArgs(object):
+ """ The arg spec for the asa facts module
+ """
+
+ def __init__(self, **kwargs):
+ pass
+
+ argument_spec = {
+ "gather_subset": dict(
+ default=["!config"], type="list", elements="str"
+ ),
+ "gather_network_resources": dict(type="list", elements="str"),
+ }
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/argspec/ogs/__init__.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/argspec/ogs/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/argspec/ogs/__init__.py
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/argspec/ogs/ogs.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/argspec/ogs/ogs.py
new file mode 100644
index 00000000..d236993a
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/argspec/ogs/ogs.py
@@ -0,0 +1,229 @@
+# -*- coding: utf-8 -*-
+# Copyright 2019 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+#############################################
+# WARNING #
+#############################################
+#
+# This file is auto generated by the resource
+# module builder playbook.
+#
+# Do not edit this file manually.
+#
+# Changes to this file will be over written
+# by the resource module builder.
+#
+# Changes should be made in the model used to
+# generate this file or in the resource module
+# builder template.
+#
+#############################################
+
+"""
+The arg spec for the asa_ogs module
+"""
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+
+class OGsArgs(object):
+ """The arg spec for the asa_ogs module
+ """
+
+ def __init__(self, **kwargs):
+ pass
+
+ argument_spec = {
+ "config": {
+ "elements": "dict",
+ "type": "list",
+ "options": {
+ "object_type": {
+ "type": "str",
+ "required": True,
+ "choices": [
+ "icmp-type",
+ "network",
+ "protocol",
+ "security",
+ "service",
+ "user",
+ ],
+ },
+ "object_groups": {
+ "elements": "dict",
+ "type": "list",
+ "options": {
+ "name": {"required": True, "type": "str"},
+ "description": {"type": "str"},
+ "icmp_type": {
+ "type": "dict",
+ "options": {
+ "icmp_object": {
+ "type": "list",
+ "elements": "str",
+ "choices": [
+ "alternate-address",
+ "conversion-error",
+ "echo",
+ "echo-reply",
+ "information-reply",
+ "information-request",
+ "mask-reply",
+ "mask-request",
+ "mobile-redirect",
+ "parameter-problem",
+ "redirect",
+ "router-advertisement",
+ "router-solicitation",
+ "source-quench",
+ "time-exceeded",
+ "timestamp-reply",
+ "timestamp-request",
+ "traceroute",
+ "unreachable",
+ ],
+ }
+ },
+ },
+ "network_object": {
+ "type": "dict",
+ "options": {
+ "host": {"type": "list", "elements": "str"},
+ "address": {"type": "list", "elements": "str"},
+ "ipv6_address": {
+ "type": "list",
+ "elements": "str",
+ },
+ },
+ },
+ "protocol_object": {
+ "type": "dict",
+ "options": {
+ "protocol": {
+ "type": "list",
+ "elements": "str",
+ "choices": [
+ "ah",
+ "eigrp",
+ "esp",
+ "gre",
+ "icmp",
+ "icmp6",
+ "igmp",
+ "igrp",
+ "ip",
+ "ipinip",
+ "ipsec",
+ "nos",
+ "ospf",
+ "pcp",
+ "pim",
+ "pptp",
+ "sctp",
+ "snp",
+ "tcp",
+ "udp",
+ ],
+ }
+ },
+ },
+ "security_group": {
+ "type": "dict",
+ "options": {
+ "sec_name": {
+ "type": "list",
+ "elements": "str",
+ },
+ "tag": {"type": "list", "elements": "str"},
+ },
+ },
+ "service_object": {
+ "type": "dict",
+ "options": {
+ "protocol": {
+ "type": "list",
+ "elements": "str",
+ "choices": [
+ "ah",
+ "eigrp",
+ "esp",
+ "gre",
+ "icmp",
+ "icmp6",
+ "igmp",
+ "igrp",
+ "ip",
+ "ipinip",
+ "ipsec",
+ "nos",
+ "ospf",
+ "pcp",
+ "pim",
+ "pptp",
+ "sctp",
+ "snp",
+ "tcp",
+ "tcp-udp",
+ "udp",
+ ],
+ },
+ "object": {"type": "str"},
+ },
+ },
+ "user_object": {
+ "type": "dict",
+ "options": {
+ "user": {
+ "elements": "dict",
+ "type": "list",
+ "options": {
+ "name": {
+ "required": True,
+ "type": "str",
+ },
+ "domain": {
+ "required": True,
+ "type": "str",
+ },
+ },
+ },
+ "user_group": {
+ "elements": "dict",
+ "type": "list",
+ "options": {
+ "name": {
+ "required": True,
+ "type": "str",
+ },
+ "domain": {
+ "required": True,
+ "type": "str",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ "running_config": {"type": "str"},
+ "state": {
+ "choices": [
+ "merged",
+ "replaced",
+ "overridden",
+ "deleted",
+ "gathered",
+ "rendered",
+ "parsed",
+ ],
+ "default": "merged",
+ "type": "str",
+ },
+ }
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/asa.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/asa.py
new file mode 100644
index 00000000..f2a3ba2f
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/asa.py
@@ -0,0 +1,194 @@
+# This code is part of Ansible, but is an independent component.
+# This particular file snippet, and this file snippet only, is BSD licensed.
+# Modules you write using this snippet, which is embedded dynamically by Ansible
+# still belong to the author of the module, and may assign their own license
+# to the complete work.
+#
+# (c) 2016 Red Hat Inc.
+#
+# Redistribution and use in source and binary forms, with or without modification,
+# are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+import json
+
+from ansible.module_utils._text import to_text
+from ansible.module_utils.basic import env_fallback
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import (
+ EntityCollection,
+)
+from ansible.module_utils.connection import exec_command
+from ansible.module_utils.connection import Connection, ConnectionError
+
+_DEVICE_CONFIGS = {}
+_CONNECTION = None
+
+asa_provider_spec = {
+ "host": dict(),
+ "port": dict(type="int"),
+ "username": dict(fallback=(env_fallback, ["ANSIBLE_NET_USERNAME"])),
+ "password": dict(
+ fallback=(env_fallback, ["ANSIBLE_NET_PASSWORD"]), no_log=True
+ ),
+ "ssh_keyfile": dict(
+ fallback=(env_fallback, ["ANSIBLE_NET_SSH_KEYFILE"]), type="path"
+ ),
+ "authorize": dict(
+ fallback=(env_fallback, ["ANSIBLE_NET_AUTHORIZE"]), type="bool"
+ ),
+ "auth_pass": dict(
+ fallback=(env_fallback, ["ANSIBLE_NET_AUTH_PASS"]), no_log=True
+ ),
+ "timeout": dict(type="int"),
+}
+
+asa_argument_spec = {
+ "provider": dict(
+ type="dict",
+ options=asa_provider_spec,
+ removed_at_date="2022-06-01",
+ removed_from_collection="cisco.asa",
+ )
+}
+
+asa_top_spec = {
+ "authorize": dict(
+ fallback=(env_fallback, ["ANSIBLE_NET_AUTHORIZE"]), type="bool"
+ ),
+ "context": dict(type="str"),
+ "passwords": dict(type="bool"),
+}
+asa_argument_spec.update(asa_top_spec)
+
+command_spec = {"command": dict(key=True), "prompt": dict(), "answer": dict()}
+
+
+def get_provider_argspec():
+ return asa_provider_spec
+
+
+def check_args(module):
+ pass
+
+
+def get_connection(module):
+ if hasattr(module, "_asa_connection"):
+ return module._asa_connection
+
+ # Not all modules include the 'context' key.
+ context = module.params.get("context")
+ capabilities = get_capabilities(module)
+ network_api = capabilities.get("network_api")
+ if network_api == "cliconf":
+ module._asa_connection = Connection(module._socket_path)
+ else:
+ module.fail_json(msg="Invalid connection type %s" % network_api)
+
+ if context:
+ if context == "system":
+ command = "changeto system"
+ else:
+ command = "changeto context %s" % context
+ module._asa_connection.get(command)
+
+ return module._asa_connection
+
+
+def get_capabilities(module):
+ if hasattr(module, "_asa_capabilities"):
+ return module._asa_capabilities
+ try:
+ capabilities = Connection(module._socket_path).get_capabilities()
+ except ConnectionError as exc:
+ module.fail_json(msg=to_text(exc, errors="surrogate_then_replace"))
+ module._asa_capabilities = json.loads(capabilities)
+
+ return module._asa_capabilities
+
+
+def to_commands(module, commands):
+ if not isinstance(commands, list):
+ raise AssertionError("argument must be of type <list>")
+
+ transform = EntityCollection(module, command_spec)
+ commands = transform(commands)
+
+ for index, item in enumerate(commands):
+ if module.check_mode and not item["command"].startswith("show"):
+ module.warn(
+ "only show commands are supported when using check "
+ "mode, not executing `%s`" % item["command"]
+ )
+
+ return commands
+
+
+def run_commands(module, commands, check_rc=True):
+ connection = get_connection(module)
+ try:
+ return connection.run_commands(commands=commands, check_rc=check_rc)
+ except ConnectionError as exc:
+ module.fail_json(msg=to_text(exc))
+
+
+def get_config(module, flags=None):
+ flags = [] if flags is None else flags
+
+ # Not all modules include the 'passwords' key.
+ passwords = module.params.get("passwords", False)
+ if passwords:
+ cmd = "more system:running-config"
+ else:
+ cmd = "show running-config "
+ cmd += " ".join(flags)
+ cmd = cmd.strip()
+
+ try:
+ return _DEVICE_CONFIGS[cmd]
+ except KeyError:
+ conn = get_connection(module)
+ out = conn.get(cmd)
+ cfg = to_text(out, errors="surrogate_then_replace").strip()
+ _DEVICE_CONFIGS[cmd] = cfg
+ return cfg
+
+
+def load_config(module, config):
+ try:
+ conn = get_connection(module)
+ conn.edit_config(config)
+ except ConnectionError as exc:
+ module.fail_json(msg=to_text(exc))
+
+
+def get_defaults_flag(module):
+ rc, out, err = exec_command(module, "show running-config ?")
+ out = to_text(out, errors="surrogate_then_replace")
+
+ commands = set()
+ for line in out.splitlines():
+ if line:
+ commands.add(line.strip().split()[0])
+
+ if "all" in commands:
+ return "all"
+ else:
+ return "full"
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/config/__init__.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/config/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/config/__init__.py
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/config/acls/__init__.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/config/acls/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/config/acls/__init__.py
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/config/acls/acls.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/config/acls/acls.py
new file mode 100644
index 00000000..548453bd
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/config/acls/acls.py
@@ -0,0 +1,199 @@
+#
+# -*- coding: utf-8 -*-
+# Copyright 2019 Red Hat Inc.
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+"""
+The asa_acls class
+It is in this file where the current configuration (as dict)
+is compared to the provided configuration (as dict) and the command set
+necessary to bring the current configuration to it's desired end-state is
+created
+"""
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+
+from ansible.module_utils.six import iteritems
+from ansible_collections.cisco.asa.plugins.module_utils.network.asa.facts.facts import (
+ Facts,
+)
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import (
+ dict_merge,
+)
+from ansible_collections.cisco.asa.plugins.module_utils.network.asa.rm_templates.acls import (
+ AclsTemplate,
+)
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.resource_module import (
+ ResourceModule,
+)
+
+
+class Acls(ResourceModule):
+ """
+ The asa_acls class
+ """
+
+ gather_subset = ["!all", "!min"]
+
+ gather_network_resources = ["acls"]
+
+ def __init__(self, module):
+ super(Acls, self).__init__(
+ empty_fact_val={},
+ facts_module=Facts(module),
+ module=module,
+ resource="acls",
+ tmplt=AclsTemplate(),
+ )
+
+ def execute_module(self):
+ """ Execute the module
+ :rtype: A dictionary
+ :returns: The result from module execution
+ """
+ self.gen_config()
+ self.run_commands()
+ return self.result
+
+ def gen_config(self):
+ """ Select the appropriate function based on the state provided
+ :rtype: A list
+ :returns: the commands necessary to migrate the current configuration
+ to the desired configuration
+ """
+ if self.want:
+ wantd = {(entry["name"]): entry for entry in self.want["acls"]}
+ else:
+ wantd = {}
+ if self.have:
+ haved = {(entry["name"]): entry for entry in self.have["acls"]}
+ else:
+ haved = {}
+
+ for k, want in iteritems(wantd):
+ h_want = haved.get(k, {})
+ if want.get("aces"):
+ for each in want["aces"]:
+ if h_want.get("aces"):
+ for e_have in h_want.get("aces"):
+ if e_have.get("source") == each.get(
+ "source"
+ ) and e_have.get("destination") == each.get(
+ "destination"
+ ):
+ if (
+ "protocol" in e_have
+ and "protocol" not in each
+ and each.get("protocol_options")
+ == e_have.get("protocol_options")
+ ):
+ del e_have["protocol"]
+ break
+ # if state is merged, merge want onto have and then compare
+ if self.state == "merged":
+ wantd = dict_merge(haved, wantd)
+
+ # if state is deleted, empty out wantd and set haved to wantd
+ if self.state == "deleted":
+ haved = {
+ k: v for k, v in iteritems(haved) if k in wantd or not wantd
+ }
+ wantd = {}
+
+ # remove superfluous config for overridden and deleted
+ if self.state in ["overridden", "deleted"]:
+ for k, have in iteritems(haved):
+ if k not in wantd:
+ self._compare(want={}, have=have)
+
+ temp = []
+ for k, want in iteritems(wantd):
+ if want.get("rename") and want.get("rename") not in temp:
+ self.commands.extend(
+ ["access-list {name} rename {rename}".format(**want)]
+ )
+ elif k in haved:
+ temp.append(k)
+ self._compare(want=want, have=haved.pop(k, {}))
+ if self.state in ["replaced", "overridden", "deleted"]:
+ config_cmd = [cmd for cmd in self.commands if "no" in cmd][::-1]
+ config_cmd.extend(
+ [cmd for cmd in self.commands if "no" not in cmd]
+ )
+ self.commands = config_cmd
+
+ def _compare(self, want, have):
+ """Leverages the base class `compare()` method and
+ populates the list of commands to be run by comparing
+ the `want` and `have` data with the `parsers` defined
+ for the Ospf_interfaces network resource.
+ """
+ parsers = ["aces"]
+
+ if want.get("aces"):
+ for each in want["aces"]:
+ set_want = True
+ if have.get("aces"):
+ temp = 0
+ for e_have in have.get("aces"):
+ if e_have.get("source") == each.get(
+ "source"
+ ) and e_have.get("destination") == each.get(
+ "destination"
+ ):
+ set_want = False
+ each.update(
+ {
+ "name": want.get("name"),
+ "acl_type": want.get("acl_type"),
+ }
+ )
+ e_have.update(
+ {
+ "name": have.get("name"),
+ "acl_type": have.get("acl_type"),
+ }
+ )
+ self.compare(
+ parsers=parsers,
+ want={"aces": each},
+ have={"aces": e_have},
+ )
+ del have.get("aces")[temp]
+ break
+ temp += 1
+ else:
+ each.update(
+ {
+ "name": want.get("name"),
+ "acl_type": want.get("acl_type"),
+ }
+ )
+ self.compare(
+ parsers=parsers, want={"aces": each}, have=dict()
+ )
+ set_want = False
+ if set_want:
+ each.update(
+ {
+ "name": want.get("name"),
+ "acl_type": want.get("acl_type"),
+ }
+ )
+ self.compare(
+ parsers=parsers, want={"aces": each}, have=dict()
+ )
+ if self.state in ["overridden", "deleted", "replaced"]:
+ if have.get("aces"):
+ for each in have["aces"]:
+ each.update(
+ {
+ "name": have.get("name"),
+ "acl_type": have.get("acl_type"),
+ }
+ )
+ self.compare(
+ parsers=parsers, want=dict(), have={"aces": each}
+ )
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/config/ogs/__init__.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/config/ogs/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/config/ogs/__init__.py
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/config/ogs/ogs.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/config/ogs/ogs.py
new file mode 100644
index 00000000..857b43ff
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/config/ogs/ogs.py
@@ -0,0 +1,459 @@
+#
+# -*- coding: utf-8 -*-
+# Copyright 2019 Red Hat Inc.
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+"""
+The asa_ogs class
+It is in this file where the current configuration (as dict)
+is compared to the provided configuration (as dict) and the command set
+necessary to bring the current configuration to it's desired end-state is
+created
+"""
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+import copy
+from ansible.module_utils.six import iteritems
+from ansible_collections.cisco.asa.plugins.module_utils.network.asa.facts.facts import (
+ Facts,
+)
+from ansible_collections.cisco.asa.plugins.module_utils.network.asa.rm_templates.ogs import (
+ OGsTemplate,
+)
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import (
+ dict_merge,
+)
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.resource_module import (
+ ResourceModule,
+)
+
+
+class OGs(ResourceModule):
+ """
+ The asa_ogs class
+ """
+
+ gather_subset = ["!all", "!min"]
+
+ gather_network_resources = ["ogs"]
+
+ def __init__(self, module):
+ super(OGs, self).__init__(
+ empty_fact_val={},
+ facts_module=Facts(module),
+ module=module,
+ resource="ogs",
+ tmplt=OGsTemplate(),
+ )
+
+ def execute_module(self):
+ """ Execute the module
+ :rtype: A dictionary
+ :returns: The result from module execution
+ """
+ self.gen_config()
+ self.run_commands()
+ return self.result
+
+ def gen_config(self):
+ """ Select the appropriate function based on the state provided
+ :rtype: A list
+ :returns: the commands necessary to migrate the current configuration
+ to the desired configuration
+ """
+ if self.want:
+ wantd = {(entry["object_type"]): entry for entry in self.want}
+ else:
+ wantd = {}
+ if self.have:
+ haved = {(entry["object_type"]): entry for entry in self.have}
+ else:
+ haved = {}
+
+ obj_gp = {}
+ for k, v in wantd.items():
+ temp = {}
+ for each in v.get("object_groups"):
+ temp[each.get("name")] = each
+ temp["object_type"] = k
+ obj_gp[k] = temp
+ if obj_gp:
+ wantd = obj_gp
+ obj_gp = {}
+ for k, v in haved.items():
+ temp = {}
+ for each in v.get("object_groups"):
+ temp[each.get("name")] = each
+ temp["object_type"] = k
+ obj_gp[k] = temp
+ if obj_gp:
+ haved = obj_gp
+
+ # if state is merged, merge want onto have
+ if self.state == "merged":
+ wantd = dict_merge(haved, wantd)
+
+ # if state is deleted, empty out wantd and set haved to wantd
+ if self.state == "deleted":
+ temp = {}
+ for k, v in iteritems(haved):
+ temp_have = {}
+ if k in wantd or not wantd:
+ for key, val in iteritems(v):
+ if not wantd or key in wantd[k]:
+ temp_have.update({key: val})
+ temp.update({k: temp_have})
+ haved = temp
+ wantd = {}
+
+ # delete processes first so we do run into "more than one" errors
+ if self.state in ["overridden", "deleted"]:
+ for k, have in iteritems(haved):
+ if k not in wantd:
+ for each_key, each_val in iteritems(have):
+ if each_key != "object_type":
+ each_val.update(
+ {"object_type": have.get("object_type")}
+ )
+ self.addcmd(each_val, "og_name", True)
+
+ for k, want in iteritems(wantd):
+ self._compare(want=want, have=haved.pop(k, {}))
+
+ def _compare(self, want, have):
+ if want != have:
+ for k, v in iteritems(want):
+ if k != "object_type":
+ v.update({"object_type": want.get("object_type")})
+ if have:
+ for k, v in iteritems(have):
+ if k != "object_type":
+ v.update({"object_type": want.get("object_type")})
+
+ object_type = want.get("object_type")
+ if object_type == "icmp-type":
+ self._icmp_object_compare(want, have)
+ if object_type == "network":
+ self._network_object_compare(want, have)
+ elif object_type == "protocol":
+ self._protocol_object_compare(want, have)
+ elif object_type == "security":
+ self._security_object_compare(want, have)
+ elif object_type == "service":
+ self._service_object_compare(want, have)
+ elif object_type == "user":
+ self._user_object_compare(want, have)
+
+ def get_list_diff(self, want, have, object, param):
+ diff = [
+ item
+ for item in want[object][param]
+ if item not in have[object][param]
+ ]
+ return diff
+
+ def check_for_have_and_overidden(self, have):
+ if have and self.state == "overridden":
+ for name, entry in iteritems(have):
+ if name != "object_type":
+ self.addcmd(entry, "og_name", True)
+
+ def _icmp_object_compare(self, want, have):
+ icmp_obj = "icmp_type"
+ for name, entry in iteritems(want):
+ h_item = have.pop(name, {})
+ if (
+ entry != h_item
+ and name != "object_type"
+ and entry[icmp_obj].get("icmp_object")
+ ):
+ if h_item:
+ self._add_object_cmd(
+ entry, h_item, icmp_obj, ["icmp_type"]
+ )
+ else:
+ self.addcmd(entry, "og_name", False)
+ self.compare(["description"], entry, h_item)
+ if self.state in ("overridden", "replaced") and h_item:
+ self.compare(["icmp_type"], {}, h_item)
+ if h_item and h_item[icmp_obj].get("icmp_object"):
+ li_diff = self.get_list_diff(
+ entry, h_item, icmp_obj, "icmp_object"
+ )
+ else:
+ li_diff = entry[icmp_obj].get("icmp_object")
+ entry[icmp_obj]["icmp_object"] = li_diff
+ self.addcmd(entry, "icmp_type", False)
+ self.check_for_have_and_overidden(have)
+
+ def _network_object_compare(self, want, have):
+ network_obj = "network_object"
+ parsers = [
+ "network_object.host",
+ "network_object.address",
+ "network_object.ipv6_address",
+ ]
+ add_obj_cmd = False
+ for name, entry in iteritems(want):
+ h_item = have.pop(name, {})
+ if entry != h_item and name != "object_type":
+ if h_item:
+ self._add_object_cmd(
+ entry,
+ h_item,
+ network_obj,
+ ["address", "host", "ipv6_address"],
+ )
+ else:
+ add_obj_cmd = True
+ self.addcmd(entry, "og_name", False)
+ self.compare(["description"], entry, h_item)
+ if entry[network_obj].get("address"):
+ self._compare_object_diff(
+ entry,
+ h_item,
+ network_obj,
+ "address",
+ parsers,
+ "network_object.address",
+ )
+ elif h_item and h_item[network_obj].get("address"):
+ h_item[network_obj] = {
+ "address": h_item[network_obj].get("address")
+ }
+ if not add_obj_cmd:
+ self.addcmd(entry, "og_name", False)
+ self.compare(parsers, {}, h_item)
+ if entry[network_obj].get("host"):
+ self._compare_object_diff(
+ entry,
+ h_item,
+ network_obj,
+ "host",
+ parsers,
+ "network_object.host",
+ )
+ elif h_item and h_item[network_obj].get("host"):
+ h_item[network_obj] = {
+ "host": h_item[network_obj].get("host")
+ }
+ if not add_obj_cmd:
+ self.addcmd(entry, "og_name", False)
+ self.compare(parsers, {}, h_item)
+ if entry[network_obj].get("ipv6_address"):
+ self._compare_object_diff(
+ entry,
+ h_item,
+ network_obj,
+ "ipv6_address",
+ parsers,
+ "network_object.ipv6_address",
+ )
+ elif h_item and h_item[network_obj].get("ipv6_address"):
+ h_item[network_obj] = {
+ "ipv6_address": h_item[network_obj].get("ipv6_address")
+ }
+ if not add_obj_cmd:
+ self.addcmd(entry, "og_name", False)
+ self.compare(parsers, {}, h_item)
+ self.check_for_have_and_overidden(have)
+
+ def _protocol_object_compare(self, want, have):
+ protocol_obj = "protocol_object"
+ for name, entry in iteritems(want):
+ h_item = have.pop(name, {})
+ if entry != h_item and name != "object_type":
+ if h_item:
+ self._add_object_cmd(
+ entry, h_item, protocol_obj, ["protocol"]
+ )
+ else:
+ self.addcmd(entry, "og_name", False)
+ self.compare(["description"], entry, h_item)
+ if entry[protocol_obj].get("protocol"):
+ self._compare_object_diff(
+ entry,
+ h_item,
+ protocol_obj,
+ "protocol",
+ [protocol_obj],
+ protocol_obj,
+ )
+ self.check_for_have_and_overidden(have)
+
+ def _security_object_compare(self, want, have):
+ security_obj = "security_group"
+ parsers = ["security_group.sec_name", "security_group.tag"]
+ add_obj_cmd = False
+ for name, entry in iteritems(want):
+ h_item = have.pop(name, {})
+ if entry != h_item and name != "object_type":
+ if h_item:
+ self._add_object_cmd(
+ entry, h_item, security_obj, ["sec_name", "tag"]
+ )
+ else:
+ add_obj_cmd = True
+ self.addcmd(entry, "og_name", False)
+ self.compare(["description"], entry, h_item)
+ if entry[security_obj].get("sec_name"):
+ self._compare_object_diff(
+ entry,
+ h_item,
+ security_obj,
+ "sec_name",
+ parsers,
+ "security_group.sec_name",
+ )
+ elif h_item and h_item[security_obj].get("sec_name"):
+ h_item[security_obj] = {
+ "sec_name": h_item[security_obj].get("sec_name")
+ }
+ if not add_obj_cmd:
+ self.addcmd(entry, "og_name", False)
+ self.compare(parsers, {}, h_item)
+ if entry[security_obj].get("tag"):
+ self._compare_object_diff(
+ entry,
+ h_item,
+ security_obj,
+ "tag",
+ parsers,
+ "security_group.tag",
+ )
+ elif h_item and h_item[security_obj].get("tag"):
+ h_item[security_obj] = {
+ "tag": h_item[security_obj].get("tag")
+ }
+ if not add_obj_cmd:
+ self.addcmd(entry, "og_name", False)
+ self.compare(parsers, {}, h_item)
+ self.check_for_have_and_overidden(have)
+
+ def _service_object_compare(self, want, have):
+ service_obj = "service_object"
+ for name, entry in iteritems(want):
+ h_item = have.pop(name, {})
+ if entry != h_item and name != "object_type":
+ if h_item:
+ self._add_object_cmd(
+ entry, h_item, service_obj, ["protocol"]
+ )
+ else:
+ self.addcmd(entry, "og_name", False)
+ self.compare(["description"], entry, h_item)
+ if entry[service_obj].get("protocol"):
+ self._compare_object_diff(
+ entry,
+ h_item,
+ service_obj,
+ "protocol",
+ ["service_object"],
+ service_obj,
+ )
+ self.check_for_have_and_overidden(have)
+
+ def _user_object_compare(self, want, have):
+ user_obj = "user_object"
+ parsers = ["user_object.user", "user_object.user_gp"]
+ add_obj_cmd = False
+ for name, entry in iteritems(want):
+ h_item = have.pop(name, {})
+ if entry != h_item and name != "object_type":
+ if h_item:
+ self._add_object_cmd(
+ entry, h_item, user_obj, ["user", "user_group"]
+ )
+ else:
+ add_obj_cmd = True
+ self.addcmd(entry, "og_name", False)
+ self.compare(["description"], entry, h_item)
+ if entry[user_obj].get("user"):
+ self._compare_object_diff(
+ entry,
+ h_item,
+ user_obj,
+ "user",
+ ["user_object.user"],
+ "user_object.user",
+ )
+ elif h_item and h_item[user_obj].get("user"):
+ h_item[user_obj] = {"user": h_item[user_obj].get("user")}
+ if not add_obj_cmd:
+ self.addcmd(entry, "og_name", False)
+ self.compare(parsers, {}, h_item)
+ if entry[user_obj].get("user_group"):
+ self._compare_object_diff(
+ entry,
+ h_item,
+ user_obj,
+ "user_group",
+ ["user_object.user_group"],
+ "user_object.user_gp",
+ )
+ elif h_item and h_item[user_obj].get("user_group"):
+ h_item[user_obj] = {
+ "user_group": h_item[user_obj].get("user_group")
+ }
+ if not add_obj_cmd:
+ self.addcmd(entry, "og_name", False)
+ self.compare(parsers, {}, h_item)
+ self.check_for_have_and_overidden(have)
+
+ def _add_object_cmd(self, want, have, object, object_elements):
+ obj_cmd_added = False
+ for each in object_elements:
+ want_element = want[object].get(each)
+ have_element = have[object].get(each)
+ if want_element and isinstance(want_element[0], dict):
+ if (
+ want_element
+ and have_element
+ and want_element != have_element
+ ):
+ if not obj_cmd_added:
+ self.addcmd(want, "og_name", False)
+ self.compare(["description"], want, have)
+ obj_cmd_added = True
+ else:
+ if (
+ want_element
+ and have_element
+ and set(want_element) != set(have_element)
+ ):
+ if not obj_cmd_added:
+ self.addcmd(want, "og_name", False)
+ self.compare(["description"], want, have)
+ obj_cmd_added = True
+
+ def _compare_object_diff(
+ self, want, have, object, object_type, parsers, val
+ ):
+ temp_have = copy.copy(have)
+ temp_want = copy.copy(want)
+ if temp_have and temp_have[object].get(object_type):
+ want_diff = self.get_list_diff(
+ temp_want, temp_have, object, object_type
+ )
+ have_diff = [
+ each
+ for each in temp_have[object][object_type]
+ if each not in temp_want[object][object_type]
+ ]
+ if have_diff:
+ temp_have[object].pop(object_type)
+ else:
+ have_diff = []
+ want_diff = temp_want[object].get(object_type)
+ temp_want[object][object_type] = want_diff
+ if (
+ have_diff
+ or temp_have.get(object)
+ and self.state in ("overridden", "replaced")
+ ):
+ if have_diff:
+ temp_have[object] = {object_type: have_diff}
+ self.compare(parsers, {}, temp_have)
+ self.addcmd(temp_want, val, False)
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/facts/__init__.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/facts/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/facts/__init__.py
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/facts/acls/__init__.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/facts/acls/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/facts/acls/__init__.py
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/facts/acls/acls.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/facts/acls/acls.py
new file mode 100644
index 00000000..5c3f7b97
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/facts/acls/acls.py
@@ -0,0 +1,106 @@
+#
+# -*- coding: utf-8 -*-
+# Copyright 2019 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+"""
+The asa_acls fact class
+It is in this file the configuration is collected from the device
+for a given resource, parsed, and the facts tree is populated
+based on the configuration.
+"""
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+
+from copy import deepcopy
+from ansible.module_utils.six import iteritems
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import (
+ utils,
+)
+from ansible_collections.cisco.asa.plugins.module_utils.network.asa.argspec.acls.acls import (
+ AclsArgs,
+)
+from ansible_collections.cisco.asa.plugins.module_utils.network.asa.rm_templates.acls import (
+ AclsTemplate,
+)
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network_template import (
+ NetworkTemplate,
+)
+
+
+class AclsFacts(object):
+ """ The asa_acls fact class
+ """
+
+ def __init__(self, module, subspec="config", options="options"):
+
+ self._module = module
+ self.argument_spec = AclsArgs.argument_spec
+ spec = deepcopy(self.argument_spec)
+ if subspec:
+ if options:
+ facts_argument_spec = spec[subspec][options]
+ else:
+ facts_argument_spec = spec[subspec]
+ else:
+ facts_argument_spec = spec
+
+ self.generated_spec = utils.generate_dict(facts_argument_spec)
+
+ def get_acls_config(self, connection):
+ return connection.get("sh access-list")
+
+ def populate_facts(self, connection, ansible_facts, data=None):
+ """ Populate the facts for ACLs
+ :param connection: the device connection
+ :param ansible_facts: Facts dictionary
+ :param data: previously collected conf
+ :rtype: dictionary
+ :returns: facts
+ """
+ if not data:
+ data = self.get_acls_config(connection)
+
+ rmmod = NetworkTemplate(lines=data.splitlines(), tmplt=AclsTemplate())
+ current = rmmod.parse()
+ acls = list()
+ if current.get("acls"):
+ for key, val in iteritems(current.get("acls")):
+ if val.get("name") == "cached":
+ continue
+ for each in val.get("aces"):
+ if "protocol_number" in each:
+ each["protocol_options"] = {
+ "protocol_number": each["protocol_number"]
+ }
+ del each["protocol_number"]
+ if "icmp_icmp6_protocol" in each and each.get("protocol"):
+ each["protocol_options"] = {
+ each.get("protocol"): {
+ each["icmp_icmp6_protocol"].replace(
+ "-", "_"
+ ): True
+ }
+ }
+ del each["icmp_icmp6_protocol"]
+ elif (
+ each.get("protocol")
+ and each.get("protocol") != "icmp"
+ and each.get("protocol") != "icmp6"
+ ):
+ each["protocol_options"] = {each.get("protocol"): True}
+ acls.append(val)
+ facts = {}
+ params = {}
+ if acls:
+ params = utils.validate_config(
+ self.argument_spec, {"config": {"acls": acls}}
+ )
+ params = utils.remove_empties(params)
+ facts["acls"] = params["config"]
+
+ ansible_facts["ansible_network_resources"].update(facts)
+ return ansible_facts
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/facts/facts.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/facts/facts.py
new file mode 100644
index 00000000..b874c3f0
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/facts/facts.py
@@ -0,0 +1,67 @@
+# -*- coding: utf-8 -*-
+# Copyright 2019 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+"""
+The facts class for asa
+this file validates each subset of facts and selectively
+calls the appropriate facts gathering function
+"""
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts import (
+ FactsBase,
+)
+from ansible_collections.cisco.asa.plugins.module_utils.network.asa.facts.acls.acls import (
+ AclsFacts,
+)
+from ansible_collections.cisco.asa.plugins.module_utils.network.asa.facts.ogs.ogs import (
+ OGsFacts,
+)
+from ansible_collections.cisco.asa.plugins.module_utils.network.asa.facts.legacy.base import (
+ Default,
+ Hardware,
+ Config,
+)
+
+
+FACT_LEGACY_SUBSETS = dict(default=Default, hardware=Hardware, config=Config)
+
+FACT_RESOURCE_SUBSETS = dict(acls=AclsFacts, ogs=OGsFacts)
+
+
+class Facts(FactsBase):
+ """ The fact class for asa
+ """
+
+ VALID_LEGACY_GATHER_SUBSETS = frozenset(FACT_LEGACY_SUBSETS.keys())
+ VALID_RESOURCE_SUBSETS = frozenset(FACT_RESOURCE_SUBSETS.keys())
+
+ def __init__(self, module):
+ super(Facts, self).__init__(module)
+
+ def get_facts(
+ self, legacy_facts_type=None, resource_facts_type=None, data=None
+ ):
+ """ Collect the facts for asa
+ :param legacy_facts_type: List of legacy facts types
+ :param resource_facts_type: List of resource fact types
+ :param data: previously collected conf
+ :rtype: dict
+ :return: the facts gathered
+ """
+ if self.VALID_RESOURCE_SUBSETS:
+ self.get_network_resources_facts(
+ FACT_RESOURCE_SUBSETS, resource_facts_type, data
+ )
+
+ if self.VALID_LEGACY_GATHER_SUBSETS:
+ self.get_network_legacy_facts(
+ FACT_LEGACY_SUBSETS, legacy_facts_type
+ )
+
+ return self.ansible_facts, self._warnings
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/facts/legacy/__init__.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/facts/legacy/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/facts/legacy/__init__.py
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/facts/legacy/base.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/facts/legacy/base.py
new file mode 100644
index 00000000..3ad46007
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/facts/legacy/base.py
@@ -0,0 +1,186 @@
+# -*- coding: utf-8 -*-
+# Copyright 2019 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+"""
+The asa legacy fact class
+It is in this file the configuration is collected from the device
+for a given resource, parsed, and the facts tree is populated
+based on the configuration.
+"""
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+
+import platform
+import re
+
+from ansible_collections.cisco.asa.plugins.module_utils.network.asa.asa import (
+ run_commands,
+ get_capabilities,
+)
+
+
+class FactsBase(object):
+
+ COMMANDS = list()
+
+ def __init__(self, module):
+ self.module = module
+ self.facts = dict()
+ self.warnings = list()
+ self.responses = None
+
+ def populate(self):
+ self.responses = run_commands(
+ self.module, commands=self.COMMANDS, check_rc=False
+ )
+
+ def run(self, cmd):
+ return run_commands(self.module, commands=cmd, check_rc=False)
+
+
+class Default(FactsBase):
+
+ COMMANDS = ["show version"]
+
+ def populate(self):
+ super(Default, self).populate()
+ self.facts.update(self.platform_facts())
+ data = self.responses[0]
+ if data:
+ self.facts["asatype"] = self.parse_asatype(data)
+ self.facts["serialnum"] = self.parse_serialnum(data)
+ self.parse_stacks(data)
+
+ def parse_asatype(self, data):
+ match = re.search(r"Hardware:(\s+)ASA", data)
+ if match:
+ return "ASA"
+
+ def parse_serialnum(self, data):
+ match = re.search(r"Serial Number: (\S+)", data)
+ if match:
+ return match.group(1)
+
+ def parse_stacks(self, data):
+ match = re.findall(r"^Model [Nn]umber\s+: (\S+)", data, re.M)
+ if match:
+ self.facts["stacked_models"] = match
+
+ match = re.findall(
+ r"^System [Ss]erial [Nn]umber\s+: (\S+)", data, re.M
+ )
+ if match:
+ self.facts["stacked_serialnums"] = match
+
+ def platform_facts(self):
+ platform_facts = {}
+
+ resp = get_capabilities(self.module)
+ device_info = resp["device_info"]
+ platform_facts["system"] = device_info["network_os"]
+
+ for item in (
+ "model",
+ "image",
+ "version",
+ "platform",
+ "hostname",
+ "firepower_version",
+ "device_mgr_version",
+ ):
+ val = device_info.get("network_os_%s" % item)
+ if val:
+ platform_facts[item] = val
+
+ platform_facts["api"] = resp["network_api"]
+ platform_facts["python_version"] = platform.python_version()
+
+ return platform_facts
+
+
+class Hardware(FactsBase):
+
+ COMMANDS = ["dir", "show memory"]
+
+ def populate(self):
+ warnings = list()
+ super(Hardware, self).populate()
+ data = self.responses[0]
+ if data:
+ self.facts["filesystems"] = self.parse_filesystems(data)
+ self.facts["filesystems_info"] = self.parse_filesystems_info(data)
+
+ data = self.responses[1]
+ if data:
+ if "Invalid input detected" in data:
+ warnings.append("Unable to gather memory statistics")
+ else:
+ mem_list = [l for l in data.splitlines() if "memory" in l]
+ for each in mem_list:
+ if "Free memory" in each:
+ match = re.search(
+ r"Free memory.+ (\d+) .+(\d\d)", each
+ )
+ if match:
+ self.facts["memfree_mb"] = (
+ int(match.group(1)) // 1024
+ )
+ elif "Used memory" in each:
+ match = re.search(
+ r"Used memory.+ (\d+) .+(\d\d)", each
+ )
+ if match:
+ self.facts["memused_mb"] = (
+ int(match.group(1)) // 1024
+ )
+ elif "Total memory" in each:
+ match = re.search(
+ r"Total memory.+ (\d+) .+(\d\d)", each
+ )
+ if match:
+ self.facts["memtotal_mb"] = (
+ int(match.group(1)) // 1024
+ )
+
+ def parse_filesystems(self, data):
+ return re.findall(r"^Directory of (\S+)/", data, re.M)
+
+ def parse_filesystems_info(self, data):
+ facts = dict()
+ fs = ""
+ for line in data.split("\n"):
+ match = re.match(r"^Directory of (\S+)/", line)
+ if match:
+ fs = match.group(1)
+ facts[fs] = dict()
+ continue
+ match = re.match(
+ r"^(\d+) bytes total \((\d+) bytes free\/(\d+)% free\)", line
+ )
+ if match:
+ facts[fs]["spacetotal_kb"] = int(match.group(1)) / 1024
+ facts[fs]["spacefree_kb"] = int(match.group(2)) / 1024
+
+ return facts
+
+
+class Config(FactsBase):
+
+ COMMANDS = ["show running-config"]
+
+ def populate(self):
+ super(Config, self).populate()
+ data = self.responses[0]
+ if data:
+ data = re.sub(
+ r"^Building configuration...\s+Current configuration : \d+ bytes\n",
+ "",
+ data,
+ flags=re.MULTILINE,
+ )
+ self.facts["config"] = data
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/facts/ogs/__init__.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/facts/ogs/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/facts/ogs/__init__.py
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/facts/ogs/ogs.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/facts/ogs/ogs.py
new file mode 100644
index 00000000..cf1c4335
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/facts/ogs/ogs.py
@@ -0,0 +1,108 @@
+# -*- coding: utf-8 -*-
+# Copyright 2019 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+"""
+The asa_og fact class
+It is in this file the configuration is collected from the device
+for a given resource, parsed, and the facts tree is populated
+based on the configuration.
+"""
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+
+from copy import deepcopy
+from ansible.module_utils.six import iteritems
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import (
+ utils,
+)
+from ansible_collections.cisco.asa.plugins.module_utils.network.asa.argspec.ogs.ogs import (
+ OGsArgs,
+)
+from ansible_collections.cisco.asa.plugins.module_utils.network.asa.rm_templates.ogs import (
+ OGsTemplate,
+)
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network_template import (
+ NetworkTemplate,
+)
+
+
+class OGsFacts(object):
+ """ The asa_ogs fact class
+ """
+
+ def __init__(self, module, subspec="config", options="options"):
+
+ self._module = module
+ self.argument_spec = OGsArgs.argument_spec
+ spec = deepcopy(self.argument_spec)
+ if subspec:
+ if options:
+ facts_argument_spec = spec[subspec][options]
+ else:
+ facts_argument_spec = spec[subspec]
+ else:
+ facts_argument_spec = spec
+
+ self.generated_spec = utils.generate_dict(facts_argument_spec)
+
+ def get_og_data(self, connection):
+ return connection.get("sh running-config object-group")
+
+ def populate_facts(self, connection, ansible_facts, data=None):
+ """ Populate the facts for OGs
+ :param connection: the device connection
+ :param ansible_facts: Facts dictionary
+ :param data: previously collected conf
+ :rtype: dictionary
+ :returns: facts
+ """
+ if not data:
+ data = self.get_og_data(connection)
+
+ rmmod = NetworkTemplate(lines=data.splitlines(), tmplt=OGsTemplate())
+ current = rmmod.parse()
+
+ ogs = []
+ object_groups = {
+ "icmp-type": "icmp_type",
+ "network": "network_object",
+ "protocol": "protocol_object",
+ "security": "security_group",
+ "service": "service_object",
+ "user": "user_object",
+ }
+ if current.get("ogs"):
+ for k, v in iteritems(current.get("ogs")):
+ obj_gp = {}
+ config_dict = {}
+ config_dict["object_type"] = k
+ config_dict["object_groups"] = []
+ for each in iteritems(v):
+ obj_gp["name"] = each[1].pop("name")
+ each[1].pop("object_type")
+ if each[1].get("description"):
+ obj_gp["description"] = each[1].pop("description")
+ if each[1].get("group_object"):
+ obj_gp["group_object"] = each[1].pop("group_object")
+ obj_gp[object_groups.get(k)] = each[1]
+ config_dict["object_groups"].append(obj_gp)
+ obj_gp = {}
+ config_dict["object_groups"] = sorted(
+ config_dict["object_groups"],
+ key=lambda k, sk="name": k[sk],
+ )
+ ogs.append(config_dict)
+ # sort the object group list of dict by object_type
+ ogs = sorted(ogs, key=lambda i: i["object_type"])
+ facts = {}
+ params = utils.remove_empties(
+ utils.validate_config(self.argument_spec, {"config": ogs})
+ )
+ facts["ogs"] = params.get("config")
+
+ ansible_facts["ansible_network_resources"].update(facts)
+ return ansible_facts
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/providers/__init__.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/providers/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/providers/__init__.py
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/providers/module.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/providers/module.py
new file mode 100644
index 00000000..1a847275
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/providers/module.py
@@ -0,0 +1,73 @@
+#
+# (c) 2019, Ansible by Red Hat, inc
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+#
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.connection import Connection
+from ansible_collections.cisco.asa.plugins.module_utils.network.asa.providers import (
+ providers,
+)
+from ansible.module_utils._text import to_text
+
+
+class NetworkModule(AnsibleModule):
+
+ fail_on_missing_provider = True
+
+ def __init__(self, connection=None, *args, **kwargs):
+ super(NetworkModule, self).__init__(*args, **kwargs)
+
+ if connection is None:
+ connection = Connection(self._socket_path)
+
+ self.connection = connection
+
+ @property
+ def provider(self):
+ if not hasattr(self, "_provider"):
+ capabilities = self.from_json(self.connection.get_capabilities())
+
+ network_os = capabilities["device_info"]["network_os"]
+ network_api = capabilities["network_api"]
+
+ if network_api == "cliconf":
+ connection_type = "network_cli"
+
+ cls = providers.get(
+ network_os, self._name.split(".")[-1], connection_type
+ )
+
+ if not cls:
+ msg = (
+ "unable to find suitable provider for network os %s"
+ % network_os
+ )
+ if self.fail_on_missing_provider:
+ self.fail_json(msg=msg)
+ else:
+ self.warn(msg)
+
+ obj = cls(self.params, self.connection, self.check_mode)
+
+ setattr(self, "_provider", obj)
+
+ return getattr(self, "_provider")
+
+ def get_facts(self, subset=None):
+ try:
+ self.provider.get_facts(subset)
+ except Exception as exc:
+ self.fail_json(msg=to_text(exc))
+
+ def edit_config(self, config_filter=None):
+ current_config = self.connection.get_config(flags=config_filter)
+ try:
+ commands = self.provider.edit_config(current_config)
+ changed = bool(commands)
+ return {"commands": commands, "changed": changed}
+ except Exception as exc:
+ self.fail_json(msg=to_text(exc))
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/providers/providers.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/providers/providers.py
new file mode 100644
index 00000000..fdf99cb3
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/providers/providers.py
@@ -0,0 +1,129 @@
+#
+# (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 json
+
+from threading import RLock
+
+from ansible.module_utils.six import itervalues
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import (
+ to_list,
+)
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.config import (
+ NetworkConfig,
+)
+
+
+_registered_providers = {}
+_provider_lock = RLock()
+
+
+def register_provider(network_os, module_name):
+ def wrapper(cls):
+ _provider_lock.acquire()
+ try:
+ if network_os not in _registered_providers:
+ _registered_providers[network_os] = {}
+ for ct in cls.supported_connections:
+ if ct not in _registered_providers[network_os]:
+ _registered_providers[network_os][ct] = {}
+ for item in to_list(module_name):
+ for entry in itervalues(_registered_providers[network_os]):
+ entry[item] = cls
+ finally:
+ _provider_lock.release()
+ return cls
+
+ return wrapper
+
+
+def get(network_os, module_name, connection_type):
+ network_os_providers = _registered_providers.get(network_os)
+ if network_os_providers is None:
+ raise ValueError("unable to find a suitable provider for this module")
+ if connection_type not in network_os_providers:
+ raise ValueError("provider does not support this connection type")
+ elif module_name not in network_os_providers[connection_type]:
+ raise ValueError("could not find a suitable provider for this module")
+ return network_os_providers[connection_type][module_name]
+
+
+class ProviderBase(object):
+
+ supported_connections = ()
+
+ def __init__(self, params, connection=None, check_mode=False):
+ self.params = params
+ self.connection = connection
+ self.check_mode = check_mode
+
+ @property
+ def capabilities(self):
+ if not hasattr(self, "_capabilities"):
+ resp = self.from_json(self.connection.get_capabilities())
+ setattr(self, "_capabilities", resp)
+ return getattr(self, "_capabilities")
+
+ def get_value(self, path):
+ params = self.params.copy()
+ for key in path.split("."):
+ params = params[key]
+ return params
+
+ def get_facts(self, subset=None):
+ raise NotImplementedError(self.__class__.__name__)
+
+ def edit_config(self):
+ raise NotImplementedError(self.__class__.__name__)
+
+
+class CliProvider(ProviderBase):
+
+ supported_connections = ("network_cli",)
+
+ @property
+ def capabilities(self):
+ if not hasattr(self, "_capabilities"):
+ resp = self.from_json(self.connection.get_capabilities())
+ setattr(self, "_capabilities", resp)
+ return getattr(self, "_capabilities")
+
+ def get_config_context(self, config, path, indent=1):
+ if config is not None:
+ netcfg = NetworkConfig(indent=indent, contents=config)
+ try:
+ config = netcfg.get_block_config(to_list(path))
+ except ValueError:
+ config = None
+ return config
+
+ def render(self, config=None):
+ raise NotImplementedError(self.__class__.__name__)
+
+ def cli(self, command):
+ try:
+ if not hasattr(self, "_command_output"):
+ setattr(self, "_command_output", {})
+ return self._command_output[command]
+ except KeyError:
+ out = self.connection.get(command)
+ try:
+ out = json.loads(out)
+ except ValueError:
+ pass
+ self._command_output[command] = out
+ return out
+
+ def get_facts(self, subset=None):
+ return self.populate()
+
+ def edit_config(self, config=None):
+ commands = self.render(config)
+ if commands and self.check_mode is False:
+ self.connection.edit_config(commands)
+ return commands
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/rm_templates/acls.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/rm_templates/acls.py
new file mode 100644
index 00000000..c57c5ffd
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/rm_templates/acls.py
@@ -0,0 +1,231 @@
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+import re
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network_template import (
+ NetworkTemplate,
+)
+
+
+def _tmplt_access_list_name(config_data):
+ command = "access-list {acls_name} ".format(**config_data)
+ return command
+
+
+def _tmplt_access_list_entries(config_data):
+ if "aces" in config_data:
+ command = []
+
+ def source_destination_common_config(config_data, cmd, type):
+ if config_data["aces"][type].get("any"):
+ cmd += " any"
+ elif config_data["aces"][type].get("any4"):
+ cmd += " any4"
+ elif config_data["aces"][type].get("any6"):
+ cmd += " any6"
+ elif config_data["aces"][type].get("address"):
+ cmd += " {address}".format(**config_data["aces"][type])
+ if config_data["aces"][type].get("netmask"):
+ cmd += " {netmask}".format(**config_data["aces"][type])
+ elif config_data["aces"][type].get("host"):
+ cmd += " host {host}".format(**config_data["aces"][type])
+ elif config_data["aces"][type].get("interface"):
+ cmd += " interface {interface}".format(
+ **config_data["aces"][type]
+ )
+ elif config_data["aces"][type].get("object_group"):
+ cmd += " object-group {object_group}".format(
+ **config_data["aces"][type]
+ )
+ if config_data["aces"].get("protocol_options"):
+ protocol_option_key = list(
+ config_data["aces"]["protocol_options"]
+ )[0]
+ if (
+ isinstance(
+ config_data["aces"]["protocol_options"][
+ protocol_option_key
+ ],
+ dict,
+ )
+ and type == "destination"
+ ):
+ val = list(
+ config_data["aces"]["protocol_options"][
+ protocol_option_key
+ ]
+ )[0]
+ cmd += " {0}".format(val.replace("_", "-"))
+ if config_data["aces"][type].get("port_protocol"):
+ port_protocol = list(
+ config_data["aces"][type]["port_protocol"]
+ )[0]
+ cmd += (
+ " "
+ + port_protocol
+ + " "
+ + config_data["aces"][type]["port_protocol"][port_protocol]
+ )
+ return cmd
+
+ cmd = ""
+ if config_data["aces"].get("remark"):
+ command.append(
+ "access-list {name} line {line} remark {remark}".format(
+ **config_data["aces"]
+ )
+ )
+ if len(config_data["aces"]) > 4:
+ cmd = "access-list {name} line {line}".format(
+ **config_data["aces"]
+ )
+ if (
+ config_data["aces"].get("acl_type")
+ and config_data["aces"].get("acl_type") != "standard"
+ ):
+ cmd += " {acl_type}".format(**config_data["aces"])
+ if config_data["aces"].get("grant"):
+ cmd += " {grant}".format(**config_data["aces"])
+ if config_data["aces"].get("protocol_options"):
+ if (
+ "protocol_number"
+ in config_data["aces"]["protocol_options"]
+ ):
+ cmd += " {protocol_number}".format(
+ **config_data["aces"]["protocol_options"]
+ )
+ else:
+ cmd += " {0}".format(
+ list(config_data["aces"]["protocol_options"])[0]
+ )
+ elif config_data["aces"].get("protocol"):
+ cmd += " {protocol}".format(**config_data["aces"])
+ if config_data["aces"].get("source"):
+ cmd = source_destination_common_config(
+ config_data, cmd, "source"
+ )
+ if config_data["aces"].get("destination"):
+ cmd = source_destination_common_config(
+ config_data, cmd, "destination"
+ )
+ if config_data["aces"].get("log"):
+ cmd += " log {log}".format(**config_data["aces"])
+ if config_data["aces"].get("inactive"):
+ cmd += " inactive"
+ if config_data["aces"].get("time_range"):
+ cmd += " time-range {time_range}".format(**config_data["aces"])
+ if cmd:
+ command.append(cmd)
+ return command
+
+
+class AclsTemplate(NetworkTemplate):
+ def __init__(self, lines=None):
+ super(AclsTemplate, self).__init__(lines=lines, tmplt=self)
+
+ PARSERS = [
+ {
+ "name": "acls_name",
+ "getval": re.compile(
+ r"""^access-list*
+ \s*(?P<acl_name>\S+);
+ \s*\S+\s*elements;
+ """,
+ re.VERBOSE,
+ ),
+ "setval": _tmplt_access_list_name,
+ "compval": "name",
+ "result": {"acls": {"{{ acl_name }}": {"name": "{{ acl_name }}"}}},
+ "shared": True,
+ },
+ {
+ "name": "aces",
+ "getval": re.compile(
+ r"""^access-list*
+ \s*(?P<acl_name>\S+)*
+ \s*(?P<line>line\s\d+)*
+ \s*(?P<remark>remark\s\S.*)*
+ \s*(?P<ethertype>ethertype)*
+ \s*(?P<webtype>webtype)*
+ \s*(?P<acl_type>extended|standard)*
+ \s*(?P<grant>deny|permit)*
+ \s*(?P<ethertype_params>(dsap\s\S+)|bpdu|eii-ipx|ipx|mpls-unicast|mpls-multicast|isis|any\s)*
+ \s*(?P<std_dest>(host\s\S+)|any4|(?:[0-9]{1,3}\.){3}[0-9]{1,3}\s(?:[0-9]{1,3}\.){3}[0-9]{1,3})*
+ \s*(?P<protocol>ah|eigrp|esp|gre|icmp|icmp6|igmp|igrp|ip|ipinip|ipsec|nos|ospf|pcp|pim|pptp|sctp|snp|tcp|udp)*
+ \s*(?P<protocol_num>\d+\s)*
+ \s*(?P<source>any4|any6|any|(?:[0-9]{1,3}\.){3}[0-9]{1,3}\s(?:[0-9]{1,3}\.){3}[0-9]{1,3}|(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\S+|host\s(?:[0-9]{1,3}\.){3}[0-9]{1,3}|interface\s\S+|object-group\s\S+)*
+ \s*(?P<source_port_protocol>(eq|gts|lt|neq)\s(\S+|\d+))*
+ \s*(?P<destination>any4|any6|any|(?:[0-9]{1,3}\.){3}[0-9]{1,3}\s(?:[0-9]{1,3}\.){3}[0-9]{1,3}|(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\S+|host\s(?:[0-9]{1,3}\.){3}[0-9]{1,3}|interface\s\S+|object-group\s\S+)*
+ \s*(?P<dest_port_protocol>(eq|gts|lt|neq)\s(\S+|\d+))*
+ \s*(?P<icmp_icmp6_protocol>alternate-address|conversion-error|echo|echo-reply|information-reply|information-request|mask-reply|mask-request|membership-query|membership-reduction|membership-report|mobile-redirect|neighbor-advertisement|neighbor-redirect|neighbor-solicitation|parameter-problem|packet-too-big|redirect|router-advertisement|router-renumbering|router-solicitation|source-quench|source-route-failed|time-exceeded|timestamp-reply|timestamp-request|traceroute|unreachable)*
+ \s*(?P<log>log\s\S+)*
+ \s*(?P<time_range>time-range\s\S+)*
+ \s*(?P<inactive>inactive)*
+ """,
+ re.VERBOSE,
+ ),
+ "setval": _tmplt_access_list_entries,
+ "result": {
+ "acls": {
+ "{{ acl_name }}": {
+ "name": "{{ acl_name }}",
+ "acl_type": "{{ acl_type if acl_type is defined }}",
+ "aces": [
+ {
+ "grant": "{{ grant }}",
+ "line": "{{ line.split(' ')[1] if line is defined }}",
+ "remark": "{{ remark.split('remark ')[1] if remark is defined }}",
+ "protocol": "{{ protocol if protocol is defined else None }}",
+ "protocol_number": "{{ protocol_num if protocol_num is defined }}",
+ "icmp_icmp6_protocol": "{{ icmp_icmp6_protocol if icmp_icmp6_protocol is defined else None }}",
+ "source": {
+ "address": "{% if source is defined and '.' in source and 'host'\
+ not in source %}{{ source.split(' ')[0] }}{% elif source is defined and\
+ '::' in source %}{{ source }}{% endif %}",
+ "netmask": "{{ source.split(' ')[1] if source is defined and '.' in source and 'host' not in source else None }}",
+ "any4": "{{ True if source is defined and source == 'any4' else None }}",
+ "any6": "{{ True if source is defined and source == 'any6' else None }}",
+ "any": "{{ True if source is defined and source == 'any' else None }}",
+ "host": "{{ source.split(' ')[1] if source is defined and 'host' in source else None }}",
+ "interface": "{{ source.split(' ')[1] if source is defined and 'interface' in source else None }}",
+ "object_group": "{{ source.split(' ')[1] if source is defined and 'object-group' in source else None }}",
+ "port_protocol": {
+ "{{ source_port_protocol.split(' ')[0] if source_port_protocol\
+ is defined else None }}": "{{ source_port_protocol.split(' ')[1]\
+ if source_port_protocol is defined else None }}"
+ },
+ },
+ "destination": {
+ "address": "{% if destination is defined and\
+ '.' in destination %}{{ destination.split(' ')[0] }}{% elif std_dest is defined and\
+ '.' in std_dest and 'host' not in std_dest %}{{ std_dest.split(' ')[0] }}{% elif destination is defined and\
+ '::' in destination %}{{ destination }}{% endif %}",
+ "netmask": "{% if destination is defined and\
+ '.' in destination %}{{ destination.split(' ')[1] }}{% elif std_dest is defined and\
+ '.' in std_dest and 'host' not in std_dest %}{{ std_dest.split(' ')[1] }}{% endif %}",
+ "any4": "{% if destination is defined and\
+ destination == 'any4' %}{{ True }}{% elif std_dest is defined and std_dest == 'any4' %}{{ True }}{% endif %}",
+ "any6": "{{ True if destination is defined and destination == 'any6' else None }}",
+ "any": "{{ True if destination is defined and destination == 'any' else None }}",
+ "host": "{% if destination is defined and\
+ 'host' in destination %}{{ source_host.split(' ')[1] }}{% elif std_dest is defined and\
+ 'host' in std_dest %}{{ std_dest.split(' ')[1] }}{% endif %}",
+ "interface": "{{ destination.split(' ')[1] if destination is defined and 'interface' in destination else None }}",
+ "object_group": "{{ destination.split(' ')[1] if destination is defined and 'object-group' in destination else None }}",
+ "port_protocol": {
+ "{{ dest_port_protocol.split(' ')[0] if dest_port_protocol\
+ is defined else None }}": "{{ dest_port_protocol.split(' ')[1]\
+ if dest_port_protocol is defined else None }}"
+ },
+ },
+ "inactive": "{{ True if inactive is defined }}",
+ "log": "{{ log.split('log ')[1] if log is defined }}",
+ "time_range": "{{ time_range if time_range is defined }}",
+ }
+ ],
+ }
+ }
+ },
+ },
+ ]
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/rm_templates/ogs.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/rm_templates/ogs.py
new file mode 100644
index 00000000..ed196fdf
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/rm_templates/ogs.py
@@ -0,0 +1,400 @@
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+import re
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network_template import (
+ NetworkTemplate,
+)
+
+
+def _tmplt_object_group(config_data):
+ command = "object-group {object_type} {name}".format(**config_data)
+ return command
+
+
+def _tmplt_icmp_object(config_data):
+ commands = []
+ if config_data.get("icmp_type").get("icmp_object"):
+ for each in config_data.get("icmp_type").get("icmp_object"):
+ commands.append("icmp-object {0}".format(each))
+ return commands
+
+
+def _tmplt_network_object(config_data):
+ commands = []
+ if config_data.get("network_object").get("host"):
+ for each in config_data.get("network_object").get("host"):
+ commands.append("network-object host {0}".format(each))
+ return commands
+
+
+def _tmplt_network_object_address(config_data):
+ commands = []
+ if config_data.get("network_object").get("address"):
+ for each in config_data.get("network_object").get("address"):
+ commands.append("network-object {0}".format(each))
+ return commands
+
+
+def _tmplt_network_object_ipv6(config_data):
+ commands = []
+ if config_data.get("network_object").get("ipv6_address"):
+ for each in config_data.get("network_object").get("ipv6_address"):
+ commands.append("network-object {0}".format(each))
+ return commands
+
+
+def _tmplt_protocol_object(config_data):
+ commands = []
+ if config_data.get("protocol_object").get("protocol"):
+ for each in config_data.get("protocol_object").get("protocol"):
+ commands.append("protocol {0}".format(each))
+ return commands
+
+
+def _tmplt_sec_group_name(config_data):
+ commands = []
+ if config_data.get("security_group").get("sec_name"):
+ for each in config_data.get("security_group").get("sec_name"):
+ commands.append("security-group name {0}".format(each))
+ return commands
+
+
+def _tmplt_sec_group_tag(config_data):
+ commands = []
+ if config_data.get("security_group").get("tag"):
+ for each in config_data.get("security_group").get("tag"):
+ commands.append("security-group tag {0}".format(each))
+ return commands
+
+
+def _tmplt_service_object(config_data):
+ if config_data.get("service_object").get("protocol"):
+ commands = []
+ for each in config_data.get("service_object").get("protocol"):
+ commands.append("service-object {0}".format(each))
+ return commands
+
+
+def _tmplt_user_object_user(config_data):
+ commands = []
+ if config_data.get("user_object").get("user"):
+ for each in config_data.get("user_object").get("user"):
+ commands.append("user {domain}\\{name}".format(**each))
+ return commands
+
+
+def _tmplt_user_object_user_gp(config_data):
+ commands = []
+ if config_data.get("user_object").get("user_group"):
+ for each in config_data.get("user_object").get("user_group"):
+ commands.append("user-group {domain}\\{name} {0}".format(**each))
+ return commands
+
+
+def _tmplt_group_object(config_data):
+ command = "group-object { group_object }".format(**config_data)
+ return command
+
+
+class OGsTemplate(NetworkTemplate):
+ def __init__(self, lines=None):
+ super(OGsTemplate, self).__init__(lines=lines, tmplt=self)
+
+ PARSERS = [
+ {
+ "name": "og_name",
+ "getval": re.compile(
+ r"""
+ ^object-group*
+ \s*(?P<obj_type>\S+)*
+ \s*(?P<obj_name>\S+)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": _tmplt_object_group,
+ "result": {
+ "ogs": {
+ "{{ obj_type }}": {
+ "{{ obj_name }}": {
+ "object_type": "{{ obj_type }}",
+ "name": "{{ obj_name }}",
+ }
+ }
+ }
+ },
+ "shared": True,
+ },
+ {
+ "name": "description",
+ "getval": re.compile(
+ r"""\s+description:*
+ \s*(?P<description>.+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "description {{ description }}",
+ "result": {
+ "ogs": {
+ "{{ obj_type }}": {
+ "{{ obj_name }}": {"description": "{{ description }}"}
+ }
+ }
+ },
+ },
+ {
+ "name": "icmp_type",
+ "getval": re.compile(
+ r"""\s+icmp-object*
+ \s*(?P<object>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": _tmplt_icmp_object,
+ "compval": "icmp_type",
+ "result": {
+ "ogs": {
+ "{{ obj_type }}": {
+ "{{ obj_name }}": {"icmp_object": ["{{ object }}"]}
+ }
+ }
+ },
+ },
+ {
+ "name": "network_object.address",
+ "getval": re.compile(
+ r"""\s+network-object*
+ \s*(?P<address>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\s\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": _tmplt_network_object_address,
+ "compval": "network_object.address",
+ "result": {
+ "ogs": {
+ "{{ obj_type }}": {
+ "{{ obj_name }}": {"address": ["{{ address }}"]}
+ }
+ }
+ },
+ },
+ {
+ "name": "network_object.host",
+ "getval": re.compile(
+ r"""\s+network-object*
+ \s*(?P<host_obj>host)*
+ \s*(?P<host_address>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": _tmplt_network_object,
+ "compval": "network_object.host",
+ "result": {
+ "ogs": {
+ "{{ obj_type }}": {
+ "{{ obj_name }}": {"host": ["{{ host_address }}"]}
+ }
+ }
+ },
+ },
+ {
+ "name": "network_object.ipv6_address",
+ "getval": re.compile(
+ r"""\s+network-object*
+ \s*(?P<ipv6>\S+::/\d+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": _tmplt_network_object_ipv6,
+ "compval": "network_object.ipv6_address",
+ "result": {
+ "ogs": {
+ "{{ obj_type }}": {
+ "{{ obj_name }}": {"ipv6_address": ["{{ ipv6 }}"]}
+ }
+ }
+ },
+ },
+ {
+ "name": "network_object.object",
+ "getval": re.compile(
+ r"""\s+network-object\s
+ object*
+ \s*(?P<object>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "network-object object {{ object }}",
+ "compval": "network_object.object",
+ "result": {
+ "ogs": {
+ "{{ obj_type }}": {
+ "{{ obj_name }}": {"object": "{{ object }}"}
+ }
+ }
+ },
+ },
+ {
+ "name": "protocol_object",
+ "getval": re.compile(
+ r"""\s+protocol-object*
+ \s*(?P<protocol>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": _tmplt_protocol_object,
+ "compval": "protocol_object",
+ "result": {
+ "ogs": {
+ "{{ obj_type }}": {
+ "{{ obj_name }}": {"protocol": ["{{ protocol }}"]}
+ }
+ }
+ },
+ },
+ {
+ "name": "security_group.sec_name",
+ "getval": re.compile(
+ r"""\s+security-group\s
+ name*
+ \s*(?P<name>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": _tmplt_sec_group_name,
+ "compval": "security_group.sec_name",
+ "result": {
+ "ogs": {
+ "{{ obj_type }}": {
+ "{{ obj_name }}": {"sec_name": ["{{ name }}"]}
+ }
+ }
+ },
+ },
+ {
+ "name": "security_group.tag",
+ "getval": re.compile(
+ r"""\s+security-group\s
+ tag*
+ \s*(?P<tag>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": _tmplt_sec_group_tag,
+ "compval": "security_group.tag",
+ "result": {
+ "ogs": {
+ "{{ obj_type }}": {
+ "{{ obj_name }}": {"tag": ["{{ tag }}"]}
+ }
+ }
+ },
+ },
+ {
+ "name": "service_object",
+ "getval": re.compile(
+ r"""\s+service-object*
+ \s*(?P<protocol>\S+)*\s
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": _tmplt_service_object,
+ "compval": "service_object",
+ "result": {
+ "ogs": {
+ "{{ obj_type }}": {
+ "{{ obj_name }}": {"protocol": ["{{ protocol }}"]}
+ }
+ }
+ },
+ },
+ {
+ "name": "service_object.object",
+ "getval": re.compile(
+ r"""\s+service-object\s
+ object*
+ \s*(?P<object>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "service-object object {{ object }}",
+ "result": {
+ "ogs": {
+ "{{ obj_type }}": {
+ "{{ obj_name }}": {"object": "{{ object }}"}
+ }
+ }
+ },
+ },
+ {
+ "name": "user_object.user",
+ "getval": re.compile(
+ r"""\s+user*
+ \s*(?P<domain>\S+)\\
+ (?P<user_name>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": _tmplt_user_object_user,
+ "compval": "user_object",
+ "result": {
+ "ogs": {
+ "{{ obj_type }}": {
+ "{{ obj_name }}": {
+ "user": [
+ {
+ "name": "{{ user_name }}",
+ "domain": "{{ domain }}",
+ }
+ ]
+ }
+ }
+ }
+ },
+ },
+ {
+ "name": "user_object.user_gp",
+ "getval": re.compile(
+ r"""\s+user-group*
+ \s*(?P<domain>\S+)\\
+ (?P<user_gp>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": _tmplt_user_object_user_gp,
+ "compval": "user_object",
+ "result": {
+ "ogs": {
+ "{{ obj_type }}": {
+ "{{ obj_name }}": {
+ "user_group": [
+ {
+ "name": "{{ user_gp }}",
+ "domain": "{{ domain }}",
+ }
+ ]
+ }
+ }
+ }
+ },
+ },
+ {
+ "name": "group_object",
+ "getval": re.compile(
+ r"""\s+group-object*
+ \s*(?P<gp_obj>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": _tmplt_group_object,
+ "compval": "group_object",
+ "result": {
+ "ogs": {
+ "{{ obj_type }}": {
+ "{{ obj_name }}": {"group_object": "{{ gp_obj }}"}
+ }
+ }
+ },
+ },
+ ]
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/utils/__init__.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/utils/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/utils/__init__.py
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/utils/utils.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/utils/utils.py
new file mode 100644
index 00000000..5dd85312
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/module_utils/network/asa/utils/utils.py
@@ -0,0 +1,330 @@
+#
+# -*- coding: utf-8 -*-
+# Copyright 2019 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+# utils
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+import socket
+from ansible.module_utils.six import iteritems
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import (
+ is_masklen,
+ to_netmask,
+)
+
+
+def remove_duplicate_cmd(cmd, commands):
+ # Remove duplicate interface from commands
+ set_cmd = []
+ for each in commands:
+ if cmd in each:
+ if each not in set_cmd:
+ set_cmd.append(each)
+ else:
+ set_cmd.append(each)
+
+ return set_cmd
+
+
+def remove_command_from_config_list(interface, cmd, commands):
+ # To delete the passed config
+ if interface not in commands:
+ commands.insert(0, interface)
+ commands.append("no %s" % cmd)
+ return commands
+
+
+def add_command_to_config_list(interface, cmd, commands):
+ # To set the passed config
+ if interface not in commands:
+ commands.insert(0, interface)
+ commands.append(cmd)
+
+
+def check_n_return_valid_ipv6_addr(module, input_list, filtered_ipv6_list):
+ # To verify the valid ipv6 address
+ try:
+ for each in input_list:
+ if "::" in each:
+ if "/" in each:
+ each = each.split("/")[0]
+ if socket.inet_pton(socket.AF_INET6, each):
+ filtered_ipv6_list.append(each)
+ return filtered_ipv6_list
+ except socket.error:
+ module.fail_json(msg="Incorrect IPV6 address!")
+
+
+def new_dict_to_set(input_dict, temp_list, test_set, count=0):
+ # recursive function to convert input dict to set for comparision
+ test_dict = dict()
+ if isinstance(input_dict, dict):
+ input_dict_len = len(input_dict)
+ for k, v in sorted(iteritems(input_dict)):
+ count += 1
+ if isinstance(v, list):
+ temp_list.append(k)
+ for each in v:
+ if isinstance(each, dict):
+ if [True for i in each.values() if type(i) == list]:
+ new_dict_to_set(each, temp_list, test_set, count)
+ else:
+ new_dict_to_set(each, temp_list, test_set, 0)
+ else:
+ if v is not None:
+ test_dict.update({k: v})
+ try:
+ if (
+ tuple(iteritems(test_dict)) not in test_set
+ and count == input_dict_len
+ ):
+ test_set.add(tuple(iteritems(test_dict)))
+ count = 0
+ except TypeError:
+ temp_dict = {}
+
+ def expand_dict(dict_to_expand):
+ temp = dict()
+ for k, v in iteritems(dict_to_expand):
+ if isinstance(v, dict):
+ expand_dict(v)
+ else:
+ if v is not None:
+ temp.update({k: v})
+ temp_dict.update(tuple(iteritems(temp)))
+
+ new_dict = {k: v}
+ expand_dict(new_dict)
+ if tuple(iteritems(temp_dict)) not in test_set:
+ test_set.add(tuple(iteritems(temp_dict)))
+
+
+def dict_to_set(sample_dict):
+ # Generate a set with passed dictionary for comparison
+ test_dict = dict()
+ if isinstance(sample_dict, dict):
+ for k, v in iteritems(sample_dict):
+ if v is not None:
+ if isinstance(v, list):
+ if isinstance(v[0], dict):
+ li = []
+ for each in v:
+ for key, value in iteritems(each):
+ if isinstance(value, list):
+ each[key] = tuple(value)
+ li.append(tuple(iteritems(each)))
+ v = tuple(li)
+ else:
+ v = tuple(v)
+ elif isinstance(v, dict):
+ li = []
+ for key, value in iteritems(v):
+ if isinstance(value, list):
+ v[key] = tuple(value)
+ li.extend(tuple(iteritems(v)))
+ v = tuple(li)
+ test_dict.update({k: v})
+ return_set = set(tuple(iteritems(test_dict)))
+ else:
+ return_set = set(sample_dict)
+ return return_set
+
+
+def filter_dict_having_none_value(want, have):
+ # Generate dict with have dict value which is None in want dict
+ test_dict = dict()
+ test_key_dict = dict()
+ name = want.get("name")
+ if name:
+ test_dict["name"] = name
+ diff_ip = False
+ want_ip = ""
+ for k, v in iteritems(want):
+ if isinstance(v, dict):
+ for key, value in iteritems(v):
+ if value is None:
+ dict_val = have.get(k).get(key)
+ test_key_dict.update({key: dict_val})
+ test_dict.update({k: test_key_dict})
+ if isinstance(v, list):
+ for key, value in iteritems(v[0]):
+ if value is None:
+ dict_val = have.get(k).get(key)
+ test_key_dict.update({key: dict_val})
+ test_dict.update({k: test_key_dict})
+ # below conditions checks are added to check if
+ # secondary IP is configured, if yes then delete
+ # the already configured IP if want and have IP
+ # is different else if it's same no need to delete
+ for each in v:
+ if each.get("secondary"):
+ want_ip = each.get("address").split("/")
+ have_ip = have.get("ipv4")
+ if (
+ len(want_ip) > 1
+ and have_ip
+ and have_ip[0].get("secondary")
+ ):
+ have_ip = have_ip[0]["address"].split(" ")[0]
+ if have_ip != want_ip[0]:
+ diff_ip = True
+ if each.get("secondary") and diff_ip is True:
+ test_key_dict.update({"secondary": True})
+ test_dict.update({"ipv4": test_key_dict})
+ if v is None:
+ val = have.get(k)
+ test_dict.update({k: val})
+ return test_dict
+
+
+def remove_duplicate_interface(commands):
+ # Remove duplicate interface from commands
+ set_cmd = []
+ for each in commands:
+ if "interface" in each:
+ if each not in set_cmd:
+ set_cmd.append(each)
+ else:
+ set_cmd.append(each)
+
+ return set_cmd
+
+
+def validate_ipv4(value, module):
+ if value:
+ address = value.split("/")
+ if len(address) != 2:
+ module.fail_json(
+ msg="address format is <ipv4 address>/<mask>, got invalid format {0}".format(
+ value
+ )
+ )
+
+ if not is_masklen(address[1]):
+ module.fail_json(
+ msg="invalid value for mask: {0}, mask should be in range 0-32".format(
+ address[1]
+ )
+ )
+
+
+def validate_ipv6(value, module):
+ if value:
+ address = value.split("/")
+ if len(address) != 2:
+ module.fail_json(
+ msg="address format is <ipv6 address>/<mask>, got invalid format {0}".format(
+ value
+ )
+ )
+ else:
+ if not 0 <= int(address[1]) <= 128:
+ module.fail_json(
+ msg="invalid value for mask: {0}, mask should be in range 0-128".format(
+ address[1]
+ )
+ )
+
+
+def validate_n_expand_ipv4(module, want):
+ # Check if input IPV4 is valid IP and expand IPV4 with its subnet mask
+ ip_addr_want = want.get("address")
+ if len(ip_addr_want.split(" ")) > 1:
+ return ip_addr_want
+ validate_ipv4(ip_addr_want, module)
+ ip = ip_addr_want.split("/")
+ if len(ip) == 2:
+ ip_addr_want = "{0} {1}".format(ip[0], to_netmask(ip[1]))
+
+ return ip_addr_want
+
+
+def normalize_interface(name):
+ """Return the normalized interface name
+ """
+ if not name:
+ return
+
+ def _get_number(name):
+ digits = ""
+ for char in name:
+ if char.isdigit() or char in "/.":
+ digits += char
+ return digits
+
+ if name.lower().startswith("gi"):
+ if_type = "GigabitEthernet"
+ elif name.lower().startswith("te"):
+ if_type = "TenGigabitEthernet"
+ elif name.lower().startswith("fa"):
+ if_type = "FastEthernet"
+ elif name.lower().startswith("fo"):
+ if_type = "FortyGigabitEthernet"
+ elif name.lower().startswith("long"):
+ if_type = "LongReachEthernet"
+ elif name.lower().startswith("et"):
+ if_type = "Ethernet"
+ elif name.lower().startswith("vl"):
+ if_type = "Vlan"
+ elif name.lower().startswith("lo"):
+ if_type = "loopback"
+ elif name.lower().startswith("po"):
+ if_type = "Port-channel"
+ elif name.lower().startswith("nv"):
+ if_type = "nve"
+ elif name.lower().startswith("twe"):
+ if_type = "TwentyFiveGigE"
+ elif name.lower().startswith("hu"):
+ if_type = "HundredGigE"
+ else:
+ if_type = None
+
+ number_list = name.split(" ")
+ if len(number_list) == 2:
+ number = number_list[-1].strip()
+ else:
+ number = _get_number(name)
+
+ if if_type:
+ proper_interface = if_type + number
+ else:
+ proper_interface = name
+
+ return proper_interface
+
+
+def get_interface_type(interface):
+ """Gets the type of interface
+ """
+
+ if interface.upper().startswith("GI"):
+ return "GigabitEthernet"
+ elif interface.upper().startswith("TE"):
+ return "TenGigabitEthernet"
+ elif interface.upper().startswith("FA"):
+ return "FastEthernet"
+ elif interface.upper().startswith("FO"):
+ return "FortyGigabitEthernet"
+ elif interface.upper().startswith("LON"):
+ return "LongReachEthernet"
+ elif interface.upper().startswith("ET"):
+ return "Ethernet"
+ elif interface.upper().startswith("VL"):
+ return "Vlan"
+ elif interface.upper().startswith("LO"):
+ return "loopback"
+ elif interface.upper().startswith("PO"):
+ return "Port-channel"
+ elif interface.upper().startswith("NV"):
+ return "nve"
+ elif interface.upper().startswith("TWE"):
+ return "TwentyFiveGigE"
+ elif interface.upper().startswith("HU"):
+ return "HundredGigE"
+ else:
+ return "unknown"
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/modules/__init__.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/modules/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/modules/__init__.py
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/modules/asa_acl.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/modules/asa_acl.py
new file mode 100644
index 00000000..a73bcc4a
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/modules/asa_acl.py
@@ -0,0 +1,235 @@
+#!/usr/bin/python
+#
+# Copyright: Ansible Project
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+
+DOCUMENTATION = """
+module: asa_acl
+author: Patrick Ogenstad (@ogenstad)
+short_description: (deprecated, removed after 2022-06-01) Manage access-lists on a
+ Cisco ASA
+description:
+- This module allows you to work with access-lists on a Cisco ASA device.
+version_added: 1.0.0
+deprecated:
+ alternative: asa_acl
+ why: Newer and updated modules released with more functionality in Ansible 2.10
+ removed_at_date: '2022-06-01'
+extends_documentation_fragment:
+- cisco.asa.asa
+options:
+ lines:
+ description:
+ - The ordered set of commands that should be configured in the section. The commands
+ must be the exact same commands as found in the device running-config. Be sure
+ to note the configuration command syntax as some commands are automatically
+ modified by the device config parser.
+ required: true
+ aliases:
+ - commands
+ type: list
+ elements: str
+ before:
+ description:
+ - The ordered set of commands to push on to the command stack if a change needs
+ to be made. This allows the playbook designer the opportunity to perform configuration
+ commands prior to pushing any changes without affecting how the set of commands
+ are matched against the system.
+ type: list
+ elements: str
+ after:
+ description:
+ - The ordered set of commands to append to the end of the command stack if a changed
+ needs to be made. Just like with I(before) this allows the playbook designer
+ to append a set of commands to be executed after the command set.
+ type: list
+ elements: str
+ match:
+ description:
+ - Instructs the module on the way to perform the matching of the set of commands
+ against the current device config. If match is set to I(line), commands are
+ matched line by line. If match is set to I(strict), command lines are matched
+ with respect to position. Finally if match is set to I(exact), command lines
+ must be an equal match.
+ default: line
+ choices:
+ - line
+ - strict
+ - exact
+ type: str
+ replace:
+ description:
+ - Instructs the module on the way to perform the configuration on the device. If
+ the replace argument is set to I(line) then the modified lines are pushed to
+ the device in configuration mode. If the replace argument is set to I(block)
+ then the entire command block is pushed to the device in configuration mode
+ if any line is not correct.
+ default: line
+ choices:
+ - line
+ - block
+ type: str
+ force:
+ description:
+ - The force argument instructs the module to not consider the current devices
+ running-config. When set to true, this will cause the module to push the contents
+ of I(src) into the device without first checking if already configured.
+ type: bool
+ default: no
+ config:
+ description:
+ - The module, by default, will connect to the remote device and retrieve the current
+ running-config to use as a base for comparing against the contents of source. There
+ are times when it is not desirable to have the task get the current running-config
+ for every task in a playbook. The I(config) argument allows the implementer
+ to pass in the configuration to use as the base config for comparison.
+ type: str
+"""
+
+EXAMPLES = """
+- cisco.asa.asa_acl:
+ lines:
+ - access-list ACL-ANSIBLE extended permit tcp any any eq 82
+ - access-list ACL-ANSIBLE extended permit tcp any any eq www
+ - access-list ACL-ANSIBLE extended permit tcp any any eq 97
+ - access-list ACL-ANSIBLE extended permit tcp any any eq 98
+ - access-list ACL-ANSIBLE extended permit tcp any any eq 99
+ before: clear configure access-list ACL-ANSIBLE
+ match: strict
+ replace: block
+ provider: '{{ cli }}'
+
+- cisco.asa.asa_acl:
+ lines:
+ - access-list ACL-OUTSIDE extended permit tcp any any eq www
+ - access-list ACL-OUTSIDE extended permit tcp any any eq https
+ context: customer_a
+ provider: '{{ cli }}'
+"""
+
+RETURN = """
+updates:
+ description: The set of commands that will be pushed to the remote device
+ returned: always
+ type: list
+ sample: ['access-list ACL-OUTSIDE extended permit tcp any any eq www']
+"""
+from ansible.module_utils.basic import AnsibleModule
+from ansible_collections.cisco.asa.plugins.module_utils.network.asa.asa import (
+ asa_argument_spec,
+)
+from ansible_collections.cisco.asa.plugins.module_utils.network.asa.asa import (
+ get_config,
+ load_config,
+)
+
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.config import (
+ NetworkConfig,
+ dumps,
+)
+
+
+def get_acl_config(module, acl_name):
+ contents = module.params["config"]
+ if not contents:
+ contents = get_config(module)
+
+ filtered_config = list()
+ for item in contents.split("\n"):
+ if item.startswith("access-list %s " % acl_name):
+ filtered_config.append(item)
+
+ return NetworkConfig(indent=1, contents="\n".join(filtered_config))
+
+
+def parse_acl_name(module):
+ first_line = True
+ for line in module.params["lines"]:
+ ace = line.split()
+ if ace[0] != "access-list":
+ module.fail_json(
+ msg='All lines/commands must begin with "access-list" %s is not permitted'
+ % ace[0]
+ )
+ if len(ace) <= 1:
+ module.fail_json(
+ msg="All lines/commands must contain the name of the access-list"
+ )
+ if first_line:
+ acl_name = ace[1]
+ else:
+ if acl_name != ace[1]:
+ module.fail_json(
+ msg="All lines/commands must use the same access-list %s is not %s"
+ % (ace[1], acl_name)
+ )
+ first_line = False
+
+ return acl_name
+
+
+def main():
+
+ argument_spec = dict(
+ lines=dict(
+ aliases=["commands"], required=True, type="list", elements="str"
+ ),
+ before=dict(type="list", elements="str"),
+ after=dict(type="list", elements="str"),
+ match=dict(
+ default="line", choices=["line", "strict", "exact"], type="str"
+ ),
+ replace=dict(default="line", choices=["line", "block"], type="str"),
+ force=dict(default=False, type="bool"),
+ config=dict(type="str"),
+ )
+
+ argument_spec.update(asa_argument_spec)
+
+ module = AnsibleModule(
+ argument_spec=argument_spec, supports_check_mode=True
+ )
+
+ lines = module.params["lines"]
+
+ result = {"changed": False}
+ if len(lines) > 0:
+ candidate = NetworkConfig(indent=1)
+ candidate.add(lines)
+
+ acl_name = parse_acl_name(module)
+
+ if not module.params["force"]:
+ contents = get_acl_config(module, acl_name)
+ config = NetworkConfig(indent=1, contents=contents)
+
+ commands = candidate.difference(config)
+ commands = dumps(commands, "commands").split("\n")
+ commands = [str(c) for c in commands if c]
+ else:
+ commands = str(candidate).split("\n")
+
+ if commands:
+ if module.params["before"]:
+ commands[:0] = module.params["before"]
+
+ if module.params["after"]:
+ commands.extend(module.params["after"])
+
+ if not module.check_mode:
+ load_config(module, commands)
+
+ result["changed"] = True
+
+ result["updates"] = commands
+
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/modules/asa_acls.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/modules/asa_acls.py
new file mode 100644
index 00000000..dfcaf159
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/modules/asa_acls.py
@@ -0,0 +1,1258 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright 2019 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+#############################################
+# WARNING #
+#############################################
+#
+# This file is auto generated by the resource
+# module builder playbook.
+#
+# Do not edit this file manually.
+#
+# Changes to this file will be over written
+# by the resource module builder.
+#
+# Changes should be made in the model used to
+# generate this file or in the resource module
+# builder template.
+#
+#############################################
+
+"""
+The module file for asa_acls
+"""
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+
+DOCUMENTATION = """
+module: asa_acls
+short_description: Access-Lists resource module
+description: This module configures and manages the named or numbered ACLs on ASA
+ platforms.
+version_added: 1.0.0
+author: Sumit Jaiswal (@justjais)
+notes:
+- Tested against Cisco ASA Version 9.10(1)11
+- This module works with connection C(network_cli). See L(ASA Platform Options,../network/user_guide/platform_asa.html).
+options:
+ config:
+ description: A dictionary of ACL options.
+ type: dict
+ suboptions:
+ acls:
+ description:
+ - A list of Access Control Lists (ACL).
+ type: list
+ elements: dict
+ suboptions:
+ name:
+ description: The name or the number of the ACL.
+ required: true
+ type: str
+ acl_type:
+ description:
+ - ACL type
+ type: str
+ choices:
+ - extended
+ - standard
+ rename:
+ description:
+ - Rename an existing access-list.
+ - If input to rename param is given, it'll take preference over other
+ parameters and only rename config will be matched and computed against.
+ type: str
+ aces:
+ description: The entries within the ACL.
+ elements: dict
+ type: list
+ suboptions:
+ grant:
+ description: Specify the action.
+ type: str
+ choices:
+ - permit
+ - deny
+ line:
+ description:
+ - Use this to specify line number at which ACE should be entered.
+ - Existing ACE can be updated based on the input line number.
+ - It's not a required param in case of configuring the acl, but in
+ case of Delete operation it's required, else Delete operation won't
+ work as expected.
+ - Refer to vendor documentation for valid values.
+ type: int
+ remark:
+ description:
+ - Specify a comment (remark) for the access-list after this keyword
+ type: str
+ protocol:
+ description:
+ - Specify the protocol to match.
+ - Refer to vendor documentation for valid values.
+ type: str
+ protocol_options:
+ description: protocol type.
+ type: dict
+ suboptions:
+ protocol_number:
+ description: An IP protocol number
+ type: int
+ ahp:
+ description: Authentication Header Protocol.
+ type: bool
+ eigrp:
+ description: Cisco's EIGRP routing protocol.
+ type: bool
+ esp:
+ description: Encapsulation Security Payload.
+ type: bool
+ gre:
+ description: Cisco's GRE tunneling.
+ type: bool
+ icmp:
+ description: Internet Control Message Protocol.
+ type: dict
+ suboptions:
+ alternate_address:
+ description: Alternate address
+ type: bool
+ conversion_error:
+ description: Datagram conversion
+ type: bool
+ echo:
+ description: Echo (ping)
+ type: bool
+ echo_reply:
+ description: Echo reply
+ type: bool
+ information_reply:
+ description: Information replies
+ type: bool
+ information_request:
+ description: Information requests
+ type: bool
+ mask_reply:
+ description: Mask replies
+ type: bool
+ mask_request:
+ description: mask_request
+ type: bool
+ mobile_redirect:
+ description: Mobile host redirect
+ type: bool
+ parameter_problem:
+ description: All parameter problems
+ type: bool
+ redirect:
+ description: All redirects
+ type: bool
+ router_advertisement:
+ description: Router discovery advertisements
+ type: bool
+ router_solicitation:
+ description: Router discovery solicitations
+ type: bool
+ source_quench:
+ description: Source quenches
+ type: bool
+ source_route_failed:
+ description: Source route
+ type: bool
+ time_exceeded:
+ description: All time exceededs
+ type: bool
+ timestamp_reply:
+ description: Timestamp replies
+ type: bool
+ timestamp_request:
+ description: Timestamp requests
+ type: bool
+ traceroute:
+ description: Traceroute
+ type: bool
+ unreachable:
+ description: All unreachables
+ type: bool
+ icmp6:
+ description: Internet Control Message Protocol.
+ type: dict
+ suboptions:
+ echo:
+ description: Echo (ping)
+ type: bool
+ echo_reply:
+ description: Echo reply
+ type: bool
+ membership_query:
+ description: Membership query
+ type: bool
+ membership_reduction:
+ description: Membership reduction
+ type: bool
+ membership_report:
+ description: Membership report
+ type: bool
+ neighbor_advertisement:
+ description: Neighbor advertisement
+ type: bool
+ neighbor_redirect:
+ description: Neighbor redirect
+ type: bool
+ neighbor_solicitation:
+ description: Neighbor_solicitation
+ type: bool
+ packet_too_big:
+ description: Packet too big
+ type: bool
+ parameter_problem:
+ description: Parameter problem
+ type: bool
+ router_advertisement:
+ description: Router discovery advertisements
+ type: bool
+ router_renumbering:
+ description: Router renumbering
+ type: bool
+ router_solicitation:
+ description: Router solicitation
+ type: bool
+ time_exceeded:
+ description: Time exceeded
+ type: bool
+ unreachable:
+ description: All unreachables
+ type: bool
+ igmp:
+ description: Internet Gateway Message Protocol.
+ type: bool
+ igrp:
+ description: Internet Gateway Routing Protocol.
+ type: bool
+ ip:
+ description: Any Internet Protocol.
+ type: bool
+ ipinip:
+ description: IP in IP tunneling.
+ type: bool
+ ipsec:
+ description: IP Security.
+ type: bool
+ nos:
+ description: KA9Q NOS compatible IP over IP tunneling.
+ type: bool
+ ospf:
+ description: OSPF routing protocol.
+ type: bool
+ pcp:
+ description: Payload Compression Protocol.
+ type: bool
+ pim:
+ description: Protocol Independent Multicast.
+ type: bool
+ pptp:
+ description: Point-to-Point Tunneling Protocol.
+ type: bool
+ sctp:
+ description: Stream Control Transmission Protocol.
+ type: bool
+ snp:
+ description: Simple Network Protocol.
+ type: bool
+ udp:
+ description: User Datagram Protocol.
+ type: bool
+ tcp:
+ description: Match TCP packet flags
+ type: bool
+ source:
+ description: Specify the packet source.
+ type: dict
+ suboptions:
+ address:
+ description: Source network address.
+ type: str
+ netmask:
+ description: Netmask for source IP address, valid with IPV4 address.
+ type: str
+ any:
+ description:
+ - Match any source address.
+ type: bool
+ any4:
+ description:
+ - Match any ipv4 source address.
+ type: bool
+ any6:
+ description:
+ - Match any ipv6 source address.
+ type: bool
+ host:
+ description: A single source host
+ type: str
+ interface:
+ description: Use interface address as source address
+ type: str
+ object_group:
+ description: Network object-group for source address
+ type: str
+ port_protocol:
+ description:
+ - Specify the destination port along with protocol.
+ - Note, Valid with TCP/UDP protocol_options
+ type: dict
+ suboptions:
+ eq:
+ description: Match only packets on a given port number.
+ type: str
+ gt:
+ description: Match only packets with a greater port number.
+ type: str
+ lt:
+ description: Match only packets with a lower port number.
+ type: str
+ neq:
+ description: Match only packets not on a given port number.
+ type: str
+ range:
+ description: Port range operator
+ type: dict
+ suboptions:
+ start:
+ description: Specify the start of the port range.
+ type: int
+ end:
+ description: Specify the end of the port range.
+ type: int
+ destination:
+ description: Specify the packet destination.
+ type: dict
+ suboptions:
+ address:
+ description: Host address to match, or any single host address.
+ type: str
+ netmask:
+ description: Netmask for destination IP address, valid with IPV4
+ address.
+ type: str
+ any:
+ description: Match any destination address.
+ type: bool
+ any4:
+ description:
+ - Match any ipv4 destination address.
+ type: bool
+ any6:
+ description:
+ - Match any ipv6 destination address.
+ type: bool
+ host:
+ description: A single destination host
+ type: str
+ interface:
+ description: Use interface address as destination address
+ type: str
+ object_group:
+ description: Network object-group for destination address
+ type: str
+ port_protocol:
+ description:
+ - Specify the destination port along with protocol.
+ - Note, Valid with TCP/UDP protocol_options
+ type: dict
+ suboptions:
+ eq:
+ description: Match only packets on a given port number.
+ type: str
+ gt:
+ description: Match only packets with a greater port number.
+ type: str
+ lt:
+ description: Match only packets with a lower port number.
+ type: str
+ neq:
+ description: Match only packets not on a given port number.
+ type: str
+ range:
+ description: Port range operator
+ type: dict
+ suboptions:
+ start:
+ description: Specify the start of the port range.
+ type: int
+ end:
+ description: Specify the end of the port range.
+ type: int
+ inactive:
+ description: Keyword for disabling an ACL element.
+ type: bool
+ log:
+ description: Log matches against this entry.
+ type: str
+ choices:
+ - default
+ - alerts
+ - critical
+ - debugging
+ - disable
+ - emergencies
+ - errors
+ - informational
+ - interval
+ - notifications
+ - warnings
+ time_range:
+ description: Specify a time-range.
+ type: str
+ running_config:
+ description:
+ - The module, by default, will connect to the remote device and retrieve the current
+ running-config to use as a base for comparing against the contents of source.
+ There are times when it is not desirable to have the task get the current running-config
+ for every task in a playbook. The I(running_config) argument allows the implementer
+ to pass in the configuration to use as the base config for comparison.
+ type: str
+ state:
+ choices:
+ - merged
+ - replaced
+ - overridden
+ - deleted
+ - gathered
+ - rendered
+ - parsed
+ default: merged
+ description:
+ - The state of the configuration after module completion
+ type: str
+
+"""
+
+EXAMPLES = """
+# Using merged
+# Before state:
+# -------------
+#
+# vasa#sh access-lists
+# access-list global_access; 2 elements; name hash: 0xbd6c87a7
+# access-list global_access line 1 extended permit icmp any any log disable (hitcnt=0) 0xf1efa630
+# access-list global_access line 2 extended deny tcp any any eq telnet (hitcnt=0) 0xae5833af
+# access-list R1_traffic; 1 elements; name hash: 0xaf40d3c2
+# access-list R1_traffic line 1
+# extended deny tcp 2001:db8:0:3::/64 eq telnet 2001:fc8:0:4::/64 eq www
+# log errors interval 300 (hitcnt=0) 0x4a4660f3
+
+- name: Merge provided configuration with device configuration
+ cisco.asa.asa_acls:
+ config:
+ acls:
+ - name: temp_access
+ acl_type: extended
+ aces:
+ - grant: deny
+ line: 1
+ protocol_options:
+ tcp: true
+ source:
+ address: 192.0.2.0
+ netmask: 255.255.255.0
+ destination:
+ address: 192.0.3.0
+ netmask: 255.255.255.0
+ port_protocol:
+ eq: www
+ log: default
+ - grant: deny
+ line: 2
+ protocol_options:
+ igrp: true
+ source:
+ address: 198.51.100.0
+ netmask: 255.255.255.0
+ destination:
+ address: 198.51.110.0
+ netmask: 255.255.255.0
+ time_range: temp
+ - grant: deny
+ line: 3
+ protocol_options:
+ tcp: true
+ source:
+ interface: management
+ destination:
+ interface: management
+ port_protocol:
+ eq: www
+ log: warnings
+ - grant: deny
+ line: 4
+ protocol_options:
+ tcp: true
+ source:
+ object_group: test_og_network
+ destination:
+ object_group: test_network_og
+ port_protocol:
+ eq: www
+ log: default
+ - name: global_access
+ acl_type: extended
+ aces:
+ - line: 3
+ remark: test global access
+ - grant: deny
+ line: 4
+ protocol_options:
+ tcp: true
+ source:
+ any: true
+ destination:
+ any: true
+ port_protocol:
+ eq: www
+ log: errors
+ - name: R1_traffic
+ aces:
+ - line: 1
+ remark: test_v6_acls
+ - grant: deny
+ line: 2
+ protocol_options:
+ tcp: true
+ source:
+ address: 2001:db8:0:3::/64
+ port_protocol:
+ eq: www
+ destination:
+ address: 2001:fc8:0:4::/64
+ port_protocol:
+ eq: telnet
+ inactive: true
+ state: merged
+
+# Commands fired:
+# ---------------
+# access-list global_access line 3 remark test global access
+# access-list global_access line 4 extended deny tcp any any eq www log errors interval 300
+# access-list R1_traffic line 1 remark test_v6_acls
+# access-list R1_traffic line 2 extended deny tcp 2001:db8:0:3::/64 eq www 2001:fc8:0:4::/64 eq telnet inactive
+# access-list temp_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 temp_access line 2 extended deny igrp 198.51.100.0 255.255.255.0 198.51.110.0 255.255.255.0
+# time-range temp inactive
+# access-list temp_access line 2 extended deny tcp interface management interface management
+# eq www log warnings
+# access-list test_access line 3 extended deny tcp object-group test_og_network object-group test_network_og
+# eq www log default
+
+# After state:
+# ------------
+#
+# vasa#sh access-lists
+# access-list global_access; 3 elements; name hash: 0xbd6c87a7
+# access-list global_access line 1 extended permit icmp any any log disable (hitcnt=0) 0xf1efa630
+# access-list global_access line 2 extended deny tcp any any eq telnet (hitcnt=0) 0xae5833af
+# access-list global_access line 3 remark test global access (hitcnt=0) 0xae78337e
+# access-list global_access line 4 extended deny tcp any any eq www log errors interval 300 (hitcnt=0) 0x605f2421
+# access-list R1_traffic; 2 elements; name hash: 0xaf40d3c2
+# access-list R1_traffic line 1 remark test_v6_acls
+# access-list R1_traffic line 2
+# extended deny tcp 2001:db8:0:3::/64 eq www 2001:fc8:0:4::/64 eq telnet
+# inactive (hitcnt=0) (inactive) 0xe922b432
+# access-list temp_access; 2 elements; name hash: 0xaf1b712e
+# access-list temp_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) 0xb58abb0d
+# access-list temp_access line 2
+# extended deny igrp 198.51.100.0 255.255.255.0 198.51.110.0 255.255.255.0
+# time-range temp (hitcnt=0) (inactive) 0xcd6b92ae
+# access-list test_access line 3
+# extended deny tcp interface management interface management eq www log warnings
+# interval 300 (hitcnt=0) 0x78aa233d
+# access-list test_access line 2 extended deny tcp object-group test_og_network object-group test_network_og
+# eq www log default (hitcnt=0) 0x477aec1e
+# access-list test_access line 2 extended deny tcp 192.0.2.0 255.255.255.0 host 192.0.3.1 eq www
+# log default (hitcnt=0) 0xdc7edff8
+# access-list test_access line 2 extended deny tcp 192.0.2.0 255.255.255.0 host 192.0.3.2 eq www
+# log default (hitcnt=0) 0x7b0e9fde
+# access-list test_access line 2 extended deny tcp 198.51.100.0 255.255.255.0 2001:db8:3::/64 eq www
+# log default (hitcnt=0) 0x97c75adc
+
+# Using Merged to Rename ACLs
+# Before state:
+# -------------
+#
+# vasa#sh access-lists
+# access-list global_access; 2 elements; name hash: 0xbd6c87a7
+# access-list global_access line 1 extended permit icmp any any log disable (hitcnt=0) 0xf1efa630
+# access-list global_access line 2 extended deny tcp any any eq telnet (hitcnt=0) 0xae5833af
+# access-list R1_traffic; 1 elements; name hash: 0xaf40d3c2
+# access-list R1_traffic line 1
+# extended deny tcp 2001:db8:0:3::/64 eq telnet 2001:fc8:0:4::/64 eq www
+# log errors interval 300 (hitcnt=0) 0x4a4660f3
+
+- name: Rename ACL with different name using Merged state
+ cisco.asa.asa_acls:
+ config:
+ acls:
+ - name: global_access
+ rename: global_access_renamed
+ - name: R1_traffic
+ rename: R1_traffic_renamed
+ state: merged
+
+# Commands fired:
+# ---------------
+# access-list global_access rename global_access_renamed
+# access-list R1_traffic rename R1_traffic_renamed
+
+# After state:
+# -------------
+#
+# vasa#sh access-lists
+# access-list global_access_renamed; 2 elements; name hash: 0xbd6c87a7
+# access-list global_access_renamed line 1 extended permit icmp any any log disable (hitcnt=0) 0xf1efa630
+# access-list global_access_renamed line 2 extended deny tcp any any eq telnet (hitcnt=0) 0xae5833af
+# access-list R1_traffic_renamed; 1 elements; name hash: 0xaf40d3c2
+# access-list R1_traffic_renamed line 1
+# extended deny tcp 2001:db8:0:3::/64 eq telnet 2001:fc8:0:4::/64 eq www
+# log errors interval 300 (hitcnt=0) 0x4a4660f3
+
+
+# Using replaced
+
+# Before state:
+# -------------
+#
+# vasa#sh access-lists
+# access-list global_access; 3 elements; name hash: 0xbd6c87a7
+# access-list global_access line 1 extended permit icmp any any log disable (hitcnt=0) 0xf1efa630
+# access-list global_access line 2 extended deny tcp any any eq telnet (hitcnt=0) 0xae5833af
+# access-list global_access line 3 extended deny tcp any any eq www log errors interval 300 (hitcnt=0) 0x605f2421
+# access-list R1_traffic; 2 elements; name hash: 0xaf40d3c2
+# access-list R1_traffic line 1
+# extended deny tcp 2001:db8:0:3::/64 eq telnet 2001:fc8:0:4::/64 eq www
+# log errors interval 300 (hitcnt=0) 0x4a4660f3
+# access-list R1_traffic line 2
+# extended deny tcp 2001:db8:0:3::/64 eq www 2001:fc8:0:4::/64 eq telnet
+# inactive (hitcnt=0) (inactive) 0xe922b432
+# access-list temp_access; 2 elements; name hash: 0xaf1b712e
+# access-list temp_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) 0xb58abb0d
+# access-list temp_access line 2
+# extended deny igrp 198.51.100.0 255.255.255.0 198.51.110.0 255.255.255.0
+# time-range temp (hitcnt=0) (inactive) 0xcd6b92ae
+
+- name: Replaces device configuration of listed acl with provided configuration
+ cisco.asa.asa_acls:
+ config:
+ acls:
+ - name: global_access
+ acl_type: extended
+ aces:
+ - grant: deny
+ line: 1
+ protocol_options:
+ tcp: true
+ source:
+ address: 192.0.4.0
+ netmask: 255.255.255.0
+ port_protocol:
+ eq: telnet
+ destination:
+ address: 192.0.5.0
+ netmask: 255.255.255.0
+ port_protocol:
+ eq: www
+ state: replaced
+
+# Commands fired:
+# ---------------
+# no access-list global_access line 3 extended deny tcp any any eq www log errors interval 300
+# no access-list global_access line 2 extended deny tcp any any eq telnet
+# no access-list global_access line 1 extended permit icmp any any log disable
+# access-list global_access line 1 extended deny tcp 192.0.4.0 255.255.255.0 eq telnet 192.0.5.0 255.255.255.0 eq www
+
+# After state:
+# -------------
+#
+# vasa#sh access-lists
+# access-list global_access; 1 elements; name hash: 0xbd6c87a7
+# access-list global_access line 1 extended deny tcp 192.0.4.0 255.255.255.0 eq telnet
+# 192.0.5.0 255.255.255.0 eq www (hitcnt=0) 0x3e5b2757
+# access-list R1_traffic; 2 elements; name hash: 0xaf40d3c2
+# access-list R1_traffic line 1
+# extended deny tcp 2001:db8:0:3::/64 eq telnet 2001:fc8:0:4::/64 eq www
+# log errors interval 300 (hitcnt=0) 0x4a4660f3
+# access-list R1_traffic line 2
+# extended deny tcp 2001:db8:0:3::/64 eq www 2001:fc8:0:4::/64 eq telnet
+# inactive (hitcnt=0) (inactive) 0xe922b432
+# access-list temp_access; 2 elements; name hash: 0xaf1b712e
+# access-list temp_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) 0xb58abb0d
+# access-list temp_access line 2
+# extended deny igrp 198.51.100.0 255.255.255.0 198.51.110.0 255.255.255.0
+# time-range temp (hitcnt=0) (inactive) 0xcd6b92ae
+
+# Using overridden
+
+# Before state:
+# -------------
+#
+# vasa#sh access-lists
+# access-list global_access; 3 elements; name hash: 0xbd6c87a7
+# access-list global_access line 1 extended permit icmp any any log disable (hitcnt=0) 0xf1efa630
+# access-list global_access line 2 extended deny tcp any any eq telnet (hitcnt=0) 0xae5833af
+# access-list global_access line 3 extended deny tcp any any eq www log errors interval 300 (hitcnt=0) 0x605f2421
+# access-list R1_traffic; 2 elements; name hash: 0xaf40d3c2
+# access-list R1_traffic line 1
+# extended deny tcp 2001:db8:0:3::/64 eq telnet 2001:fc8:0:4::/64 eq www
+# log errors interval 300 (hitcnt=0) 0x4a4660f3
+# access-list R1_traffic line 2
+# extended deny tcp 2001:db8:0:3::/64 eq www 2001:fc8:0:4::/64 eq telnet
+# inactive (hitcnt=0) (inactive) 0xe922b432
+# access-list temp_access; 2 elements; name hash: 0xaf1b712e
+# access-list temp_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) 0xb58abb0d
+# access-list temp_access line 2
+# extended deny igrp 198.51.100.0 255.255.255.0 198.51.110.0 255.255.255.0
+# time-range temp (hitcnt=0) (inactive) 0xcd6b92ae
+
+
+- name: Override device configuration of all acl with provided configuration
+ cisco.asa.asa_acls:
+ config:
+ acls:
+ - name: global_access
+ acl_type: extended
+ aces:
+ - grant: deny
+ line: 1
+ protocol_options:
+ tcp: true
+ source:
+ address: 192.0.4.0
+ netmask: 255.255.255.0
+ port_protocol:
+ eq: telnet
+ destination:
+ address: 192.0.5.0
+ netmask: 255.255.255.0
+ port_protocol:
+ eq: www
+ state: overridden
+
+# Commands fired:
+# ---------------
+# access-list temp_access line 2
+# extended deny igrp 198.51.100.0 255.255.255.0 198.51.110.0 255.255.255.0 time-range temp
+# no access-list temp_access line 1
+# extended grant 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 R1_traffic line 2
+# extended grant deny tcp 2001:db8:0:3::/64 eq www 2001:fc8:0:4::/64 eq telnet inactive
+# no access-list R1_traffic line 1
+# extended grant deny tcp 2001:db8:0:3::/64 eq telnet 2001:fc8:0:4::/64 eq www log errors
+# no access-list global_access line 3 extended grant deny tcp any any eq www log errors
+# no access-list global_access line 2 extended grant deny tcp any any eq telnet
+# no access-list global_access line 1 extended grant permit icmp any any log disable
+# access-list global_access line 4 extended deny tcp 192.0.4.0 255.255.255.0 eq telnet 192.0.5.0 255.255.255.0 eq www
+
+# After state:
+# -------------
+#
+# vasa#sh access-lists
+# access-list global_access; 1 elements; name hash: 0xbd6c87a7
+# access-list global_access line 1 extended permit icmp any any log disable (hitcnt=0) 0xf1efa630
+
+# Using Deleted
+
+# Before state:
+# -------------
+#
+# vasa#sh access-lists
+# access-list global_access; 3 elements; name hash: 0xbd6c87a7
+# access-list global_access line 1 extended permit icmp any any log disable (hitcnt=0) 0xf1efa630
+# access-list global_access line 2 extended deny tcp any any eq telnet (hitcnt=0) 0xae5833af
+# access-list global_access line 3 extended deny tcp any any eq www log errors interval 300 (hitcnt=0) 0x605f2421
+# access-list R1_traffic; 2 elements; name hash: 0xaf40d3c2
+# access-list R1_traffic line 1
+# extended deny tcp 2001:db8:0:3::/64 eq telnet 2001:fc8:0:4::/64 eq www
+# log errors interval 300 (hitcnt=0) 0x4a4660f3
+# access-list R1_traffic line 2
+# extended deny tcp 2001:db8:0:3::/64 eq www 2001:fc8:0:4::/64 eq telnet
+# inactive (hitcnt=0) (inactive) 0xe922b432
+# access-list temp_access; 2 elements; name hash: 0xaf1b712e
+# access-list temp_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) 0xb58abb0d
+# access-list temp_access line 2
+# extended deny igrp 198.51.100.0 255.255.255.0 198.51.110.0 255.255.255.0
+# time-range temp (hitcnt=0) (inactive) 0xcd6b92ae
+
+- name: "Delete module attributes of given acl (Note: This won't delete ALL of the ACLs configured)"
+ cisco.asa.asa_acls:
+ config:
+ acls:
+ - name: temp_access
+ - name: global_access
+ state: deleted
+
+# Commands fired:
+# ---------------
+# no access-list temp_access line 2 extended deny igrp 198.51.100.0 255.255.255.0 198.51.110.0 255.255.255.0
+# time-range temp inactive
+# no access-list temp_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 global_access line 3 extended deny tcp any any eq www log errors interval 300
+# no access-list global_access line 2 extended deny tcp any any eq telnet
+# no access-list global_access line 1 extended permit icmp any any log disable
+
+# After state:
+# -------------
+#
+# vasa#sh access-lists
+# access-list R1_traffic; 2 elements; name hash: 0xaf40d3c2
+# access-list R1_traffic line 1
+# extended deny tcp 2001:db8:0:3::/64 eq telnet 2001:fc8:0:4::/64 eq www
+# log errors interval 300 (hitcnt=0) 0x4a4660f3
+# access-list R1_traffic line 2
+# extended deny tcp 2001:db8:0:3::/64 eq www 2001:fc8:0:4::/64 eq telnet
+# inactive (hitcnt=0) (inactive) 0xe922b432
+
+# Using Deleted without any config passed
+#"(NOTE: This will delete all of configured resource module attributes)"
+
+# Before state:
+# -------------
+#
+# vasa#sh access-lists
+# access-list global_access; 3 elements; name hash: 0xbd6c87a7
+# access-list global_access line 1 extended permit icmp any any log disable (hitcnt=0) 0xf1efa630
+# access-list global_access line 2 extended deny tcp any any eq telnet (hitcnt=0) 0xae5833af
+# access-list global_access line 3 extended deny tcp any any eq www log errors interval 300 (hitcnt=0) 0x605f2421
+# access-list R1_traffic; 2 elements; name hash: 0xaf40d3c2
+# access-list R1_traffic line 1
+# extended deny tcp 2001:db8:0:3::/64 eq telnet 2001:fc8:0:4::/64 eq www
+# log errors interval 300 (hitcnt=0) 0x4a4660f3
+# access-list R1_traffic line 2
+# extended deny tcp 2001:db8:0:3::/64 eq www 2001:fc8:0:4::/64 eq telnet
+# inactive (hitcnt=0) (inactive) 0xe922b432
+# access-list temp_access; 2 elements; name hash: 0xaf1b712e
+# access-list temp_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) 0xb58abb0d
+# access-list temp_access line 2
+# extended deny igrp 198.51.100.0 255.255.255.0 198.51.110.0 255.255.255.0
+# time-range temp (hitcnt=0) (inactive) 0xcd6b92ae
+
+- name: 'Delete ALL ACLs in one go (Note: This WILL delete the ALL of configured ACLs)'
+ cisco.asa.asa_acls:
+ state: deleted
+
+# Commands fired:
+# ---------------
+# no access-list global_access line 1 extended permit icmp any any log disable
+# no access-list global_access line 2 extended deny tcp any any eq telnet
+# no access-list global_access line 3 extended deny tcp any any eq www log errors interval 300
+# no access-list R1_traffic line 1 extended deny tcp 2001:db8:0:3::/64 eq telnet 2001:fc8:0:4::/64 eq www
+# log errors interval 300
+# no access-list R1_traffic line 2 extended deny tcp 2001:db8:0:3::/64 eq www 2001:fc8:0:4::/64 eq telnet inactive
+# no access-list temp_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 temp_access line 2 extended deny igrp 198.51.100.0 255.255.255.0 198.51.110.0 255.255.255.0
+# time-range temp inactive
+
+
+# After state:
+# -------------
+#
+# vasa#sh access-lists
+
+# Using Gathered
+
+# Before state:
+# -------------
+#
+# access-list global_access; 3 elements; name hash: 0xbd6c87a7
+# access-list global_access line 1 extended permit icmp any any log disable (hitcnt=0) 0xf1efa630
+# access-list global_access line 2 extended deny tcp any any eq telnet (hitcnt=0) 0xae5833af
+# access-list R1_traffic; 2 elements; name hash: 0xaf40d3c2
+# access-list R1_traffic line 1
+# extended deny tcp 2001:db8:0:3::/64 eq telnet 2001:fc8:0:4::/64 eq www
+# log errors interval 300 (hitcnt=0) 0x4a4660f3
+# access-list R1_traffic line 2
+# extended deny tcp 2001:db8:0:3::/64 eq www 2001:fc8:0:4::/64 eq telnet
+# inactive (hitcnt=0) (inactive) 0xe922b432
+# access-list temp_access; 2 elements; name hash: 0xaf1b712e
+# access-list temp_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) 0xb58abb0d
+# access-list temp_access line 2
+# extended deny igrp 198.51.100.0 255.255.255.0 198.51.110.0 255.255.255.0
+# time-range temp (hitcnt=0) (inactive) 0xcd6b92ae
+
+
+- name: Gather listed ACLs with provided configurations
+ cisco.asa.asa_acls:
+ config:
+ state: gathered
+
+# Module Execution Result:
+# ------------------------
+#
+# "gathered": [
+# {
+# "acls": [
+# {
+# "aces": [
+# {
+# "destination": {
+# "any": true
+# },
+# "grant": "permit",
+# "line": 1,
+# "log": "disable",
+# "protocol": "icmp",
+# "source": {
+# "any": true
+# }
+# },
+# {
+# "destination": {
+# "any": true,
+# "port_protocol": {
+# "eq": "telnet"
+# }
+# },
+# "grant": "deny",
+# "line": 2,
+# "protocol": "tcp",
+# "protocol_options": {
+# "tcp": true
+# },
+# "source": {
+# "any": true
+# }
+# }
+# ],
+# "acl_type": "extended",
+# "name": "global_access"
+# },
+# {
+# "aces": [
+# {
+# "destination": {
+# "address": "2001:fc8:0:4::/64",
+# "port_protocol": {
+# "eq": "www"
+# }
+# },
+# "grant": "deny",
+# "line": 1,
+# "log": "errors",
+# "protocol": "tcp",
+# "protocol_options": {
+# "tcp": true
+# },
+# "source": {
+# "address": "2001:db8:0:3::/64",
+# "port_protocol": {
+# "eq": "telnet"
+# }
+# }
+# },
+# {
+# "destination": {
+# "address": "2001:fc8:0:4::/64",
+# "port_protocol": {
+# "eq": "telnet"
+# }
+# },
+# "grant": "deny",
+# "inactive": true,
+# "line": 2,
+# "protocol": "tcp",
+# "protocol_options": {
+# "tcp": true
+# },
+# "source": {
+# "address": "2001:db8:0:3::/64",
+# "port_protocol": {
+# "eq": "www"
+# }
+# }
+# }
+# ],
+# "acl_type": "extended",
+# "name": "R1_traffic"
+# },
+# {
+# "aces": [
+# {
+# "destination": {
+# "address": "192.0.3.0",
+# "netmask": "255.255.255.0",
+# "port_protocol": {
+# "eq": "www"
+# }
+# },
+# "grant": "deny",
+# "line": 1,
+# "log": "default",
+# "protocol": "tcp",
+# "protocol_options": {
+# "tcp": true
+# },
+# "source": {
+# "address": "192.0.2.0",
+# "netmask": "255.255.255.0"
+# }
+# },
+# {
+# "destination": {
+# "address": "198.51.110.0",
+# "netmask": "255.255.255.0"
+# },
+# "grant": "deny",
+# "inactive": true,
+# "line": 2,
+# "protocol": "igrp",
+# "protocol_options": {
+# "igrp": true
+# },
+# "source": {
+# "address": "198.51.100.0",
+# "netmask": "255.255.255.0"
+# },
+# "time_range": "temp"
+# }
+# ],
+# "acl_type": "extended",
+# "name": "temp_access"
+# }
+# ]
+# }
+# ]
+
+# Using Rendered
+
+- name: Rendered the provided configuration with the exisiting running configuration
+ cisco.asa.asa_acls:
+ config:
+ acls:
+ - name: temp_access
+ acl_type: extended
+ aces:
+ - grant: deny
+ line: 1
+ protocol_options:
+ tcp: true
+ source:
+ address: 192.0.2.0
+ netmask: 255.255.255.0
+ destination:
+ address: 192.0.3.0
+ netmask: 255.255.255.0
+ port_protocol:
+ eq: www
+ log: default
+ - grant: deny
+ line: 2
+ protocol_options:
+ igrp: true
+ source:
+ address: 198.51.100.0
+ netmask: 255.255.255.0
+ destination:
+ address: 198.51.110.0
+ netmask: 255.255.255.0
+ time_range: temp
+ - name: R1_traffic
+ aces:
+ - grant: deny
+ protocol_options:
+ tcp: true
+ source:
+ address: 2001:db8:0:3::/64
+ port_protocol:
+ eq: www
+ destination:
+ address: 2001:fc8:0:4::/64
+ port_protocol:
+ eq: telnet
+ inactive: true
+ state: rendered
+
+# Module Execution Result:
+# ------------------------
+#
+# "rendered": [
+# "access-list temp_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 temp_access line 2
+# extended deny igrp 198.51.100.0 255.255.255.0 198.51.110.0 255.255.255.0
+# time-range temp"
+# "access-list R1_traffic
+# deny tcp 2001:db8:0:3::/64 eq www 2001:fc8:0:4::/64 eq telnet inactive"
+# ]
+
+# Using Parsed
+
+# parsed.cfg
+#
+# access-list test_access; 2 elements; name hash: 0xaf1b712e
+# access-list test_access line 1 extended deny tcp 192.0.2.0 255.255.255.0 192.0.3.0 255.255.255.0 eq www log default
+# access-list test_access line 2 extended deny igrp 198.51.100.0 255.255.255.0 198.51.110.0 255.255.255.0 log errors
+# access-list test_R1_traffic; 1 elements; name hash: 0xaf40d3c2
+# access-list test_R1_traffic line 1 extended deny tcp 2001:db8:0:3::/64 eq www 2001:fc8:0:4::/64 eq telnet inactive
+
+- name: Parse the commands for provided configuration
+ cisco.asa.asa_acls:
+ running_config: "{{ lookup('file', 'parsed.cfg') }}"
+ state: parsed
+
+# Module Execution Result:
+# ------------------------
+#
+# "parsed": [
+# {
+# "acls": [
+# {
+# "aces": [
+# {
+# "destination": {
+# "address": "192.0.3.0",
+# "netmask": "255.255.255.0",
+# "port_protocol": {
+# "eq": "www"
+# }
+# },
+# "grant": "deny",
+# "line": 1,
+# "log": "default",
+# "protocol": "tcp",
+# "protocol_options": {
+# "tcp": true
+# },
+# "source": {
+# "address": "192.0.2.0",
+# "netmask": "255.255.255.0"
+# }
+# },
+# {
+# "destination": {
+# "address": "198.51.110.0",
+# "netmask": "255.255.255.0"
+# },
+# "grant": "deny",
+# "line": 2,
+# "log": "errors",
+# "protocol": "igrp",
+# "protocol_options": {
+# "igrp": true
+# },
+# "source": {
+# "address": "198.51.100.0",
+# "netmask": "255.255.255.0"
+# }
+# }
+# ],
+# "acl_type": "extended",
+# "name": "test_access"
+# },
+# {
+# "aces": [
+# {
+# "destination": {
+# "address": "2001:fc8:0:4::/64",
+# "port_protocol": {
+# "eq": "telnet"
+# }
+# },
+# "grant": "deny",
+# "inactive": true,
+# "line": 1,
+# "protocol": "tcp",
+# "protocol_options": {
+# "tcp": true
+# },
+# "source": {
+# "address": "2001:db8:0:3::/64",
+# "port_protocol": {
+# "eq": "www"
+# }
+# }
+# }
+# ],
+# "acl_type": "extended",
+# "name": "test_R1_TRAFFIC"
+# }
+# ]
+# }
+# ]
+
+"""
+
+RETURN = """
+before:
+ description: The configuration as structured data prior to module invocation.
+ returned: always
+ type: list
+ sample: The configuration returned will always be in the same format of the parameters above.
+after:
+ description: The configuration as structured data after module completion.
+ returned: when changed
+ type: list
+ sample: The configuration returned will always be in the same format of the parameters above.
+commands:
+ description: The set of commands pushed to the remote device
+ returned: always
+ type: list
+ sample: ['access-list global_access line 1 extended permit icmp any any log disable']
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible_collections.cisco.asa.plugins.module_utils.network.asa.argspec.acls.acls import (
+ AclsArgs,
+)
+from ansible_collections.cisco.asa.plugins.module_utils.network.asa.config.acls.acls import (
+ Acls,
+)
+
+
+def main():
+ """
+ Main entry point for module execution
+ :returns: the result form module invocation
+ """
+ required_if = [
+ ("state", "merged", ("config",)),
+ ("state", "replaced", ("config",)),
+ ("state", "overridden", ("config",)),
+ ("state", "rendered", ("config",)),
+ ("state", "parsed", ("running_config",)),
+ ]
+ mutually_exclusive = [("config", "running_config")]
+
+ module = AnsibleModule(
+ argument_spec=AclsArgs.argument_spec,
+ required_if=required_if,
+ mutually_exclusive=mutually_exclusive,
+ supports_check_mode=True,
+ )
+
+ result = Acls(module).execute_module()
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/modules/asa_command.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/modules/asa_command.py
new file mode 100644
index 00000000..ce5f2f77
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/modules/asa_command.py
@@ -0,0 +1,197 @@
+#!/usr/bin/python
+#
+# Copyright: Ansible Project
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+
+DOCUMENTATION = """
+module: asa_command
+author: Peter Sprygada (@privateip), Patrick Ogenstad (@ogenstad)
+short_description: Run arbitrary commands on Cisco ASA devices
+description:
+- Sends arbitrary commands to an ASA node and returns the results read from the device.
+ The C(asa_command) module includes an argument that will cause the module to wait
+ for a specific condition before returning or timing out if the condition is not
+ met.
+version_added: 1.0.0
+extends_documentation_fragment:
+- cisco.asa.asa
+options:
+ commands:
+ description:
+ - List of commands to send to the remote device over the configured provider.
+ The resulting output from the command is returned. If the I(wait_for) argument
+ is provided, the module is not returned until the condition is satisfied or
+ the number of retires as expired.
+ required: true
+ type: list
+ elements: str
+ wait_for:
+ description:
+ - List of conditions to evaluate against the output of the command. The task will
+ wait for each condition to be true before moving forward. If the conditional
+ is not true within the configured number of retries, the task fails. See examples.
+ aliases:
+ - waitfor
+ type: list
+ elements: str
+ match:
+ description:
+ - The I(match) argument is used in conjunction with the I(wait_for) argument to
+ specify the match policy. Valid values are C(all) or C(any). If the value
+ is set to C(all) then all conditionals in the wait_for must be satisfied. If
+ the value is set to C(any) then only one of the values must be satisfied.
+ default: all
+ choices:
+ - any
+ - all
+ type: str
+ retries:
+ description:
+ - Specifies the number of retries a command should by tried before it is considered
+ failed. The command is run on the target device every retry and evaluated against
+ the I(wait_for) conditions.
+ default: 10
+ type: int
+ interval:
+ description:
+ - Configures the interval in seconds to wait between retries of the command. If
+ the command does not pass the specified conditions, the interval indicates how
+ long to wait before trying the command again.
+ default: 1
+ type: int
+notes:
+- When processing wait_for, each commands' output is stored as an element of the I(result)
+ array. The allowed operators for conditional evaluation are I(eq), I(==), I(neq),
+ I(ne), I(!=), I(gt), I(>), I(ge), I(>=), I(lt), I(<), I(le), I(<=), I(contains),
+ I(matches). Operators can be prefaced by I(not) to negate their meaning. The I(contains)
+ operator searches for a substring match (like the Python I(in) operator). The I(matches)
+ operator searches using a regex search operation.
+"""
+
+EXAMPLES = """
+- name: Show the ASA version
+ cisco.asa.asa_command:
+ commands:
+ - show version
+
+- name: Show ASA drops and memory
+ cisco.asa.asa_command:
+ commands:
+ - show asp drop
+ - show memory
+
+- name: Send repeat pings and wait for the result to pass 100%
+ cisco.asa.asa_command:
+ commands:
+ - ping 8.8.8.8 repeat 20 size 350
+ wait_for:
+ - result[0] contains 100
+ retries: 2
+"""
+
+RETURN = """
+stdout:
+ description: the set of responses from the commands
+ returned: always
+ type: list
+ sample: ['...', '...']
+
+stdout_lines:
+ description: The value of stdout split into a list
+ returned: always
+ type: list
+ sample: [['...', '...'], ['...'], ['...']]
+
+failed_conditions:
+ description: the conditionals that failed
+ returned: failed
+ type: list
+ sample: ['...', '...']
+"""
+import time
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible_collections.cisco.asa.plugins.module_utils.network.asa.asa import (
+ asa_argument_spec,
+ check_args,
+)
+from ansible_collections.cisco.asa.plugins.module_utils.network.asa.asa import (
+ run_commands,
+)
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.parsing import (
+ Conditional,
+)
+from ansible.module_utils.six import string_types
+
+
+def to_lines(stdout):
+ for item in stdout:
+ if isinstance(item, string_types):
+ item = str(item).split("\n")
+ yield item
+
+
+def main():
+ spec = dict(
+ # { command: <str>, prompt: <str>, response: <str> }
+ commands=dict(type="list", required=True, elements="str"),
+ wait_for=dict(type="list", aliases=["waitfor"], elements="str"),
+ match=dict(default="all", choices=["all", "any"], type="str"),
+ retries=dict(default=10, type="int"),
+ interval=dict(default=1, type="int"),
+ )
+
+ spec.update(asa_argument_spec)
+
+ module = AnsibleModule(argument_spec=spec, supports_check_mode=True)
+ check_args(module)
+
+ result = {"changed": False}
+
+ wait_for = module.params["wait_for"] or list()
+ conditionals = [Conditional(c) for c in wait_for]
+
+ commands = module.params["commands"]
+ retries = module.params["retries"]
+ interval = module.params["interval"]
+ match = module.params["match"]
+
+ while retries > 0:
+ responses = run_commands(module, commands)
+
+ for item in list(conditionals):
+ if item(responses):
+ if match == "any":
+ conditionals = list()
+ break
+ conditionals.remove(item)
+
+ if not conditionals:
+ break
+
+ time.sleep(interval)
+ retries -= 1
+
+ if conditionals:
+ failed_conditions = [item.raw for item in conditionals]
+ msg = "One or more conditional statements have not be satisfied"
+ module.fail_json(msg=msg, failed_conditions=failed_conditions)
+
+ result.update(
+ {
+ "changed": False,
+ "stdout": responses,
+ "stdout_lines": list(to_lines(responses)),
+ }
+ )
+
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/modules/asa_config.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/modules/asa_config.py
new file mode 100644
index 00000000..71cb9fb0
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/modules/asa_config.py
@@ -0,0 +1,368 @@
+#!/usr/bin/python
+#
+# Copyright: Ansible Project
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+
+DOCUMENTATION = """
+module: asa_config
+author: Peter Sprygada (@privateip), Patrick Ogenstad (@ogenstad)
+short_description: Manage configuration sections on Cisco ASA devices
+description:
+- Cisco ASA configurations use a simple block indent file syntax for segmenting configuration
+ into sections. This module provides an implementation for working with ASA configuration
+ sections in a deterministic way.
+version_added: 1.0.0
+extends_documentation_fragment:
+- cisco.asa.asa
+options:
+ lines:
+ description:
+ - The ordered set of commands that should be configured in the section. The commands
+ must be the exact same commands as found in the device running-config. Be sure
+ to note the configuration command syntax as some commands are automatically
+ modified by the device config parser.
+ aliases:
+ - commands
+ type: list
+ elements: str
+ parents:
+ description:
+ - The ordered set of parents that uniquely identify the section or hierarchy the
+ commands should be checked against. If the parents argument is omitted, the
+ commands are checked against the set of top level or global commands.
+ type: list
+ elements: str
+ src:
+ description:
+ - Specifies the source path to the file that contains the configuration or configuration
+ template to load. The path to the source file can either be the full path on
+ the Ansible control host or a relative path from the playbook or role root directory. This
+ argument is mutually exclusive with I(lines), I(parents).
+ type: path
+ before:
+ description:
+ - The ordered set of commands to push on to the command stack if a change needs
+ to be made. This allows the playbook designer the opportunity to perform configuration
+ commands prior to pushing any changes without affecting how the set of commands
+ are matched against the system.
+ type: list
+ elements: str
+ after:
+ description:
+ - The ordered set of commands to append to the end of the command stack if a change
+ needs to be made. Just like with I(before) this allows the playbook designer
+ to append a set of commands to be executed after the command set.
+ type: list
+ elements: str
+ match:
+ description:
+ - Instructs the module on the way to perform the matching of the set of commands
+ against the current device config. If match is set to I(line), commands are
+ matched line by line. If match is set to I(strict), command lines are matched
+ with respect to position. If match is set to I(exact), command lines must be
+ an equal match. Finally, if match is set to I(none), the module will not attempt
+ to compare the source configuration with the running configuration on the remote
+ device.
+ default: line
+ choices:
+ - line
+ - strict
+ - exact
+ - none
+ type: str
+ replace:
+ description:
+ - Instructs the module on the way to perform the configuration on the device. If
+ the replace argument is set to I(line) then the modified lines are pushed to
+ the device in configuration mode. If the replace argument is set to I(block)
+ then the entire command block is pushed to the device in configuration mode
+ if any line is not correct
+ default: line
+ choices:
+ - line
+ - block
+ type: str
+ backup:
+ description:
+ - This argument will cause the module to create a full backup of the current C(running-config)
+ from the remote device before any changes are made. If the C(backup_options)
+ value is not given, the backup file is written to the C(backup) folder in the
+ playbook root directory. If the directory does not exist, it is created.
+ type: bool
+ default: no
+ config:
+ description:
+ - The C(config) argument allows the playbook designer to supply the base configuration
+ to be used to validate configuration changes necessary. If this argument is
+ provided, the module will not download the running-config from the remote node.
+ type: str
+ defaults:
+ description:
+ - This argument specifies whether or not to collect all defaults when getting
+ the remote device running config. When enabled, the module will get the current
+ config by issuing the command C(show running-config all).
+ type: bool
+ default: no
+ passwords:
+ description:
+ - This argument specifies to include passwords in the config when retrieving the
+ running-config from the remote device. This includes passwords related to VPN
+ endpoints. This argument is mutually exclusive with I(defaults).
+ type: bool
+ default: false
+ save:
+ description:
+ - The C(save) argument instructs the module to save the running- config to the
+ startup-config at the conclusion of the module running. If check mode is specified,
+ this argument is ignored.
+ type: bool
+ default: no
+ backup_options:
+ description:
+ - This is a dict object containing configurable options related to backup file
+ path. The value of this option is read only when C(backup) is set to I(yes),
+ if C(backup) is set to I(no) this option will be silently ignored.
+ suboptions:
+ filename:
+ description:
+ - The filename to be used to store the backup configuration. If the filename
+ is not given it will be generated based on the hostname, current time and
+ date in format defined by <hostname>_config.<current-date>@<current-time>
+ type: str
+ dir_path:
+ description:
+ - This option provides the path ending with directory name in which the backup
+ configuration file will be stored. If the directory does not exist it will
+ be first created and the filename is either the value of C(filename) or
+ default filename as described in C(filename) options description. If the
+ path value is not given in that case a I(backup) directory will be created
+ in the current working directory and backup configuration will be copied
+ in C(filename) within I(backup) directory.
+ type: path
+ type: dict
+"""
+
+EXAMPLES = """
+- cisco.asa.asa_config:
+ lines:
+ - network-object host 10.80.30.18
+ - network-object host 10.80.30.19
+ - network-object host 10.80.30.20
+ parents: [object-group network OG-MONITORED-SERVERS]
+ provider: '{{ cli }}'
+
+- cisco.asa.asa_config:
+ host: '{{ inventory_hostname }}'
+ lines:
+ - message-length maximum client auto
+ - message-length maximum 512
+ match: line
+ parents: [policy-map type inspect dns PM-DNS, parameters]
+ authorize: yes
+ auth_pass: cisco
+ username: admin
+ password: cisco
+ context: ansible
+
+- cisco.asa.asa_config:
+ lines:
+ - ikev1 pre-shared-key MyS3cretVPNK3y
+ parents: tunnel-group 1.1.1.1 ipsec-attributes
+ passwords: yes
+ provider: '{{ cli }}'
+
+- name: attach ASA acl on interface vlan13/nameif cloud13
+ cisco.asa.asa_config:
+ lines:
+ - access-group cloud-acl_access_in in interface cloud13
+ provider: '{{ cli }}'
+
+- name: configure ASA (>=9.2) default BGP
+ cisco.asa.asa_config:
+ lines:
+ - bgp log-neighbor-changes
+ - bgp bestpath compare-routerid
+ provider: '{{ cli }}'
+ parents:
+ - router bgp 65002
+ register: bgp
+ when: bgp_default_config is defined
+- name: configure ASA (>=9.2) BGP neighbor in default/single context mode
+ cisco.asa.asa_config:
+ lines:
+ - bgp router-id {{ bgp_router_id }}
+ - neighbor {{ bgp_neighbor_ip }} remote-as {{ bgp_neighbor_as }}
+ - neighbor {{ bgp_neighbor_ip }} description {{ bgp_neighbor_name }}
+ provider: '{{ cli }}'
+ parents:
+ - router bgp 65002
+ - address-family ipv4 unicast
+ register: bgp
+ when: bgp_neighbor_as is defined
+- name: configure ASA interface with standby
+ cisco.asa.asa_config:
+ lines:
+ - description my cloud interface
+ - nameif cloud13
+ - security-level 50
+ - ip address 192.168.13.1 255.255.255.0 standby 192.168.13.2
+ provider: '{{ cli }}'
+ parents: [interface Vlan13]
+ register: interface
+- name: Show changes to interface from task above
+ debug:
+ var: interface
+
+- name: configurable backup path
+ cisco.asa.asa_config:
+ lines:
+ - access-group cloud-acl_access_in in interface cloud13
+ provider: '{{ cli }}'
+ backup: yes
+ backup_options:
+ filename: backup.cfg
+ dir_path: /home/user
+"""
+
+RETURN = """
+updates:
+ description: The set of commands that will be pushed to the remote device
+ returned: always
+ type: list
+ sample: ['...', '...']
+backup_path:
+ description: The full path to the backup file
+ returned: when backup is yes
+ type: str
+ sample: /playbooks/ansible/backup/asa_config.2016-07-16@22:28:34
+"""
+from ansible.module_utils.basic import AnsibleModule
+from ansible_collections.cisco.asa.plugins.module_utils.network.asa.asa import (
+ asa_argument_spec,
+ check_args,
+)
+from ansible_collections.cisco.asa.plugins.module_utils.network.asa.asa import (
+ get_config,
+ load_config,
+ run_commands,
+)
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.config import (
+ NetworkConfig,
+ dumps,
+)
+
+
+def get_candidate(module):
+ candidate = NetworkConfig(indent=1)
+ if module.params["src"]:
+ candidate.load(module.params["src"])
+ elif module.params["lines"]:
+ parents = module.params["parents"] or list()
+ candidate.add(module.params["lines"], parents=parents)
+ return candidate
+
+
+def run(module, result):
+ match = module.params["match"]
+ replace = module.params["replace"]
+ path = module.params["parents"]
+
+ candidate = get_candidate(module)
+ if match != "none":
+ contents = module.params["config"]
+ if not contents:
+ contents = get_config(module)
+ config = NetworkConfig(indent=1, contents=contents)
+ configobjs = candidate.difference(
+ config, path=path, match=match, replace=replace
+ )
+
+ else:
+ configobjs = candidate.items
+
+ if configobjs:
+ commands = dumps(configobjs, "commands").split("\n")
+
+ if module.params["lines"]:
+ if module.params["before"]:
+ commands[:0] = module.params["before"]
+
+ if module.params["after"]:
+ commands.extend(module.params["after"])
+
+ result["updates"] = commands
+
+ # send the configuration commands to the device and merge
+ # them with the current running config
+ if not module.check_mode:
+ load_config(module, commands)
+ result["changed"] = True
+
+ if module.params["save"]:
+ if not module.check_mode:
+ run_commands(module, "write mem")
+ result["changed"] = True
+
+
+def main():
+ """ main entry point for module execution
+ """
+ backup_spec = dict(filename=dict(), dir_path=dict(type="path"))
+ argument_spec = dict(
+ src=dict(type="path"),
+ lines=dict(aliases=["commands"], type="list", elements="str"),
+ parents=dict(type="list", elements="str"),
+ before=dict(type="list", elements="str"),
+ after=dict(type="list", elements="str"),
+ match=dict(
+ default="line", choices=["line", "strict", "exact", "none"]
+ ),
+ replace=dict(default="line", choices=["line", "block"]),
+ backup_options=dict(type="dict", options=backup_spec),
+ config=dict(),
+ defaults=dict(type="bool", default=False),
+ passwords=dict(type="bool", default=False),
+ backup=dict(type="bool", default=False),
+ save=dict(type="bool", default=False),
+ )
+
+ argument_spec.update(asa_argument_spec)
+
+ mutually_exclusive = [
+ ("lines", "src"),
+ ("parents", "src"),
+ ("defaults", "passwords"),
+ ]
+
+ required_if = [
+ ("match", "strict", ["lines"]),
+ ("match", "exact", ["lines"]),
+ ("replace", "block", ["lines"]),
+ ]
+
+ module = AnsibleModule(
+ argument_spec=argument_spec,
+ mutually_exclusive=mutually_exclusive,
+ required_if=required_if,
+ supports_check_mode=True,
+ )
+
+ result = {"changed": False}
+
+ check_args(module)
+
+ if module.params["backup"]:
+ result["__backup__"] = get_config(module)
+
+ run(module, result)
+
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/modules/asa_facts.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/modules/asa_facts.py
new file mode 100644
index 00000000..6efd2175
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/modules/asa_facts.py
@@ -0,0 +1,209 @@
+#!/usr/bin/python
+#
+# This file is part of Ansible
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
+#
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+
+DOCUMENTATION = """
+module: asa_facts
+author:
+- Sumit Jaiswal (@justjais)
+short_description: Collect facts from remote devices running Cisco ASA
+description:
+- Collects a base set of device facts from a remote device that is running ASA. This
+ module prepends all of the base network fact keys with C(ansible_net_<fact>). The
+ facts module will always collect a base set of facts from the device and can enable
+ or disable collection of additional facts.
+- Note, to collects facts from ASA device properly user should elevate the privilege
+ to become.
+version_added: 1.0.0
+extends_documentation_fragment:
+- cisco.asa.asa
+notes:
+- Tested against asa 9.10(1)11
+options:
+ gather_subset:
+ description:
+ - When supplied, this argument restricts the facts collected to a given subset.
+ - Possible values for this argument include C(all), C(min), C(hardware), C(config).
+ - Specify a list of values to include a larger subset.
+ - Use a value with an initial C(!) to collect all facts except that subset.
+ required: false
+ type: list
+ elements: str
+ default: '!config'
+ gather_network_resources:
+ description:
+ - When supplied, this argument will restrict the facts collected to a given subset.
+ Possible values for this argument include all and the resources like interfaces,
+ vlans etc. Can specify a list of values to include a larger subset. Values can
+ also be used with an initial C(M(!)) to specify that a specific subset should
+ not be collected. Valid subsets are 'all', 'acls', 'ogs'.
+ required: false
+ type: list
+ elements: str
+"""
+
+EXAMPLES = """
+- name: Gather all legacy facts
+ cisco.asa.asa_facts:
+ gather_subset: all
+
+- name: Gather only the config and default facts
+ cisco.asa.asa_facts:
+ gather_subset:
+ - config
+
+- name: Do not gather hardware facts
+ cisco.asa.asa_facts:
+ gather_subset:
+ - '!hardware'
+
+- name: Gather legacy and resource facts
+ cisco.asa.asa_facts:
+ gather_subset: all
+"""
+
+RETURN = """
+ansible_net_gather_subset:
+ description: The list of fact subsets collected from the device
+ returned: always
+ type: list
+
+# default
+ansible_net_model:
+ description: The model name returned from the device
+ returned: always
+ type: str
+ansible_net_serialnum:
+ description: The serial number of the remote device
+ returned: always
+ type: str
+ansible_net_version:
+ description: The operating system version running on the remote device
+ returned: always
+ type: str
+ansible_net_firepower_version:
+ description: The Firepower operating system version running on the remote device.
+ returned: always
+ type: str
+ansible_net_device_mgr_version:
+ description: The Device manager version running on the remote device.
+ returned: always
+ type: str
+ansible_net_asatype:
+ description: The operating system type (Cisco ASA) running on the remote device.
+ returned: always
+ type: str
+ansible_net_hostname:
+ description: The configured hostname of the device
+ returned: always
+ type: str
+ansible_net_image:
+ description: The image file the device is running
+ returned: always
+ type: str
+ansible_net_stacked_models:
+ description: The model names of each device in the stack
+ returned: when multiple devices are configured in a stack
+ type: list
+ansible_net_stacked_serialnums:
+ description: The serial numbers of each device in the stack
+ returned: when multiple devices are configured in a stack
+ type: list
+ansible_net_api:
+ description: The name of the transport
+ returned: always
+ type: str
+ansible_net_python_version:
+ description: The Python version Ansible controller is using
+ returned: always
+ type: str
+
+# hardware
+ansible_net_filesystems:
+ description: All file system names available on the device
+ returned: when hardware is configured
+ type: list
+ansible_net_filesystems_info:
+ description: A hash of all file systems containing info about each file system (e.g. free and total space)
+ returned: when hardware is configured
+ type: dict
+ansible_net_memfree_mb:
+ description: The available free memory on the remote device in Mb
+ returned: when hardware is configured
+ type: int
+ansible_net_memused_mb:
+ description: The used memory on the remote device in Mb
+ returned: when hardware is configured
+ type: int
+ansible_net_memtotal_mb:
+ description: The total memory on the remote device in Mb
+ returned: when hardware is configured
+ type: int
+
+# config
+ansible_net_config:
+ description: The current active config from the device
+ returned: when config is configured
+ type: str
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.cisco.asa.plugins.module_utils.network.asa.argspec.facts.facts import (
+ FactsArgs,
+)
+from ansible_collections.cisco.asa.plugins.module_utils.network.asa.facts.facts import (
+ Facts,
+)
+from ansible_collections.cisco.asa.plugins.module_utils.network.asa.asa import (
+ asa_argument_spec,
+)
+
+
+def main():
+ """
+ Main entry point for module execution
+
+ :returns: ansible_facts
+ """
+ argument_spec = FactsArgs.argument_spec
+ argument_spec.update(asa_argument_spec)
+
+ module = AnsibleModule(
+ argument_spec=argument_spec, supports_check_mode=True
+ )
+
+ warnings = []
+ if module.params["gather_subset"] == "!config":
+ warnings.append(
+ "default value for `gather_subset` will be changed to `min` from `!config` v2.11 onwards"
+ )
+
+ result = Facts(module).get_facts()
+
+ ansible_facts, additional_warnings = result
+ warnings.extend(additional_warnings)
+
+ module.exit_json(ansible_facts=ansible_facts, warnings=warnings)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/modules/asa_og.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/modules/asa_og.py
new file mode 100644
index 00000000..de37aebb
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/modules/asa_og.py
@@ -0,0 +1,1034 @@
+#!/usr/bin/python
+# -*- 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)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+
+DOCUMENTATION = """
+module: asa_og
+author:
+- Federico Olivieri (@Federico87)
+short_description: (deprecated, removed after 2022-06-01) Manage object groups on
+ a Cisco ASA
+description:
+- This module allows you to create and update object-group network/service on Cisco
+ ASA device.
+version_added: 1.0.0
+deprecated:
+ alternative: asa_ogs
+ why: Newer and updated modules released with more functionality in Ansible 2.10
+ removed_at_date: '2022-06-01'
+options:
+ name:
+ description:
+ - Name of the object group.
+ required: true
+ type: str
+ group_type:
+ description:
+ - The object group type.
+ choices:
+ - network-object
+ - service-object
+ - port-object
+ required: true
+ type: str
+ protocol:
+ description:
+ - The protocol for object-group service with port-object.
+ choices:
+ - udp
+ - tcp
+ - tcp-udp
+ type: str
+ host_ip:
+ description:
+ - The host IP address for object-group network.
+ type: list
+ elements: str
+ description:
+ description:
+ - The description for the object-group.
+ type: str
+ group_object:
+ description:
+ - The group-object for network object-group.
+ type: list
+ elements: str
+ ip_mask:
+ description:
+ - The IP address and mask for network object-group.
+ type: list
+ elements: str
+ port_range:
+ description:
+ - The port range for port-object.
+ type: list
+ elements: str
+ port_eq:
+ description:
+ - The single port for port-object.
+ type: list
+ elements: str
+ service_cfg:
+ description:
+ - The service-object configuration protocol, direction, range or port.
+ type: list
+ elements: str
+ state:
+ description:
+ - Manage the state of the resource.
+ type: str
+ default: present
+ choices:
+ - present
+ - absent
+ - replace
+
+"""
+
+EXAMPLES = """
+- name: configure network object-group
+ cisco.asa.asa_og:
+ name: ansible_test_0
+ group_type: network-object
+ state: present
+ description: ansible_test object-group description
+ host_ip:
+ - 8.8.8.8
+ - 8.8.4.4
+ ip_mask:
+ - 10.0.0.0 255.255.255.0
+ - 192.168.0.0 255.255.0.0
+ group_object:
+ - awx_lon
+ - awx_ams
+
+- name: configure port-object object-group
+ cisco.asa.asa_og:
+ name: ansible_test_1
+ group_type: port-object
+ state: replace
+ description: ansible_test object-group description
+ protocol: tcp-udp
+ port_eq:
+ - 1025
+ - kerberos
+ port_range:
+ - 1025 5201
+ - 0 1024
+
+- name: configure service-object object-group
+ cisco.asa.asa_og:
+ name: ansible_test_2
+ group_type: service-object
+ state: absent
+ description: ansible_test object-group description
+ service_cfg:
+ - tcp destination eq 8080
+ - tcp destination eq www
+"""
+
+RETURN = """
+commands:
+ description: command sent to the device
+ returned: always
+ type: list
+ sample: [
+ "object-group network ansible_test_0",
+ "description ansible_test object-group description",
+ "network-object host 8.8.8.8",
+ "network-object host 8.8.4.4",
+ "network-object 10.0.0.0 255.255.255.0",
+ "network-object 192.168.0.0 255.255.0.0",
+ "network-object 192.168.0.0 255.255.0.0",
+ "group-object awx_lon",
+ "group-object awx_ams",
+ ]
+"""
+import re
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible_collections.cisco.asa.plugins.module_utils.network.asa.asa import (
+ get_config,
+ load_config,
+)
+
+
+class Parser:
+ """Regex class for outputs parsing"""
+
+ def __init__(self, config, protocol):
+ """Parser __init__ method"""
+ self.config = config
+ self.protocol = protocol
+
+ def parse_obj_grp_name(self):
+ list_return = list()
+ match = re.search(
+ r"(?:object-group\s)(network\s|service\s)(\w+)\s?(tcp-udp|tcp|udp)?",
+ self.config,
+ re.M,
+ )
+
+ if match:
+ if match.group(3):
+ list_return.append(str(match.group(3)))
+ else:
+ list_return.append(False)
+
+ if match.group(2):
+ list_return.append(str(match.group(2)))
+
+ if match.group(1):
+ list_return.append(str(match.group(1)))
+
+ return list_return
+
+ def parse_description(self):
+ match = re.search(r"description(:)?\s(.*)", self.config, re.M)
+ if match:
+ description = match.group(2)
+
+ return description
+
+ def parse_host(self):
+ list_return = list()
+ match = re.findall(r"(host\s)(\d+\.\d+\.\d+\.\d+)", self.config, re.M)
+
+ if match:
+ for i in match:
+ if i[1]:
+ list_return.append(str(i[1]))
+
+ return list_return
+
+ def parse_group_object(self):
+ list_return = list()
+ match = re.findall(r"(group-object\s)(.*)", self.config, re.M)
+
+ if match:
+ for i in match:
+ if i[1]:
+ list_return.append(str(i[1]))
+
+ return list_return
+
+ def parse_address(self):
+ list_return = list()
+ match = re.findall(
+ r"(network-object\s)(\d+\.\d+\.\d+\.\d+\s\d+\.\d+\.\d+\.\d+)",
+ self.config,
+ re.M,
+ )
+
+ if match:
+ for i in match:
+ if i[1]:
+ list_return.append(str(i[1]))
+
+ return list_return
+
+ def parse_port_range(self):
+ list_return = list()
+ match = re.findall(r"(range\s)(.*)", self.config, re.M)
+
+ if match:
+ for i in match:
+ if i[1]:
+ list_return.append(str(i[1]))
+
+ return list_return
+
+ def parse_port_eq(self):
+ list_return = list()
+ match = re.findall(r"(eq\s)(.*)", self.config, re.M)
+
+ if match:
+ for i in match:
+ if i[1]:
+ list_return.append(str(i[1]))
+
+ return list_return
+
+ def parse_service_cfg(self):
+ list_return = list()
+ match = re.findall(r"(service-object\s)(.*)", self.config, re.M)
+
+ if match:
+ for i in match:
+ if i[1]:
+ list_return.append(str(i[1]))
+
+ return list_return
+
+
+def map_config_to_obj(module):
+
+ obj = list()
+ obj_dict = dict()
+
+ group_name = module.params["name"]
+ protocol = module.params["protocol"]
+
+ sh_run_group_name = get_config(
+ module, flags=["object-group | include {0}".format(group_name)]
+ )
+ run_group_name = Parser(sh_run_group_name, protocol).parse_obj_grp_name()
+
+ obj_dict["have_name"] = run_group_name
+
+ if run_group_name:
+ if run_group_name[0] is not False:
+ obj_dict["have_group_type"] = "port-object"
+ obj_dict["have_protocol"] = run_group_name[0]
+ elif "network" in run_group_name[2]:
+ obj_dict["have_group_type"] = "network-object"
+ elif "service" in run_group_name[2] and run_group_name[0] is False:
+ obj_dict["have_group_type"] = "service-object"
+ else:
+ obj_dict["have_group_type"] = None
+
+ sh_run_group_type = get_config(
+ module, flags=["object-group id {0}".format(group_name)]
+ )
+
+ have_description = Parser(sh_run_group_type, protocol).parse_description()
+ obj_dict["have_description"] = have_description
+
+ have_host_ip = Parser(sh_run_group_type, protocol).parse_host()
+ obj_dict["have_host_ip"] = have_host_ip
+
+ have_group_object = Parser(
+ sh_run_group_type, protocol
+ ).parse_group_object()
+ obj_dict["have_group_object"] = have_group_object
+
+ have_ip_mask = Parser(sh_run_group_type, protocol).parse_address()
+ obj_dict["have_ip_mask"] = have_ip_mask
+
+ have_port_range = Parser(sh_run_group_type, protocol).parse_port_range()
+ obj_dict["have_port_range"] = have_port_range
+
+ have_port_eq = Parser(sh_run_group_type, protocol).parse_port_eq()
+ obj_dict["have_port_eq"] = have_port_eq
+
+ have_service_cfg = Parser(sh_run_group_type, protocol).parse_service_cfg()
+
+ if have_service_cfg:
+ have_lines = list()
+ for i in have_service_cfg:
+ have_lines.append(i.rstrip(" "))
+ obj_dict["have_service_cfg"] = have_lines
+ elif have_service_cfg is None:
+ obj_dict["have_service_cfg"] = have_service_cfg
+
+ obj.append(obj_dict)
+
+ return obj
+
+
+def replace(want_dict, have):
+
+ commands = list()
+ add_lines = list()
+ remove_lines = list()
+
+ have_group_type = have[0].get("have_group_type")
+ have_description = have[0].get("have_description")
+ have_host_ip = have[0].get("have_host_ip")
+ have_group_object = have[0].get("have_group_object")
+ have_ip_mask = have[0].get("have_ip_mask")
+ have_protocol = have[0].get("have_protocol")
+ have_port_range = have[0].get("have_port_range")
+ have_port_eq = have[0].get("have_port_eq")
+ have_service_cfg = have[0].get("have_service_cfg")
+
+ name = want_dict["name"]
+ group_type = want_dict["group_type"]
+ protocol = want_dict["protocol"]
+ description = want_dict["description"]
+ host = want_dict["host_ip"]
+ group_object = want_dict["group_object"]
+ address = want_dict["ip_mask"]
+ port_range = want_dict["port_range"]
+ port_eq = want_dict["port_eq"]
+ service_cfg = want_dict["service_cfg"]
+
+ if "network-object" in group_type:
+
+ if have_group_type is None:
+ commands.append("object-group network {0}".format(name))
+
+ if host:
+ for i in host:
+ commands.append("network-object host " + i)
+ if description:
+ if have_description is None:
+ commands.append("description {0}".format(description))
+ if group_object:
+ for i in group_object:
+ if i not in have_group_object:
+ commands.append("group-object " + i)
+ if address:
+ for i in address:
+ commands.append("network-object " + i)
+
+ elif "network" in have_group_type:
+
+ if host:
+ if sorted(host) != sorted(have_host_ip):
+ for i in host:
+ if i not in have_host_ip:
+ if (
+ "object-group network {0}".format(name)
+ not in commands
+ ):
+ commands.append(
+ "object-group network {0}".format(name)
+ )
+ add_lines.append("network-object host " + i)
+ for i in have_host_ip:
+ if i not in host:
+ if (
+ "object-group network {0}".format(name)
+ not in commands
+ ):
+ commands.append(
+ "object-group network {0}".format(name)
+ )
+ remove_lines.append("no network-object host " + i)
+
+ if description:
+ if description != have_description:
+ if "object-group network {0}".format(name) not in commands:
+ commands.append(
+ "object-group network {0}".format(name)
+ )
+ add_lines.append("description {0}".format(description))
+
+ if group_object:
+ if sorted(group_object) != sorted(have_group_object):
+ for i in group_object:
+ if i not in have_group_object:
+ if (
+ "object-group network {0}".format(name)
+ not in commands
+ ):
+ commands.append(
+ "object-group network {0}".format(name)
+ )
+ add_lines.append("group-object " + i)
+ for i in have_group_object:
+ if i not in group_object:
+ if (
+ "object-group network {0}".format(name)
+ not in commands
+ ):
+ commands.append(
+ "object-group network {0}".format(name)
+ )
+ remove_lines.append("no group-object " + i)
+ if address:
+ if sorted(address) != sorted(have_ip_mask):
+ for i in address:
+ if i not in have_ip_mask:
+ if (
+ "object-group network {0}".format(name)
+ not in commands
+ ):
+ commands.append(
+ "object-group network {0}".format(name)
+ )
+ add_lines.append("network-object " + i)
+ for i in have_ip_mask:
+ if i not in address:
+ if (
+ "object-group network {0}".format(name)
+ not in commands
+ ):
+ commands.append(
+ "object-group network {0}".format(name)
+ )
+ remove_lines.append("no network-object " + i)
+
+ elif "port-object" in group_type:
+
+ if have_group_type is None and have_protocol != protocol:
+ commands.append(
+ "object-group service {0} {1}".format(name, protocol)
+ )
+
+ if port_range:
+ for i in port_range:
+ commands.append("port-object range " + i)
+ if port_eq:
+ for i in port_eq:
+ commands.append("port-object eq " + i)
+ if description:
+ commands.append("description {0}".format(description))
+
+ elif "port" in have_group_type and have_protocol == protocol:
+
+ if port_range:
+ if sorted(port_range) != sorted(have_port_range):
+ for i in port_range:
+ if i not in have_port_range:
+ if (
+ "object-group service {0} {1}".format(
+ name, protocol
+ )
+ not in commands
+ ):
+ commands.append(
+ "object-group service {0} {1}".format(
+ name, protocol
+ )
+ )
+ add_lines.append("port-object range " + i)
+ for i in have_port_range:
+ if i not in port_range:
+ if (
+ "object-group service {0} {1}".format(
+ name, protocol
+ )
+ not in commands
+ ):
+ commands.append(
+ "object-group service {0} {1}".format(
+ name, protocol
+ )
+ )
+ remove_lines.append("no port-object range " + i)
+ if port_eq:
+ if sorted(port_eq) != sorted(have_port_eq):
+ for i in port_eq:
+ if i not in have_port_eq:
+ if (
+ "object-group service {0} {1}".format(
+ name, protocol
+ )
+ not in commands
+ ):
+ commands.append(
+ "object-group service {0} {1}".format(
+ name, protocol
+ )
+ )
+ add_lines.append("port-object eq " + i)
+ for i in have_port_eq:
+ if i not in port_eq:
+ if (
+ "object-group service {0} {1}".format(
+ name, protocol
+ )
+ not in commands
+ ):
+ commands.append(
+ "object-group service {0} {1}".format(
+ name, protocol
+ )
+ )
+ remove_lines.append("no port-object eq " + i)
+ if description:
+ if description != have_description:
+ if (
+ "object-group service {0} {1}".format(name, protocol)
+ not in commands
+ ):
+ commands.append(
+ "object-group service {0} {1}".format(
+ name, protocol
+ )
+ )
+ commands.append("description {0}".format(description))
+
+ elif "service-object" in group_type:
+
+ if have_group_type is None:
+ commands.append("object-group service {0}".format(name))
+
+ if description:
+ if have_description is None:
+ commands.append("description {0}".format(description))
+ if service_cfg:
+ for i in service_cfg:
+ commands.append("service-object " + i)
+
+ elif "service" in have_group_type:
+ if description:
+ if description != have_description:
+ if "object-group service {0}".format(name) not in commands:
+ commands.append(
+ "object-group service {0}".format(name)
+ )
+ commands.append("description {0}".format(description))
+ if service_cfg:
+ for i in service_cfg:
+ if i not in have_service_cfg:
+ if (
+ "object-group service {0}".format(name)
+ not in commands
+ ):
+ commands.append(
+ "object-group service {0}".format(name)
+ )
+ add_lines.append("service " + i)
+ for i in have_service_cfg:
+ if i not in service_cfg:
+ if (
+ "object-group service {0}".format(name)
+ not in commands
+ ):
+ commands.append(
+ "object-group service {0}".format(name)
+ )
+ remove_lines.append("no service " + i)
+
+ set_add_lines = set(add_lines)
+ set_remove_lines = set(remove_lines)
+
+ for i in list(set_add_lines) + list(set_remove_lines):
+ commands.append(i)
+
+ return commands
+
+
+def present(want_dict, have):
+
+ commands = list()
+
+ have_group_type = have[0].get("have_group_type")
+ have_description = have[0].get("have_description")
+ have_host_ip = have[0].get("have_host_ip")
+ have_group_object = have[0].get("have_group_object")
+ have_ip_mask = have[0].get("have_ip_mask")
+ have_protocol = have[0].get("have_protocol")
+ have_port_range = have[0].get("have_port_range")
+ have_port_eq = have[0].get("have_port_eq")
+ have_service_cfg = have[0].get("have_service_cfg")
+
+ name = want_dict["name"]
+ group_type = want_dict["group_type"]
+ protocol = want_dict["protocol"]
+ description = want_dict["description"]
+ host = want_dict["host_ip"]
+ group_object = want_dict["group_object"]
+ address = want_dict["ip_mask"]
+ port_range = want_dict["port_range"]
+ port_eq = want_dict["port_eq"]
+ service_cfg = want_dict["service_cfg"]
+
+ if "network-object" in group_type:
+
+ if have_group_type is None:
+ commands.append("object-group network {0}".format(name))
+
+ if host:
+ for i in host:
+ commands.append("network-object host " + i)
+ if description:
+ if have_description is None:
+ commands.append("description {0}".format(description))
+ if group_object:
+ for i in group_object:
+ commands.append("group-object " + i)
+ if address:
+ for i in address:
+ commands.append("network-object " + i)
+
+ elif "network" in have_group_type:
+
+ if host:
+ for i in host:
+ if i not in have_host_ip:
+ if (
+ "object-group network {0}".format(name)
+ not in commands
+ ):
+ commands.append(
+ "object-group network {0}".format(name)
+ )
+ commands.append("network-object host " + i)
+ if description:
+ if description != have_description:
+ if "object-group network {0}".format(name) not in commands:
+ commands.append(
+ "object-group network {0}".format(name)
+ )
+ commands.append("description {0}".format(description))
+ if group_object:
+ for i in group_object:
+ if i not in have_group_object:
+ if (
+ "object-group network {0}".format(name)
+ not in commands
+ ):
+ commands.append(
+ "object-group network {0}".format(name)
+ )
+ commands.append("group-object " + i)
+ if address:
+ for i in address:
+ if i not in have_ip_mask:
+ if (
+ "object-group network {0}".format(name)
+ not in commands
+ ):
+ commands.append(
+ "object-group network {0}".format(name)
+ )
+ commands.append("network-object " + i)
+
+ elif "port-object" in group_type:
+
+ if have_group_type is None and have_protocol != protocol:
+ commands.append(
+ "object-group service {0} {1}".format(name, protocol)
+ )
+
+ if port_range:
+ for i in port_range:
+ commands.append("port-object range " + i)
+ if port_eq:
+ for i in port_eq:
+ commands.append("port-object eq " + i)
+ if description:
+ commands.append("description {0}".format(description))
+
+ elif "port" in have_group_type and have_protocol == protocol:
+
+ if port_range:
+ for i in port_range:
+ if i not in have_port_range:
+ if (
+ "object-group service {0} {1}".format(
+ name, protocol
+ )
+ not in commands
+ ):
+ commands.append(
+ "object-group service {0} {1}".format(
+ name, protocol
+ )
+ )
+ commands.append("port-object range " + i)
+ if port_eq:
+ for i in port_eq:
+ if i not in have_port_eq:
+ if (
+ "object-group service {0} {1}".format(
+ name, protocol
+ )
+ not in commands
+ ):
+ commands.append(
+ "object-group service {0} {1}".format(
+ name, protocol
+ )
+ )
+ commands.append("port-object eq " + i)
+ if description:
+ if description != have_description:
+ if (
+ "object-group service {0} {1}".format(name, protocol)
+ not in commands
+ ):
+ commands.append(
+ "object-group service {0} {1}".format(
+ name, protocol
+ )
+ )
+ commands.append("description {0}".format(description))
+
+ elif "service-object" in group_type:
+
+ if have_group_type is None:
+ commands.append("object-group service {0}".format(name))
+
+ if description:
+ if have_description is None:
+ commands.append("description {0}".format(description))
+ if service_cfg:
+ for i in service_cfg:
+ commands.append("service-object " + i)
+
+ elif "service" in have_group_type:
+
+ if description:
+ if description != have_description:
+ if "object-group service {0}".format(name) not in commands:
+ commands.append(
+ "object-group service {0}".format(name)
+ )
+ commands.append("description {0}".format(description))
+ if service_cfg:
+ for i in service_cfg:
+ if i not in have_service_cfg:
+ if (
+ "object-group service {0}".format(name)
+ not in commands
+ ):
+ commands.append(
+ "object-group service {0}".format(name)
+ )
+ commands.append("service " + i)
+
+ return commands
+
+
+def absent(want_dict, have):
+
+ commands = list()
+
+ have_group_type = have[0].get("have_group_type")
+ have_description = have[0].get("have_description")
+ have_host_ip = have[0].get("have_host_ip")
+ have_group_object = have[0].get("have_group_object")
+ have_ip_mask = have[0].get("have_ip_mask")
+ have_protocol = have[0].get("have_protocol")
+ have_port_range = have[0].get("have_port_range")
+ have_port_eq = have[0].get("have_port_eq")
+ have_service_cfg = have[0].get("have_service_cfg")
+
+ name = want_dict["name"]
+ group_type = want_dict["group_type"]
+ protocol = want_dict["protocol"]
+ description = want_dict["description"]
+ host = want_dict["host_ip"]
+ group_object = want_dict["group_object"]
+ address = want_dict["ip_mask"]
+ port_range = want_dict["port_range"]
+ port_eq = want_dict["port_eq"]
+ service_cfg = want_dict["service_cfg"]
+
+ if "network-object" in group_type:
+
+ if have_group_type is None:
+ return commands
+
+ elif "network" in have_group_type:
+
+ if host:
+ for i in host:
+ if i in have_host_ip:
+ if (
+ "object-group network {0}".format(name)
+ not in commands
+ ):
+ commands.append(
+ "object-group network {0}".format(name)
+ )
+ commands.append("no network-object host " + i)
+ if description:
+ if description == have_description:
+ if "object-group network {0}".format(name) not in commands:
+ commands.append(
+ "object-group network {0}".format(name)
+ )
+ commands.append("no description {0}".format(description))
+ if group_object:
+ for i in group_object:
+ if i in have_group_object:
+ if (
+ "object-group network {0}".format(name)
+ not in commands
+ ):
+ commands.append(
+ "object-group network {0}".format(name)
+ )
+ commands.append("no group-object " + i)
+ if address:
+ for i in address:
+ if i in have_ip_mask:
+ if (
+ "object-group network {0}".format(name)
+ not in commands
+ ):
+ commands.append(
+ "object-group network {0}".format(name)
+ )
+ commands.append("no network-object " + i)
+
+ elif "port-object" in group_type:
+
+ if have_group_type is None and have_protocol is None:
+ return commands
+
+ elif "port" in have_group_type and have_protocol == protocol:
+
+ if port_range:
+ for i in port_range:
+ if i in have_port_range:
+ if (
+ "object-group service {0} {1}".format(
+ name, protocol
+ )
+ not in commands
+ ):
+ commands.append(
+ "object-group service {0} {1}".format(
+ name, protocol
+ )
+ )
+ commands.append("no port-object range " + i)
+ if port_eq:
+ for i in port_eq:
+ if i in have_port_eq:
+ if (
+ "object-group service {0} {1}".format(
+ name, protocol
+ )
+ not in commands
+ ):
+ commands.append(
+ "object-group service {0} {1}".format(
+ name, protocol
+ )
+ )
+ commands.append("no port-object eq " + i)
+ if description:
+ if description == have_description:
+ if (
+ "object-group service {0} {1}".format(name, protocol)
+ not in commands
+ ):
+ commands.append(
+ "object-group service {0} {1}".format(
+ name, protocol
+ )
+ )
+ commands.append("no description {0}".format(description))
+
+ elif "service-object" in group_type:
+
+ if have_group_type is None:
+ return commands
+
+ elif "service" in have_group_type:
+ if description:
+ if description == have_description:
+ if "object-group service {0}".format(name) not in commands:
+ commands.append(
+ "object-group service {0}".format(name)
+ )
+ commands.append("no description {0}".format(description))
+ if service_cfg:
+ for i in service_cfg:
+ if i in have_service_cfg:
+ if (
+ "object-group service {0}".format(name)
+ not in commands
+ ):
+ commands.append(
+ "object-group service {0}".format(name)
+ )
+ commands.append("no service " + i)
+
+ return commands
+
+
+def map_obj_to_commands(want, have, module):
+
+ for w in want:
+
+ want_dict = dict()
+
+ want_dict["name"] = w["name"]
+ want_dict["group_type"] = w["group_type"]
+ want_dict["protocol"] = w["protocol"]
+ want_dict["description"] = w["description"]
+ want_dict["host_ip"] = w["host_ip"]
+ want_dict["group_object"] = w["group_object"]
+ want_dict["ip_mask"] = w["ip_mask"]
+ want_dict["port_range"] = w["port_range"]
+ want_dict["port_eq"] = w["port_eq"]
+ want_dict["service_cfg"] = w["service_cfg"]
+ state = w["state"]
+
+ if state == "replace":
+ return replace(want_dict, have)
+ elif state == "present":
+ return present(want_dict, have)
+ elif state == "absent":
+ return absent(want_dict, have)
+
+
+def map_params_to_obj(module):
+
+ obj = list()
+
+ obj.append(
+ {
+ "name": module.params["name"],
+ "group_type": module.params["group_type"],
+ "protocol": module.params["protocol"],
+ "state": module.params["state"],
+ "description": module.params["description"],
+ "host_ip": module.params["host_ip"],
+ "group_object": module.params["group_object"],
+ "port_range": module.params["port_range"],
+ "port_eq": module.params["port_eq"],
+ "service_cfg": module.params["service_cfg"],
+ "ip_mask": module.params["ip_mask"],
+ }
+ )
+
+ return obj
+
+
+def main():
+
+ argument_spec = dict(
+ name=dict(required=True),
+ group_type=dict(
+ choices=["network-object", "service-object", "port-object"],
+ required=True,
+ ),
+ protocol=dict(choices=["udp", "tcp", "tcp-udp"]),
+ host_ip=dict(type="list", elements="str"),
+ description=dict(),
+ group_object=dict(type="list", elements="str"),
+ ip_mask=dict(type="list", elements="str"),
+ port_range=dict(type="list"),
+ port_eq=dict(type="list", elements="str"),
+ service_cfg=dict(type="list", elements="str"),
+ state=dict(
+ choices=["present", "absent", "replace"], default="present"
+ ),
+ )
+
+ required_if = [
+ ("group_type", "port-object", ["protocol"]),
+ ("group_type", "service-object", ["service_cfg"]),
+ ]
+
+ module = AnsibleModule(
+ argument_spec=argument_spec,
+ required_if=required_if,
+ supports_check_mode=True,
+ )
+
+ result = {"changed": False}
+
+ want = map_params_to_obj(module)
+ have = map_config_to_obj(module)
+ config_commans = map_obj_to_commands(want, have, module)
+
+ result["commands"] = config_commans
+
+ if config_commans:
+ if not module.check_mode:
+ load_config(module, config_commans)
+ result["changed"] = True
+
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/modules/asa_ogs.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/modules/asa_ogs.py
new file mode 100644
index 00000000..5792bc80
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/modules/asa_ogs.py
@@ -0,0 +1,892 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright 2019 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+#############################################
+# WARNING #
+#############################################
+#
+# This file is auto generated by the resource
+# module builder playbook.
+#
+# Do not edit this file manually.
+#
+# Changes to this file will be over written
+# by the resource module builder.
+#
+# Changes should be made in the model used to
+# generate this file or in the resource module
+# builder template.
+#
+#############################################
+
+"""
+The module file for asa_ogs
+"""
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+
+DOCUMENTATION = """
+module: asa_ogs
+short_description: Object Group resource module
+description: This module configures and manages Objects and Groups on ASA platforms.
+version_added: 1.0.0
+author: Sumit Jaiswal (@justjais)
+notes:
+- Tested against Cisco ASA Version 9.10(1)11
+- This module works with connection C(network_cli). See L(ASA Platform Options,../network/user_guide/platform_asa.html).
+options:
+ config:
+ description: A list of Object Group options.
+ type: list
+ elements: dict
+ suboptions:
+ object_type:
+ description: The object group type.
+ type: str
+ required: true
+ choices:
+ - icmp-type
+ - network
+ - protocol
+ - security
+ - service
+ - user
+ object_groups:
+ description: The object groups.
+ type: list
+ elements: dict
+ suboptions:
+ name:
+ description: Specifies object-group ID
+ required: true
+ type: str
+ description:
+ description: The description for the object-group.
+ type: str
+ icmp_type:
+ description: Configure an ICMP-type object
+ type: dict
+ suboptions:
+ icmp_object:
+ description: Defines the ICMP types in the group.
+ type: list
+ elements: str
+ choices: [alternate-address, conversion-error, echo, echo-reply, information-reply,
+ information-request, mask-reply, mask-request, mobile-redirect,
+ parameter-problem, redirect, router-advertisement, router-solicitation,
+ source-quench, time-exceeded, timestamp-reply, timestamp-request,
+ traceroute, unreachable]
+ network_object:
+ description: Configure a network object
+ type: dict
+ suboptions:
+ host:
+ description: Set this to specify a single host object.
+ type: list
+ elements: str
+ address:
+ description: Enter an IPv4 network address with space seperated netmask.
+ type: list
+ elements: str
+ ipv6_address:
+ description: Enter an IPv6 prefix.
+ type: list
+ elements: str
+ protocol_object:
+ description: Configure a protocol object
+ type: dict
+ suboptions:
+ protocol:
+ description: Defines the protocols in the group.
+ type: list
+ elements: str
+ choices: [ah, eigrp, esp, gre, icmp, icmp6, igmp, igrp, ip, ipinip,
+ ipsec, nos, ospf, pcp, pim, pptp, sctp, snp, tcp, udp]
+ security_group:
+ description: Configure a security-group
+ type: dict
+ suboptions:
+ sec_name:
+ description: Enter this keyword to specify a security-group name.
+ type: list
+ elements: str
+ tag:
+ description: Enter this keyword to specify a security-group tag.
+ type: list
+ elements: str
+ service_object:
+ description: Configure a service object
+ type: dict
+ suboptions:
+ protocol:
+ description: Defines the protocols in the group.
+ type: list
+ elements: str
+ choices: [ah, eigrp, esp, gre, icmp, icmp6, igmp, igrp, ip, ipinip,
+ ipsec, nos, ospf, pcp, pim, pptp, sctp, snp, tcp, tcp-udp, udp]
+ object:
+ description: Enter this keyword to specify a service object
+ type: str
+ user_object:
+ description: Configures single user, local or import user group
+ type: dict
+ suboptions:
+ user:
+ description: Configure a user objectUser name to configure a user
+ object.
+ type: list
+ elements: dict
+ suboptions:
+ name:
+ description: Enter the name of the user
+ type: str
+ required: true
+ domain:
+ description: User domain
+ type: str
+ required: true
+ user_group:
+ description: Configure a user group object.
+ type: list
+ elements: dict
+ suboptions:
+ name:
+ description: Enter the name of the group
+ type: str
+ required: true
+ domain:
+ description: Group domain
+ type: str
+ required: true
+ running_config:
+ description:
+ - The module, by default, will connect to the remote device and retrieve the current
+ running-config to use as a base for comparing against the contents of source.
+ There are times when it is not desirable to have the task get the current running-config
+ for every task in a playbook. The I(running_config) argument allows the implementer
+ to pass in the configuration to use as the base config for comparison. This
+ value of this option should be the output received from device by executing
+ command.
+ type: str
+ state:
+ description:
+ - The state the configuration should be left in
+ type: str
+ choices:
+ - merged
+ - replaced
+ - overridden
+ - deleted
+ - gathered
+ - rendered
+ - parsed
+ default: merged
+"""
+
+EXAMPLES = """
+
+# Using merged
+
+# Before state:
+# -------------
+#
+# ciscoasa# sh running-config object-group
+# object-group network test_og_network
+# description test_network_og
+# network-object host 192.0.3.1
+
+- name: "Merge module attributes of given object-group"
+ cisco.asa.asa_ogs:
+ config:
+ - object_type: network
+ object_groups:
+ - name: test_og_network
+ description: test_og_network
+ network_object:
+ host:
+ - 192.0.2.1
+ - 192.0.2.2
+ address:
+ - 192.0.2.0 255.255.255.0
+ - 198.51.100.0 255.255.255.0
+ - name: test_network_og
+ description: test_network_og
+ network_object:
+ host:
+ - 192.0.3.1
+ - 192.0.3.2
+ ipv6_address:
+ - 2001:db8:3::/64
+ - object_type: security
+ object_groups:
+ - name: test_og_security
+ description: test_security
+ security_group:
+ sec_name:
+ - test_1
+ - test_2
+ tag:
+ - 10
+ - 20
+ - object_type: user
+ object_groups:
+ - name: test_og_user
+ description: test_user
+ user_object:
+ user:
+ - name: new_user_1
+ domain: LOCAL
+ - name: new_user_2
+ domain: LOCAL
+ state: merged
+
+# Commands fired:
+# ---------------
+#
+# object-group security test_og_security
+# description test_security
+# security-group name test_1
+# security-group name test_2
+# security-group tag 10
+# security-group tag 20
+# object-group network test_og_network
+# description test_og_network
+# network-object 192.0.2.0 255.255.255.0
+# network-object 198.51.100.0 255.255.255.0
+# network-object host 192.0.2.1
+# network-object host 192.0.2.2
+# object-group network test_network_og
+# network-object host 192.0.3.1
+# network-object host 192.0.3.2
+# network-object 2001:db8:3::/64
+# object-group user test_og_user
+# description test_user
+# user LOCAL\\new_user_1
+# user LOCAL\\new_user_2
+
+# After state:
+# ------------
+#
+# ciscoasa# sh running-config object-group
+# object-group network test_og_network
+# description test_og_network
+# network-object host 192.0.2.1
+# network-object host 192.0.2.2
+# network-object 192.0.2.0 255.255.255.0
+# network-object 198.51.100.0 255.255.255.0
+# network-object host 192.0.3.1
+# 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
+# group-object test_og_network
+# object-group security test_og_security
+# security-group name test_1
+# security-group name test_2
+# security-group tag 10
+# security-group tag 20
+# object-group user test_og_user
+# description test_user
+# user LOCAL\\new_user_1
+# user LOCAL\\new_user_2
+
+# Using Replaced
+
+# Before state:
+# -------------
+#
+# ciscoasa# sh running-config object-group
+# object-group network test_og_network
+# description test_og_network
+# network-object host 192.0.2.1
+# network-object host 192.0.2.2
+# network-object 192.0.2.0 255.255.255.0
+# network-object 198.51.100.0 255.255.255.0
+# 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
+# group-object test_og_network
+# object-group security test_og_security
+# security-group name test_1
+# security-group name test_2
+# security-group tag 10
+# security-group tag 20
+# object-group user test_og_user
+# user LOCAL\\new_user_1
+# user LOCAL\\new_user_2
+
+- name: "Replace module attributes of given object-group"
+ cisco.asa.asa_ogs:
+ config:
+ - object_type: network
+ object_groups:
+ - name: test_og_network
+ description: test_og_network_replace
+ network_object:
+ host:
+ - 192.0.3.1
+ address:
+ - 192.0.3.0 255.255.255.0
+ - object_type: protocol
+ object_groups:
+ - name: test_og_protocol
+ description: test_og_protocol
+ protocol_object:
+ protocol:
+ - tcp
+ - udp
+ state: replaced
+
+# Commands Fired:
+# ---------------
+#
+# object-group protocol test_og_protocol
+# description test_og_protocol
+# protocol tcp
+# protocol udp
+# object-group network test_og_network
+# description test_og_network_replace
+# no network-object 192.0.2.0 255.255.255.0
+# no network-object 198.51.100.0 255.255.255.0
+# network-object 192.0.3.0 255.255.255.0
+# no network-object host 192.0.2.1
+# no network-object host 192.0.2.2
+# network-object host 192.0.3.1
+
+# After state:
+# -------------
+#
+# ciscoasa# sh running-config object-group
+# object-group network test_og_network
+# description test_og_network_replace
+# network-object host 192.0.3.1
+# network-object 192.0.3.0 255.255.255.0
+# 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
+# group-object test_og_network
+# object-group security test_og_security
+# security-group name test_1
+# security-group name test_2
+# security-group tag 10
+# security-group tag 20
+# object-group user test_og_user
+# user LOCAL\\new_user_1
+# user LOCAL\\new_user_2
+# object-group protocol test_og_protocol
+# protocol-object tcp
+# protocol-object udp
+
+# Using Overridden
+
+# Before state:
+# -------------
+#
+# ciscoasa# sh running-config object-group
+# object-group network test_og_network
+# description test_og_network
+# network-object host 192.0.2.1
+# network-object host 192.0.2.2
+# network-object 192.0.2.0 255.255.255.0
+# network-object 198.51.100.0 255.255.255.0
+# 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
+# group-object test_og_network
+# object-group security test_og_security
+# security-group name test_1
+# security-group name test_2
+# security-group tag 10
+# security-group tag 20
+# object-group user test_og_user
+# user LOCAL\\new_user_1
+# user LOCAL\\new_user_2
+
+- name: "Overridden module attributes of given object-group"
+ cisco.asa.asa_ogs:
+ config:
+ - object_type: network
+ object_groups:
+ - name: test_og_network
+ description: test_og_network_override
+ network_object:
+ host:
+ - 192.0.3.1
+ address:
+ - 192.0.3.0 255.255.255.0
+ - object_type: protocol
+ object_groups:
+ - name: test_og_protocol
+ description: test_og_protocol
+ protocol_object:
+ protocol:
+ - tcp
+ - udp
+ state: overridden
+
+# Commands Fired:
+# ---------------
+#
+# no object-group security test_og_security
+# no object-group user test_og_user
+# object-group protocol test_og_protocol
+# description test_og_protocol
+# protocol tcp
+# protocol udp
+# object-group network test_og_network
+# description test_og_network_override
+# no network-object 192.0.2.0 255.255.255.0
+# no network-object 198.51.100.0 255.255.255.0
+# network-object 192.0.3.0 255.255.255.0
+# no network-object host 192.0.2.1
+# no network-object host 192.0.2.2
+# network-object host 192.0.3.1
+# no object-group network test_network_og
+
+# After state:
+# -------------
+#
+# ciscoasa# sh running-config object-group
+# object-group network test_og_network
+# description test_og_network_override
+# network-object host 192.0.3.1
+# network-object 192.0.3.0 255.255.255.0
+# object-group protocol test_og_protocol
+# protocol-object tcp
+# protocol-object udp
+
+# Using Deleted
+
+# Before state:
+# -------------
+#
+# ciscoasa# sh running-config object-group
+# object-group network test_og_network
+# description test_og_network
+# network-object host 192.0.2.1
+# network-object host 192.0.2.2
+# network-object 192.0.2.0 255.255.255.0
+# network-object 198.51.100.0 255.255.255.0
+# 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
+# group-object test_og_network
+# object-group security test_og_security
+# security-group name test_1
+# security-group name test_2
+# security-group tag 10
+# security-group tag 20
+# object-group user test_og_user
+# user LOCAL\\new_user_1
+# user LOCAL\\new_user_2
+
+- name: "Delete given module attributes"
+ cisco.asa.asa_ogs:
+ config:
+ - object_type: network
+ object_groups:
+ - name: test_og_network
+ - name: test_network_og
+ - object_type: security
+ object_groups:
+ - name: test_og_security
+ state: deleted
+
+# Commands Fired:
+# ---------------
+#
+# no object-group network test_og_network
+# no object-group network test_network_og
+# no object-group security test_og_security
+
+# After state:
+# -------------
+#
+# ciscoasa# sh running-config object-group
+# object-group user test_og_user
+# user LOCAL\\new_user_1
+# user LOCAL\\new_user_2
+
+# Using DELETED without any config passed
+#"(NOTE: This will delete all of configured resource module attributes)"
+
+# Before state:
+# -------------
+#
+# ciscoasa# sh running-config object-group
+# object-group network test_og_network
+# description test_og_network
+# network-object host 192.0.2.1
+# network-object host 192.0.2.2
+# network-object 192.0.2.0 255.255.255.0
+# network-object 198.51.100.0 255.255.255.0
+# 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
+# group-object test_og_network
+# object-group security test_og_security
+# security-group name test_1
+# security-group name test_2
+# security-group tag 10
+# security-group tag 20
+# object-group user test_og_user
+# user LOCAL\\new_user_1
+# user LOCAL\\new_user_2
+
+- name: Delete ALL configured module attributes
+ cisco.asa.asa_ogs:
+ config:
+ state: deleted
+
+# Commands Fired:
+# ---------------
+#
+# no object-group network test_og_network
+# no object-group network test_network_og
+# no object-group security test_og_security
+# no object-group user test_og_user
+
+# After state:
+# -------------
+#
+# ciscoasa# sh running-config object-group
+
+# Using Gathered
+
+# Before state:
+# -------------
+#
+# ciscoasa# sh running-config object-group
+# object-group network test_og_network
+# description test_og_network
+# network-object host 192.0.2.1
+# network-object host 192.0.2.2
+# network-object 192.0.2.0 255.255.255.0
+# network-object 198.51.100.0 255.255.255.0
+# 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
+# group-object test_og_network
+# object-group security test_og_security
+# security-group name test_1
+# security-group name test_2
+# security-group tag 10
+# security-group tag 20
+# object-group user test_og_user
+# user LOCAL\\new_user_1
+# user LOCAL\\new_user_2
+
+- name: Gather listed OGs with provided configurations
+ cisco.asa.asa_ogs:
+ config:
+ state: gathered
+
+# Module Execution Result:
+# ------------------------
+#
+# "gathered": [
+# {
+# "object_groups": [
+# {
+# "description": "test_security",
+# "name": "test_og_security",
+# "security_group": {
+# "sec_name": [
+# "test_2",
+# "test_1"
+# ],
+# "tag": [
+# 10,
+# 20
+# ]
+# }
+# }
+# ],
+# "object_type": "security"
+# },
+# {
+# "object_groups": [
+# {
+# "description": "test_network_og",
+# "name": "test_network_og",
+# "network_object": {
+# "host": [
+# "192.0.3.1",
+# "192.0.3.2"
+# ],
+# "ipv6_address": [
+# "2001:db8:3::/64"
+# ]
+# }
+# },
+# {
+# "description": "test_og_network",
+# "name": "test_og_network",
+# "network_object": {
+# "address": [
+# "192.0.2.0 255.255.255.0",
+# "198.51.100.0 255.255.255.0"
+# ],
+# "host": [
+# "192.0.2.1",
+# "192.0.2.2"
+# ]
+# }
+# }
+# ],
+# "object_type": "network"
+# },
+# {
+# "object_groups": [
+# {
+# "description": "test_user",
+# "name": "test_og_user",
+# "user_object": {
+# "user": [
+# {
+# "domain": "LOCAL",
+# "name": "new_user_1"
+# },
+# {
+# "domain": "LOCAL",
+# "name": "new_user_2"
+# }
+# ]
+# }
+# }
+# ],
+# "object_type": "user"
+# }
+# ]
+
+# After state:
+# ------------
+#
+# ciscoasa# sh running-config object-group
+# object-group network test_og_network
+# description test_og_network
+# network-object host 192.0.2.1
+# network-object host 192.0.2.2
+# network-object 192.0.2.0 255.255.255.0
+# network-object 198.51.100.0 255.255.255.0
+# 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
+# group-object test_og_network
+# object-group security test_og_security
+# security-group name test_1
+# security-group name test_2
+# security-group tag 10
+# security-group tag 20
+# object-group user test_og_user
+# user LOCAL\\new_user_1
+# user LOCAL\\new_user_2
+
+# Using Rendered
+
+- name: Render the commands for provided configuration
+ cisco.asa.asa_ogs:
+ config:
+ - object_type: network
+ object_groups:
+ - name: test_og_network
+ description: test_og_network
+ network_object:
+ host:
+ - 192.0.2.1
+ - 192.0.2.2
+ address:
+ - 192.0.2.0 255.255.255.0
+ - 198.51.100.0 255.255.255.0
+ - name: test_network_og
+ description: test_network_og
+ network_object:
+ host:
+ - 192.0.3.1
+ - 192.0.3.2
+ ipv6_address:
+ - 2001:db8:3::/64
+ - object_type: security
+ object_groups:
+ - name: test_og_security
+ description: test_security
+ security_group:
+ sec_name:
+ - test_1
+ - test_2
+ tag:
+ - 10
+ - 20
+ - object_type: user
+ object_groups:
+ - name: test_og_user
+ description: test_user
+ user_object:
+ user:
+ - name: new_user_1
+ domain: LOCAL
+ - name: new_user_2
+ domain: LOCAL
+ state: rendered
+
+# Module Execution Result:
+# ------------------------
+#
+# "rendered": [
+# "object-group security test_og_security",
+# "description test_security",
+# "security-group name test_1",
+# "security-group name test_2",
+# "security-group tag 10",
+# "security-group tag 20",
+# "object-group network test_og_network",
+# "description test_og_network",
+# "network-object 192.0.2.0 255.255.255.0",
+# "network-object 198.51.100.0 255.255.255.0",
+# "network-object host 192.0.2.1",
+# "network-object host 192.0.2.2",
+# "object-group network test_network_og",
+# "description test_network_og",
+# "network-object host 192.0.3.1",
+# "network-object host 192.0.3.2",
+# "network-object 2001:db8:3::/64",
+# "object-group user test_og_user",
+# "description test_user",
+# "user LOCAL\\new_user_1",
+# "user LOCAL\\new_user_2"
+# ]
+
+# Using Parsed
+
+# parsed.cfg
+#
+# object-group network test_og_network
+# description test_og_network
+# network-object host 192.0.2.1
+# network-object 192.0.2.0 255.255.255.0
+# object-group network test_network_og
+# network-object 2001:db8:3::/64
+# object-group service test_og_service
+# service-object tcp-udp
+
+- name: Parse the commands for provided configuration
+ cisco.asa.asa_ogs:
+ running_config: "{{ lookup('file', 'parsed.cfg') }}"
+ state: parsed
+
+# Module Execution Result:
+# ------------------------
+#
+# "parsed": [
+# {
+# "object_groups": [
+# {
+# "name": "test_network_og"
+# },
+# {
+# "description": "test_og_network",
+# "name": "test_og_network",
+# "network_object": {
+# "host": [
+# "192.0.2.2"
+# ]
+# }
+# }
+# ],
+# "object_type": "network"
+# },
+# {
+# "object_groups": [
+# {
+# "name": "test_og_service",
+# "service_object": {
+# "protocol": [
+# "tcp-udp",
+# "ipinip"
+# ]
+# }
+# }
+# ],
+# "object_type": "service"
+# }
+# ]
+
+"""
+
+RETURN = """
+before:
+ description: The configuration as structured data prior to module invocation.
+ returned: always
+ type: list
+ sample: The configuration returned will always be in the same format of the parameters above.
+after:
+ description: The configuration as structured data after module completion.
+ returned: when changed
+ type: list
+ sample: The configuration returned will always be in the same format of the parameters above.
+commands:
+ description: The set of commands pushed to the remote device
+ returned: always
+ type: list
+ sample: ['object-group network test_network_og', 'description test_network_og', 'network-object host 192.0.2.1']
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible_collections.cisco.asa.plugins.module_utils.network.asa.argspec.ogs.ogs import (
+ OGsArgs,
+)
+from ansible_collections.cisco.asa.plugins.module_utils.network.asa.config.ogs.ogs import (
+ OGs,
+)
+
+
+def main():
+ """
+ Main entry point for module execution
+ :returns: the result form module invocation
+ """
+
+ required_if = [
+ ("state", "merged", ("config",)),
+ ("state", "replaced", ("config",)),
+ ("state", "overridden", ("config",)),
+ ("state", "rendered", ("config",)),
+ ("state", "parsed", ("running_config",)),
+ ]
+
+ mutually_exclusive = [("config", "running_config")]
+
+ module = AnsibleModule(
+ argument_spec=OGsArgs.argument_spec,
+ required_if=required_if,
+ mutually_exclusive=mutually_exclusive,
+ supports_check_mode=True,
+ )
+ result = OGs(module).execute_module()
+
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/terminal/__init__.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/terminal/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/terminal/__init__.py
diff --git a/collections-debian-merged/ansible_collections/cisco/asa/plugins/terminal/asa.py b/collections-debian-merged/ansible_collections/cisco/asa/plugins/terminal/asa.py
new file mode 100644
index 00000000..83f33918
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/cisco/asa/plugins/terminal/asa.py
@@ -0,0 +1,76 @@
+#
+# (c) 2016 Red Hat Inc.
+#
+# This file is part of Ansible
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
+#
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+import re
+import json
+
+from ansible.errors import AnsibleConnectionFailure
+from ansible.module_utils._text import to_text, to_bytes
+from ansible.plugins.terminal import TerminalBase
+
+
+class TerminalModule(TerminalBase):
+
+ terminal_stdout_re = [
+ re.compile(br"[\r\n]?[\w+\-\.:\/\[\]]+(?:\([^\)]+\)){,3}(?:>|#) ?$"),
+ re.compile(br"\[\w+\@[\w\-\.]+(?: [^\]])\] ?[>#\$] ?$"),
+ ]
+
+ terminal_stderr_re = [
+ re.compile(br"error:", re.I),
+ re.compile(br"Removing.* not allowed, it is being used"),
+ re.compile(br"^Command authorization failed\r?$", re.MULTILINE),
+ ]
+
+ def on_open_shell(self):
+ if self._get_prompt().strip().endswith(b"#"):
+ self.disable_pager()
+
+ def disable_pager(self):
+ try:
+ self._exec_cli_command(u"no terminal pager")
+ except AnsibleConnectionFailure:
+ raise AnsibleConnectionFailure("unable to disable terminal pager")
+
+ def on_become(self, passwd=None):
+ if self._get_prompt().strip().endswith(b"#"):
+ return
+
+ cmd = {u"command": u"enable"}
+ if passwd:
+ # Note: python-3.5 cannot combine u"" and r"" together. Thus make
+ # an r string and use to_text to ensure it's text on both py2 and py3.
+ cmd[u"prompt"] = to_text(
+ r"[\r\n]?[Pp]assword: $", errors="surrogate_or_strict"
+ )
+ cmd[u"answer"] = passwd
+
+ try:
+ self._exec_cli_command(
+ to_bytes(json.dumps(cmd), errors="surrogate_or_strict")
+ )
+ except AnsibleConnectionFailure:
+ raise AnsibleConnectionFailure(
+ "unable to elevate privilege to enable mode"
+ )
+
+ self.disable_pager()