summaryrefslogtreecommitdiffstats
path: root/collections-debian-merged/ansible_collections/community/fortios/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'collections-debian-merged/ansible_collections/community/fortios/plugins')
-rw-r--r--collections-debian-merged/ansible_collections/community/fortios/plugins/httpapi/fortianalyzer.py453
-rw-r--r--collections-debian-merged/ansible_collections/community/fortios/plugins/httpapi/fortimanager.py459
-rw-r--r--collections-debian-merged/ansible_collections/community/fortios/plugins/module_utils/fortianalyzer/common.py291
-rw-r--r--collections-debian-merged/ansible_collections/community/fortios/plugins/module_utils/fortianalyzer/fortianalyzer.py476
-rw-r--r--collections-debian-merged/ansible_collections/community/fortios/plugins/modules/faz_device.py432
-rw-r--r--collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_device.py296
-rw-r--r--collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_device_config.py231
-rw-r--r--collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_device_group.py323
-rw-r--r--collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_device_provision_template.py1546
-rw-r--r--collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_fwobj_address.py661
-rw-r--r--collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_fwobj_ippool.py442
-rw-r--r--collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_fwobj_ippool6.py223
-rw-r--r--collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_fwobj_service.py617
-rw-r--r--collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_fwobj_vip.py2424
-rw-r--r--collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_fwpol_ipv4.py1355
-rw-r--r--collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_fwpol_package.py479
-rw-r--r--collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_ha.py349
-rw-r--r--collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_provisioning.py360
-rw-r--r--collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_query.py424
-rw-r--r--collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_script.py262
-rw-r--r--collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_appctrl.py516
-rw-r--r--collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_av.py1386
-rw-r--r--collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_dns.py339
-rw-r--r--collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_ips.py664
-rw-r--r--collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_profile_group.py287
-rw-r--r--collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_proxy.py332
-rw-r--r--collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_spam.py607
-rw-r--r--collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_ssl_ssh.py954
-rw-r--r--collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_voip.py1198
-rw-r--r--collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_waf.py1477
-rw-r--r--collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_wanopt.py685
-rw-r--r--collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_web.py1081
32 files changed, 21629 insertions, 0 deletions
diff --git a/collections-debian-merged/ansible_collections/community/fortios/plugins/httpapi/fortianalyzer.py b/collections-debian-merged/ansible_collections/community/fortios/plugins/httpapi/fortianalyzer.py
new file mode 100644
index 00000000..0e59ea48
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/community/fortios/plugins/httpapi/fortianalyzer.py
@@ -0,0 +1,453 @@
+# Copyright (c) 2018 Fortinet and/or its affiliates.
+#
+# 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:
+ - Luke Weighall (@lweighall)
+ - Andrew Welsh (@Ghilli3)
+ - Jim Huber (@p4r4n0y1ng)
+name: fortianalyzer
+short_description: HttpApi Plugin for Fortinet FortiAnalyzer Appliance or VM.
+description:
+ - This HttpApi plugin provides methods to connect to Fortinet FortiAnalyzer Appliance or VM via JSON RPC API.
+
+'''
+
+import json
+from ansible.plugins.httpapi import HttpApiBase
+from ansible.module_utils.basic import to_text
+from ansible_collections.community.fortios.plugins.module_utils.fortianalyzer.common import BASE_HEADERS
+from ansible_collections.community.fortios.plugins.module_utils.fortianalyzer.common import FAZBaseException
+from ansible_collections.community.fortios.plugins.module_utils.fortianalyzer.common import FAZCommon
+from ansible_collections.community.fortios.plugins.module_utils.fortianalyzer.common import FAZMethods
+
+
+class HttpApi(HttpApiBase):
+ def __init__(self, connection):
+ super(HttpApi, self).__init__(connection)
+ self._req_id = 0
+ self._sid = None
+ self._url = "/jsonrpc"
+ self._host = None
+ self._tools = FAZCommon
+ self._debug = False
+ self._connected_faz = None
+ self._last_response_msg = None
+ self._last_response_code = None
+ self._last_data_payload = None
+ self._last_url = None
+ self._last_response_raw = None
+ self._locked_adom_list = list()
+ self._locked_adoms_by_user = list()
+ self._uses_workspace = False
+ self._uses_adoms = False
+ self._adom_list = list()
+ self._logged_in_user = None
+
+ def set_become(self, become_context):
+ """
+ ELEVATION IS NOT REQUIRED ON FORTINET DEVICES - SKIPPED
+ :param become_context: Unused input.
+ :return: None
+ """
+ return None
+
+ def update_auth(self, response, response_data):
+ """
+ TOKENS ARE NOT USED SO NO NEED TO UPDATE AUTH
+ :param response: Unused input.
+ :param response_data Unused_input.
+ :return: None
+ """
+ return None
+
+ def login(self, username, password):
+ """
+ This function will log the plugin into FortiAnalyzer, and return the results.
+ :param username: Username of FortiAnalyzer Admin
+ :param password: Password of FortiAnalyzer Admin
+
+ :return: Dictionary of status if it logged in or not.
+ """
+
+ self._logged_in_user = username
+ self.send_request(FAZMethods.EXEC, self._tools.format_request(FAZMethods.EXEC, "sys/login/user",
+ passwd=password, user=username,))
+
+ if "FortiAnalyzer object connected to FortiAnalyzer" in self.__str__():
+ # If Login worked then inspect the FortiAnalyzer for Workspace Mode, and it's system information.
+ self.inspect_faz()
+ return
+ else:
+ raise FAZBaseException(msg="Unknown error while logging in...connection was lost during login operation..."
+ " Exiting")
+
+ def inspect_faz(self):
+ # CHECK FOR WORKSPACE MODE TO SEE IF WE HAVE TO ENABLE ADOM LOCKS
+ status = self.get_system_status()
+ if status[0] == -11:
+ # THE CONNECTION GOT LOST SOMEHOW, REMOVE THE SID AND REPORT BAD LOGIN
+ self.logout()
+ raise FAZBaseException(msg="Error -11 -- the Session ID was likely malformed somehow. Contact authors."
+ " Exiting")
+ elif status[0] == 0:
+ try:
+ self.check_mode()
+ if self._uses_adoms:
+ self.get_adom_list()
+ if self._uses_workspace:
+ self.get_locked_adom_list()
+ self._connected_faz = status[1]
+ self._host = self._connected_faz["Hostname"]
+ except Exception:
+ pass
+ return
+
+ def logout(self):
+ """
+ This function will logout of the FortiAnalyzer.
+ """
+ if self.sid is not None:
+ # IF WE WERE USING WORKSPACES, THEN CLEAN UP OUR LOCKS IF THEY STILL EXIST
+ if self.uses_workspace:
+ self.get_lock_info()
+ self.run_unlock()
+ ret_code, response = self.send_request(FAZMethods.EXEC,
+ self._tools.format_request(FAZMethods.EXEC, "sys/logout"))
+ self.sid = None
+ return ret_code, response
+
+ def send_request(self, method, params):
+ """
+ Responsible for actual sending of data to the connection httpapi base plugin. Does some formatting as well.
+ :param params: A formatted dictionary that was returned by self.common_datagram_params()
+ before being called here.
+ :param method: The preferred API Request method (GET, ADD, POST, etc....)
+ :type method: basestring
+
+ :return: Dictionary of status if it logged in or not.
+ """
+
+ try:
+ if self.sid is None and params[0]["url"] != "sys/login/user":
+ try:
+ self.connection._connect()
+ except Exception as err:
+ raise FAZBaseException(
+ msg="An problem happened with the httpapi plugin self-init connection process. "
+ "Error: " + to_text(err))
+ except IndexError:
+ raise FAZBaseException("An attempt was made at communicating with a FAZ with "
+ "no valid session and an incorrectly formatted request.")
+ except Exception:
+ raise FAZBaseException("An attempt was made at communicating with a FAZ with "
+ "no valid session and an unexpected error was discovered.")
+
+ self._update_request_id()
+ json_request = {
+ "method": method,
+ "params": params,
+ "session": self.sid,
+ "id": self.req_id,
+ "verbose": 1
+ }
+ data = json.dumps(json_request, ensure_ascii=False).replace('\\\\', '\\')
+ try:
+ # Sending URL and Data in Unicode, per Ansible Specifications for Connection Plugins
+ response, response_data = self.connection.send(path=to_text(self._url), data=to_text(data),
+ headers=BASE_HEADERS)
+ # Get Unicode Response - Must convert from StringIO to unicode first so we can do a replace function below
+ result = json.loads(to_text(response_data.getvalue()))
+ self._update_self_from_response(result, self._url, data)
+ return self._handle_response(result)
+ except Exception as err:
+ raise FAZBaseException(err)
+
+ def _handle_response(self, response):
+ self._set_sid(response)
+ if isinstance(response["result"], list):
+ result = response["result"][0]
+ else:
+ result = response["result"]
+ if "data" in result:
+ return result["status"]["code"], result["data"]
+ else:
+ return result["status"]["code"], result
+
+ def _update_self_from_response(self, response, url, data):
+ self._last_response_raw = response
+ if isinstance(response["result"], list):
+ result = response["result"][0]
+ else:
+ result = response["result"]
+ if "status" in result:
+ self._last_response_code = result["status"]["code"]
+ self._last_response_msg = result["status"]["message"]
+ self._last_url = url
+ self._last_data_payload = data
+
+ def _set_sid(self, response):
+ if self.sid is None and "session" in response:
+ self.sid = response["session"]
+
+ def return_connected_faz(self):
+ """
+ Returns the data stored under self._connected_faz
+
+ :return: dict
+ """
+ try:
+ if self._connected_faz:
+ return self._connected_faz
+ except Exception:
+ raise FAZBaseException("Couldn't Retrieve Connected FAZ Stats")
+
+ def get_system_status(self):
+ """
+ Returns the system status page from the FortiAnalyzer, for logging and other uses.
+ return: status
+ """
+ status = self.send_request(FAZMethods.GET, self._tools.format_request(FAZMethods.GET, "sys/status"))
+ return status
+
+ @property
+ def debug(self):
+ return self._debug
+
+ @debug.setter
+ def debug(self, val):
+ self._debug = val
+
+ @property
+ def req_id(self):
+ return self._req_id
+
+ @req_id.setter
+ def req_id(self, val):
+ self._req_id = val
+
+ def _update_request_id(self, reqid=0):
+ self.req_id = reqid if reqid != 0 else self.req_id + 1
+
+ @property
+ def sid(self):
+ return self._sid
+
+ @sid.setter
+ def sid(self, val):
+ self._sid = val
+
+ def __str__(self):
+ if self.sid is not None and self.connection._url is not None:
+ return "FortiAnalyzer object connected to FortiAnalyzer: " + to_text(self.connection._url)
+ return "FortiAnalyzer object with no valid connection to a FortiAnalyzer appliance."
+
+ ##################################
+ # BEGIN DATABASE LOCK CONTEXT CODE
+ ##################################
+
+ @property
+ def uses_workspace(self):
+ return self._uses_workspace
+
+ @uses_workspace.setter
+ def uses_workspace(self, val):
+ self._uses_workspace = val
+
+ @property
+ def uses_adoms(self):
+ return self._uses_adoms
+
+ @uses_adoms.setter
+ def uses_adoms(self, val):
+ self._uses_adoms = val
+
+ def add_adom_to_lock_list(self, adom):
+ if adom not in self._locked_adom_list:
+ self._locked_adom_list.append(adom)
+
+ def remove_adom_from_lock_list(self, adom):
+ if adom in self._locked_adom_list:
+ self._locked_adom_list.remove(adom)
+
+ def check_mode(self):
+ """
+ Checks FortiAnalyzer for the use of Workspace mode
+ """
+ url = "/cli/global/system/global"
+ code, resp_obj = self.send_request(FAZMethods.GET,
+ self._tools.format_request(FAZMethods.GET,
+ url,
+ fields=["workspace-mode", "adom-status"]))
+ try:
+ if resp_obj["workspace-mode"] == "workflow":
+ self.uses_workspace = True
+ elif resp_obj["workspace-mode"] == "disabled":
+ self.uses_workspace = False
+ except KeyError:
+ self.uses_workspace = False
+ except Exception:
+ raise FAZBaseException(msg="Couldn't determine workspace-mode in the plugin")
+ try:
+ if resp_obj["adom-status"] in [1, "enable"]:
+ self.uses_adoms = True
+ else:
+ self.uses_adoms = False
+ except KeyError:
+ self.uses_adoms = False
+ except Exception:
+ raise FAZBaseException(msg="Couldn't determine adom-status in the plugin")
+
+ def run_unlock(self):
+ """
+ Checks for ADOM status, if locked, it will unlock
+ """
+ for adom_locked in self._locked_adoms_by_user:
+ adom = adom_locked["adom"]
+ self.unlock_adom(adom)
+
+ def lock_adom(self, adom=None, *args, **kwargs):
+ """
+ Locks an ADOM for changes
+ """
+ if adom:
+ if adom.lower() == "global":
+ url = "/dvmdb/global/workspace/lock/"
+ else:
+ url = "/dvmdb/adom/{adom}/workspace/lock/".format(adom=adom)
+ else:
+ url = "/dvmdb/adom/root/workspace/lock"
+ code, respobj = self.send_request(FAZMethods.EXEC, self._tools.format_request(FAZMethods.EXEC, url))
+ if code == 0 and respobj["status"]["message"].lower() == "ok":
+ self.add_adom_to_lock_list(adom)
+ return code, respobj
+
+ def unlock_adom(self, adom=None, *args, **kwargs):
+ """
+ Unlocks an ADOM after changes
+ """
+ if adom:
+ if adom.lower() == "global":
+ url = "/dvmdb/global/workspace/unlock/"
+ else:
+ url = "/dvmdb/adom/{adom}/workspace/unlock/".format(adom=adom)
+ else:
+ url = "/dvmdb/adom/root/workspace/unlock"
+ code, respobj = self.send_request(FAZMethods.EXEC, self._tools.format_request(FAZMethods.EXEC, url))
+ if code == 0 and respobj["status"]["message"].lower() == "ok":
+ self.remove_adom_from_lock_list(adom)
+ return code, respobj
+
+ def commit_changes(self, adom=None, aux=False, *args, **kwargs):
+ """
+ Commits changes to an ADOM
+ """
+ if adom:
+ if aux:
+ url = "/pm/config/adom/{adom}/workspace/commit".format(adom=adom)
+ else:
+ if adom.lower() == "global":
+ url = "/dvmdb/global/workspace/commit/"
+ else:
+ url = "/dvmdb/adom/{adom}/workspace/commit".format(adom=adom)
+ else:
+ url = "/dvmdb/adom/root/workspace/commit"
+ return self.send_request(FAZMethods.EXEC, self._tools.format_request(FAZMethods.EXEC, url))
+
+ def get_lock_info(self, adom=None):
+ """
+ Gets ADOM lock info so it can be displayed with the error messages. Or if determined to be locked by ansible
+ for some reason, then unlock it.
+ """
+ if not adom or adom == "root":
+ url = "/dvmdb/adom/root/workspace/lockinfo"
+ else:
+ if adom.lower() == "global":
+ url = "/dvmdb/global/workspace/lockinfo/"
+ else:
+ url = "/dvmdb/adom/{adom}/workspace/lockinfo/".format(adom=adom)
+ datagram = {}
+ data = self._tools.format_request(FAZMethods.GET, url, **datagram)
+ resp_obj = self.send_request(FAZMethods.GET, data)
+ code = resp_obj[0]
+ if code != 0:
+ self._module.fail_json(msg=("An error occurred trying to get the ADOM Lock Info. Error: " + to_text(resp_obj)))
+ elif code == 0:
+ try:
+ if resp_obj[1]["status"]["message"] == "OK":
+ self._lock_info = None
+ except Exception:
+ self._lock_info = resp_obj[1]
+ return resp_obj
+
+ def get_adom_list(self):
+ """
+ Gets the list of ADOMs for the FortiAnalyzer
+ """
+ if self.uses_adoms:
+ url = "/dvmdb/adom"
+ datagram = {}
+ data = self._tools.format_request(FAZMethods.GET, url, **datagram)
+ resp_obj = self.send_request(FAZMethods.GET, data)
+ code = resp_obj[0]
+ if code != 0:
+ self._module.fail_json(msg=("An error occurred trying to get the ADOM Info. Error: " + to_text(resp_obj)))
+ elif code == 0:
+ num_of_adoms = len(resp_obj[1])
+ append_list = ['root', ]
+ for adom in resp_obj[1]:
+ if adom["tab_status"] != "":
+ append_list.append(to_text(adom["name"]))
+ self._adom_list = append_list
+ return resp_obj
+
+ def get_locked_adom_list(self):
+ """
+ Gets the list of locked adoms
+ """
+ try:
+ locked_list = list()
+ locked_by_user_list = list()
+ for adom in self._adom_list:
+ adom_lock_info = self.get_lock_info(adom=adom)
+ try:
+ if adom_lock_info[1]["status"]["message"] == "OK":
+ continue
+ except Exception:
+ pass
+ try:
+ if adom_lock_info[1][0]["lock_user"]:
+ locked_list.append(to_text(adom))
+ if adom_lock_info[1][0]["lock_user"] == self._logged_in_user:
+ locked_by_user_list.append({"adom": to_text(adom), "user": to_text(adom_lock_info[1][0]["lock_user"])})
+ except Exception as err:
+ raise FAZBaseException(err)
+ self._locked_adom_list = locked_list
+ self._locked_adoms_by_user = locked_by_user_list
+
+ except Exception as err:
+ raise FAZBaseException(msg=("An error occurred while trying to get the locked adom list. Error: "
+ + to_text(err)))
+
+ #################################
+ # END DATABASE LOCK CONTEXT CODE
+ #################################
diff --git a/collections-debian-merged/ansible_collections/community/fortios/plugins/httpapi/fortimanager.py b/collections-debian-merged/ansible_collections/community/fortios/plugins/httpapi/fortimanager.py
new file mode 100644
index 00000000..bbdaacb8
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/community/fortios/plugins/httpapi/fortimanager.py
@@ -0,0 +1,459 @@
+# Copyright (c) 2018 Fortinet and/or its affiliates.
+#
+# 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:
+ - Luke Weighall (@lweighall)
+ - Andrew Welsh (@Ghilli3)
+ - Jim Huber (@p4r4n0y1ng)
+name: fortimanager
+short_description: HttpApi Plugin for Fortinet FortiManager Appliance or VM.
+description:
+ - This HttpApi plugin provides methods to connect to Fortinet FortiManager Appliance or VM via JSON RPC API.
+'''
+
+import json
+from ansible.errors import AnsibleError
+from ansible.plugins.httpapi import HttpApiBase
+from ansible.module_utils.basic import to_text
+
+try:
+ from ansible_collections.fortinet.fortimanager.plugins.module_utils.common import BASE_HEADERS
+ from ansible_collections.fortinet.fortimanager.plugins.module_utils.common import FMGBaseException
+ from ansible_collections.fortinet.fortimanager.plugins.module_utils.common import FMGRCommon
+ from ansible_collections.fortinet.fortimanager.plugins.module_utils.common import FMGRMethods
+ HAS_FORTIMANAGER_COLLECTION = True
+except ImportError:
+ HAS_FORTIMANAGER_COLLECTION = False
+
+
+class HttpApi(HttpApiBase):
+ def __init__(self, connection):
+ super(HttpApi, self).__init__(connection)
+ self._req_id = 0
+ self._sid = None
+ self._url = "/jsonrpc"
+ self._host = None
+ self._tools = FMGRCommon
+ self._debug = False
+ self._connected_fmgr = None
+ self._last_response_msg = None
+ self._last_response_code = None
+ self._last_data_payload = None
+ self._last_url = None
+ self._last_response_raw = None
+ self._locked_adom_list = list()
+ self._locked_adoms_by_user = list()
+ self._uses_workspace = False
+ self._uses_adoms = False
+ self._adom_list = list()
+ self._logged_in_user = None
+ if not HAS_FORTIMANAGER_COLLECTION:
+ raise AnsibleError("The community.fortios.fortimanager httpapi plugin requires the fortios.fortimanager collection.")
+
+ def set_become(self, become_context):
+ """
+ ELEVATION IS NOT REQUIRED ON FORTINET DEVICES - SKIPPED.
+ :param become_context: Unused input.
+ :return: None
+ """
+ return None
+
+ def update_auth(self, response, response_data):
+ """
+ TOKENS ARE NOT USED SO NO NEED TO UPDATE AUTH.
+ :param response: Unused input.
+ :param response_data Unused_input.
+ :return: None
+ """
+ return None
+
+ def login(self, username, password):
+
+ """
+ This function will log the plugin into FortiManager, and return the results.
+ :param username: Username of FortiManager Admin
+ :param password: Password of FortiManager Admin
+
+ :return: Dictionary of status if it logged in or not.
+ """
+ self._logged_in_user = username
+ self.send_request(FMGRMethods.EXEC, self._tools.format_request(FMGRMethods.EXEC, "sys/login/user",
+ passwd=password, user=username, ))
+
+ if "FortiManager object connected to FortiManager" in self.__str__():
+ # If Login worked, then inspect the FortiManager for Workspace Mode, and it's system information.
+ self.inspect_fmgr()
+ return
+ else:
+ raise FMGBaseException(msg="Unknown error while logging in...connection was lost during login operation...."
+ " Exiting")
+
+ def inspect_fmgr(self):
+ # CHECK FOR WORKSPACE MODE TO SEE IF WE HAVE TO ENABLE ADOM LOCKS
+ status = self.get_system_status()
+ if status[0] == -11:
+ # THE CONNECTION GOT LOST SOMEHOW, REMOVE THE SID AND REPORT BAD LOGIN
+ self.logout()
+ raise FMGBaseException(msg="Error -11 -- the Session ID was likely malformed somehow. Contact authors."
+ " Exiting")
+ elif status[0] == 0:
+ try:
+ self.check_mode()
+ if self._uses_adoms:
+ self.get_adom_list()
+ if self._uses_workspace:
+ self.get_locked_adom_list()
+ self._connected_fmgr = status[1]
+ self._host = self._connected_fmgr["Hostname"]
+ except BaseException:
+ pass
+ return
+
+ def logout(self):
+ """
+ This function will logout of the FortiManager.
+ """
+ if self.sid is not None:
+ # IF WE WERE USING WORKSPACES, THEN CLEAN UP OUR LOCKS IF THEY STILL EXIST
+ if self.uses_workspace:
+ self.get_lock_info()
+ self.run_unlock()
+ ret_code, response = self.send_request(FMGRMethods.EXEC,
+ self._tools.format_request(FMGRMethods.EXEC, "sys/logout"))
+ self.sid = None
+ return ret_code, response
+
+ def send_request(self, method, params):
+ """
+ Responsible for actual sending of data to the connection httpapi base plugin. Does some formatting too.
+ :param params: A formatted dictionary that was returned by self.common_datagram_params()
+ before being called here.
+ :param method: The preferred API Request method (GET, ADD, POST, etc....)
+ :type method: basestring
+
+ :return: Dictionary of status, if it logged in or not.
+ """
+ try:
+ if self.sid is None and params[0]["url"] != "sys/login/user":
+ try:
+ self.connection._connect()
+ except Exception as err:
+ raise FMGBaseException(
+ msg="An problem happened with the httpapi plugin self-init connection process. "
+ "Error: " + to_text(err))
+ except IndexError:
+ raise FMGBaseException("An attempt was made at communicating with a FMG with "
+ "no valid session and an incorrectly formatted request.")
+ except Exception as err:
+ raise FMGBaseException("An attempt was made at communicating with a FMG with "
+ "no valid session and an unexpected error was discovered. \n Error: " + to_text(err))
+
+ self._update_request_id()
+ json_request = {
+ "method": method,
+ "params": params,
+ "session": self.sid,
+ "id": self.req_id,
+ "verbose": 1
+ }
+ data = json.dumps(json_request, ensure_ascii=False).replace('\\\\', '\\')
+ try:
+ # Sending URL and Data in Unicode, per Ansible Specifications for Connection Plugins
+ response, response_data = self.connection.send(path=to_text(self._url), data=to_text(data),
+ headers=BASE_HEADERS)
+ # Get Unicode Response - Must convert from StringIO to unicode first so we can do a replace function below
+ result = json.loads(to_text(response_data.getvalue()))
+ self._update_self_from_response(result, self._url, data)
+ return self._handle_response(result)
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ def _handle_response(self, response):
+ self._set_sid(response)
+ if isinstance(response["result"], list):
+ result = response["result"][0]
+ else:
+ result = response["result"]
+ if "data" in result:
+ return result["status"]["code"], result["data"]
+ else:
+ return result["status"]["code"], result
+
+ def _update_self_from_response(self, response, url, data):
+ self._last_response_raw = response
+ if isinstance(response["result"], list):
+ result = response["result"][0]
+ else:
+ result = response["result"]
+ if "status" in result:
+ self._last_response_code = result["status"]["code"]
+ self._last_response_msg = result["status"]["message"]
+ self._last_url = url
+ self._last_data_payload = data
+
+ def _set_sid(self, response):
+ if self.sid is None and "session" in response:
+ self.sid = response["session"]
+
+ def return_connected_fmgr(self):
+ """
+ Returns the data stored under self._connected_fmgr
+
+ :return: dict
+ """
+ try:
+ if self._connected_fmgr:
+ return self._connected_fmgr
+ except Exception:
+ raise FMGBaseException("Couldn't Retrieve Connected FMGR Stats")
+
+ def get_system_status(self):
+ """
+ Returns the system status page from the FortiManager, for logging and other uses.
+ return: status
+ """
+ status = self.send_request(FMGRMethods.GET, self._tools.format_request(FMGRMethods.GET, "sys/status"))
+ return status
+
+ @property
+ def debug(self):
+ return self._debug
+
+ @debug.setter
+ def debug(self, val):
+ self._debug = val
+
+ @property
+ def req_id(self):
+ return self._req_id
+
+ @req_id.setter
+ def req_id(self, val):
+ self._req_id = val
+
+ def _update_request_id(self, reqid=0):
+ self.req_id = reqid if reqid != 0 else self.req_id + 1
+
+ @property
+ def sid(self):
+ return self._sid
+
+ @sid.setter
+ def sid(self, val):
+ self._sid = val
+
+ def __str__(self):
+ if self.sid is not None and self.connection._url is not None:
+ return "FortiManager object connected to FortiManager: " + to_text(self.connection._url)
+ return "FortiManager object with no valid connection to a FortiManager appliance."
+
+ ##################################
+ # BEGIN DATABASE LOCK CONTEXT CODE
+ ##################################
+
+ @property
+ def uses_workspace(self):
+ return self._uses_workspace
+
+ @uses_workspace.setter
+ def uses_workspace(self, val):
+ self._uses_workspace = val
+
+ @property
+ def uses_adoms(self):
+ return self._uses_adoms
+
+ @uses_adoms.setter
+ def uses_adoms(self, val):
+ self._uses_adoms = val
+
+ def add_adom_to_lock_list(self, adom):
+ if adom not in self._locked_adom_list:
+ self._locked_adom_list.append(adom)
+
+ def remove_adom_from_lock_list(self, adom):
+ if adom in self._locked_adom_list:
+ self._locked_adom_list.remove(adom)
+
+ def check_mode(self):
+ """
+ Checks FortiManager for the use of Workspace mode
+ """
+ url = "/cli/global/system/global"
+ code, resp_obj = self.send_request(FMGRMethods.GET,
+ self._tools.format_request(FMGRMethods.GET,
+ url,
+ fields=["workspace-mode", "adom-status"]))
+ try:
+ if resp_obj["workspace-mode"] == "workflow":
+ self.uses_workspace = True
+ elif resp_obj["workspace-mode"] == "disabled":
+ self.uses_workspace = False
+ except KeyError:
+ raise FMGBaseException(msg="Couldn't determine workspace-mode in the plugin")
+ try:
+ if resp_obj["adom-status"] in [1, "enable"]:
+ self.uses_adoms = True
+ else:
+ self.uses_adoms = False
+ except KeyError:
+ raise FMGBaseException(msg="Couldn't determine adom-status in the plugin")
+
+ def run_unlock(self):
+ """
+ Checks for ADOM status, if locked, it will unlock
+ """
+ for adom_locked in self._locked_adoms_by_user:
+ adom = adom_locked["adom"]
+ self.unlock_adom(adom)
+
+ def lock_adom(self, adom=None, *args, **kwargs):
+ """
+ Locks an ADOM for changes
+ """
+ if adom:
+ if adom.lower() == "global":
+ url = "/dvmdb/global/workspace/lock/"
+ else:
+ url = "/dvmdb/adom/{adom}/workspace/lock/".format(adom=adom)
+ else:
+ url = "/dvmdb/adom/root/workspace/lock"
+ code, respobj = self.send_request(FMGRMethods.EXEC, self._tools.format_request(FMGRMethods.EXEC, url))
+ if code == 0 and respobj["status"]["message"].lower() == "ok":
+ self.add_adom_to_lock_list(adom)
+ return code, respobj
+
+ def unlock_adom(self, adom=None, *args, **kwargs):
+ """
+ Unlocks an ADOM after changes
+ """
+ if adom:
+ if adom.lower() == "global":
+ url = "/dvmdb/global/workspace/unlock/"
+ else:
+ url = "/dvmdb/adom/{adom}/workspace/unlock/".format(adom=adom)
+ else:
+ url = "/dvmdb/adom/root/workspace/unlock"
+ code, respobj = self.send_request(FMGRMethods.EXEC, self._tools.format_request(FMGRMethods.EXEC, url))
+ if code == 0 and respobj["status"]["message"].lower() == "ok":
+ self.remove_adom_from_lock_list(adom)
+ return code, respobj
+
+ def commit_changes(self, adom=None, aux=False, *args, **kwargs):
+ """
+ Commits changes to an ADOM
+ """
+ if adom:
+ if aux:
+ url = "/pm/config/adom/{adom}/workspace/commit".format(adom=adom)
+ else:
+ if adom.lower() == "global":
+ url = "/dvmdb/global/workspace/commit/"
+ else:
+ url = "/dvmdb/adom/{adom}/workspace/commit".format(adom=adom)
+ else:
+ url = "/dvmdb/adom/root/workspace/commit"
+ return self.send_request(FMGRMethods.EXEC, self._tools.format_request(FMGRMethods.EXEC, url))
+
+ def get_lock_info(self, adom=None):
+ """
+ Gets ADOM lock info so it can be displayed with the error messages. Or if determined to be locked by ansible
+ for some reason, then unlock it.
+ """
+ if not adom or adom == "root":
+ url = "/dvmdb/adom/root/workspace/lockinfo"
+ else:
+ if adom.lower() == "global":
+ url = "/dvmdb/global/workspace/lockinfo/"
+ else:
+ url = "/dvmdb/adom/{adom}/workspace/lockinfo/".format(adom=adom)
+ datagram = {}
+ data = self._tools.format_request(FMGRMethods.GET, url, **datagram)
+ resp_obj = self.send_request(FMGRMethods.GET, data)
+ code = resp_obj[0]
+ if code != 0:
+ self._module.fail_json(msg=("An error occurred trying to get the ADOM Lock Info. "
+ "Error: " + to_text(resp_obj)))
+ elif code == 0:
+ try:
+ if resp_obj[1]["status"]["message"] == "OK":
+ self._lock_info = None
+ except Exception:
+ self._lock_info = resp_obj[1]
+ return resp_obj
+
+ def get_adom_list(self):
+ """
+ Gets the list of ADOMs for the FortiManager
+ """
+ if self.uses_adoms:
+ url = "/dvmdb/adom"
+ datagram = {}
+ data = self._tools.format_request(FMGRMethods.GET, url, **datagram)
+ resp_obj = self.send_request(FMGRMethods.GET, data)
+ code = resp_obj[0]
+ if code != 0:
+ self._module.fail_json(msg=("An error occurred trying to get the ADOM Info. "
+ "Error: " + to_text(resp_obj)))
+ elif code == 0:
+ num_of_adoms = len(resp_obj[1])
+ append_list = ['root', ]
+ for adom in resp_obj[1]:
+ if adom["tab_status"] != "":
+ append_list.append(to_text(adom["name"]))
+ self._adom_list = append_list
+ return resp_obj
+
+ def get_locked_adom_list(self):
+ """
+ Gets the list of locked adoms
+ """
+ try:
+ locked_list = list()
+ locked_by_user_list = list()
+ for adom in self._adom_list:
+ adom_lock_info = self.get_lock_info(adom=adom)
+ try:
+ if adom_lock_info[1]["status"]["message"] == "OK":
+ continue
+ except IndexError as err:
+ pass
+ try:
+ if adom_lock_info[1][0]["lock_user"]:
+ locked_list.append(to_text(adom))
+ if adom_lock_info[1][0]["lock_user"] == self._logged_in_user:
+ locked_by_user_list.append({"adom": to_text(adom),
+ "user": to_text(adom_lock_info[1][0]["lock_user"])})
+ except Exception as err:
+ raise FMGBaseException(err)
+ self._locked_adom_list = locked_list
+ self._locked_adoms_by_user = locked_by_user_list
+
+ except Exception as err:
+ raise FMGBaseException(msg=("An error occurred while trying to get the locked adom list. Error: "
+ + to_text(err)))
+
+ ################################
+ # END DATABASE LOCK CONTEXT CODE
+ ################################
diff --git a/collections-debian-merged/ansible_collections/community/fortios/plugins/module_utils/fortianalyzer/common.py b/collections-debian-merged/ansible_collections/community/fortios/plugins/module_utils/fortianalyzer/common.py
new file mode 100644
index 00000000..50cd95cc
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/community/fortios/plugins/module_utils/fortianalyzer/common.py
@@ -0,0 +1,291 @@
+# 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) 2017 Fortinet, Inc
+# All rights reserved.
+#
+# 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
+
+
+# BEGIN STATIC DATA AND MESSAGES
+class FAZMethods:
+ GET = "get"
+ SET = "set"
+ EXEC = "exec"
+ EXECUTE = "exec"
+ UPDATE = "update"
+ ADD = "add"
+ DELETE = "delete"
+ REPLACE = "replace"
+ CLONE = "clone"
+ MOVE = "move"
+
+
+BASE_HEADERS = {
+ 'Content-Type': 'application/json',
+ 'Accept': 'application/json'
+}
+
+
+# FAZ RETURN CODES
+FAZ_RC = {
+ "faz_return_codes": {
+ 0: {
+ "msg": "OK",
+ "changed": True,
+ "stop_on_success": True
+ },
+ -100000: {
+ "msg": "Module returned without actually running anything. "
+ "Check parameters, and please contact the authors if needed.",
+ "failed": True
+ },
+ -2: {
+ "msg": "Object already exists.",
+ "skipped": True,
+ "changed": False,
+ "good_codes": [0, -2]
+ },
+ -6: {
+ "msg": "Invalid Url. Sometimes this can happen because the path is mapped to a hostname or object that"
+ " doesn't exist. Double check your input object parameters."
+ },
+ -3: {
+ "msg": "Object doesn't exist.",
+ "skipped": True,
+ "changed": False,
+ "good_codes": [0, -3]
+ },
+ -10131: {
+ "msg": "Object dependency failed. Do all named objects in parameters exist?",
+ "changed": False,
+ "skipped": True
+ },
+ -9998: {
+ "msg": "Duplicate object. Try using mode='set', if using add. STOPPING. Use 'ignore_errors=yes' in playbook"
+ "to override and mark successful.",
+ },
+ -20042: {
+ "msg": "Device Unreachable.",
+ "skipped": True
+ },
+ -10033: {
+ "msg": "Duplicate object. Try using mode='set', if using add.",
+ "changed": False,
+ "skipped": True
+ },
+ -10000: {
+ "msg": "Duplicate object. Try using mode='set', if using add.",
+ "changed": False,
+ "skipped": True
+ },
+ -20010: {
+ "msg": "Device already added to FortiAnalyzer. Serial number already in use.",
+ "good_codes": [0, -20010],
+ "changed": False,
+ "stop_on_failure": False
+ },
+ -20002: {
+ "msg": "Invalid Argument -- Does this Device exist on FortiAnalyzer?",
+ "changed": False,
+ "skipped": True,
+ }
+ }
+}
+
+DEFAULT_RESULT_OBJ = (-100000, {"msg": "Nothing Happened. Check that handle_response is being called!"})
+FAIL_SOCKET_MSG = {"msg": "Socket Path Empty! The persistent connection manager is messed up. "
+ "Try again in a few moments."}
+
+
+# BEGIN ERROR EXCEPTIONS
+class FAZBaseException(Exception):
+ """Wrapper to catch the unexpected"""
+
+ def __init__(self, msg=None, *args, **kwargs):
+ if msg is None:
+ msg = "An exception occurred within the fortianalyzer.py httpapi connection plugin."
+ super(FAZBaseException, self).__init__(msg, *args)
+
+# END ERROR CLASSES
+
+
+# BEGIN CLASSES
+class FAZCommon(object):
+
+ @staticmethod
+ def format_request(method, url, *args, **kwargs):
+ """
+ Formats the payload from the module, into a payload the API handler can use.
+
+ :param url: Connection URL to access
+ :type url: string
+ :param method: The preferred API Request method (GET, ADD, POST, etc....)
+ :type method: basestring
+ :param kwargs: The payload dictionary from the module to be converted.
+
+ :return: Properly formatted dictionary payload for API Request via Connection Plugin.
+ :rtype: dict
+ """
+
+ params = [{"url": url}]
+ if args:
+ for arg in args:
+ params[0].update(arg)
+ if kwargs:
+ keylist = list(kwargs)
+ for k in keylist:
+ kwargs[k.replace("__", "-")] = kwargs.pop(k)
+ if method == "get" or method == "clone":
+ params[0].update(kwargs)
+ else:
+ if kwargs.get("data", False):
+ params[0]["data"] = kwargs["data"]
+ else:
+ params[0]["data"] = kwargs
+ return params
+
+ @staticmethod
+ def split_comma_strings_into_lists(obj):
+ """
+ Splits a CSV String into a list. Also takes a dictionary, and converts any CSV strings in any key, to a list.
+
+ :param obj: object in CSV format to be parsed.
+ :type obj: str or dict
+
+ :return: A list containing the CSV items.
+ :rtype: list
+ """
+ return_obj = ()
+ if isinstance(obj, dict):
+ if len(obj) > 0:
+ for k, v in obj.items():
+ if isinstance(v, str):
+ new_list = list()
+ if "," in v:
+ new_items = v.split(",")
+ for item in new_items:
+ new_list.append(item.strip())
+ obj[k] = new_list
+ return_obj = obj
+ elif isinstance(obj, str):
+ return_obj = obj.replace(" ", "").split(",")
+
+ return return_obj
+
+ @staticmethod
+ def cidr_to_netmask(cidr):
+ """
+ Converts a CIDR Network string to full blown IP/Subnet format in decimal format.
+ Decided not use IP Address module to keep includes to a minimum.
+
+ :param cidr: String object in CIDR format to be processed
+ :type cidr: str
+
+ :return: A string object that looks like this "x.x.x.x/y.y.y.y"
+ :rtype: str
+ """
+ if isinstance(cidr, str):
+ cidr = int(cidr)
+ mask = (0xffffffff >> (32 - cidr)) << (32 - cidr)
+ return (str((0xff000000 & mask) >> 24) + '.'
+ + str((0x00ff0000 & mask) >> 16) + '.'
+ + str((0x0000ff00 & mask) >> 8) + '.'
+ + str((0x000000ff & mask)))
+
+ @staticmethod
+ def paramgram_child_list_override(list_overrides, paramgram, module):
+ """
+ If a list of items was provided to a "parent" paramgram attribute, the paramgram needs to be rewritten.
+ The child keys of the desired attribute need to be deleted, and then that "parent" keys' contents is replaced
+ With the list of items that was provided.
+
+ :param list_overrides: Contains the response from the FortiAnalyzer.
+ :type list_overrides: list
+ :param paramgram: Contains the paramgram passed to the modules' local modify function.
+ :type paramgram: dict
+ :param module: Contains the Ansible Module Object being used by the module.
+ :type module: classObject
+
+ :return: A new "paramgram" refactored to allow for multiple entries being added.
+ :rtype: dict
+ """
+ if len(list_overrides) > 0:
+ for list_variable in list_overrides:
+ try:
+ list_variable = list_variable.replace("-", "_")
+ override_data = module.params[list_variable]
+ if override_data:
+ del paramgram[list_variable]
+ paramgram[list_variable] = override_data
+ except BaseException as e:
+ raise FAZBaseException("Error occurred merging custom lists for the paramgram parent: " + str(e))
+ return paramgram
+
+ @staticmethod
+ def syslog(module, msg):
+ try:
+ module.log(msg=msg)
+ except BaseException:
+ pass
+
+
+# RECURSIVE FUNCTIONS START
+def prepare_dict(obj):
+ """
+ Removes any keys from a dictionary that are only specific to our use in the module. FortiAnalyzer will reject
+ requests with these empty/None keys in it.
+
+ :param obj: Dictionary object to be processed.
+ :type obj: dict
+
+ :return: Processed dictionary.
+ :rtype: dict
+ """
+
+ list_of_elems = ["mode", "adom", "host", "username", "password"]
+
+ if isinstance(obj, dict):
+ obj = dict((key, prepare_dict(value)) for (key, value) in obj.items() if key not in list_of_elems)
+ return obj
+
+
+def scrub_dict(obj):
+ """
+ Removes any keys from a dictionary that are EMPTY -- this includes parent keys. FortiAnalyzer doesn't
+ like empty keys in dictionaries
+
+ :param obj: Dictionary object to be processed.
+ :type obj: dict
+
+ :return: Processed dictionary.
+ :rtype: dict
+ """
+
+ if isinstance(obj, dict):
+ return dict((k, scrub_dict(v)) for k, v in obj.items() if v and scrub_dict(v))
+ else:
+ return obj
diff --git a/collections-debian-merged/ansible_collections/community/fortios/plugins/module_utils/fortianalyzer/fortianalyzer.py b/collections-debian-merged/ansible_collections/community/fortios/plugins/module_utils/fortianalyzer/fortianalyzer.py
new file mode 100644
index 00000000..74e85e30
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/community/fortios/plugins/module_utils/fortianalyzer/fortianalyzer.py
@@ -0,0 +1,476 @@
+# 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) 2017 Fortinet, Inc
+# All rights reserved.
+#
+# 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
+
+
+from ansible_collections.community.fortios.plugins.module_utils.fortianalyzer.common import FAZ_RC
+from ansible_collections.community.fortios.plugins.module_utils.fortianalyzer.common import FAZBaseException
+from ansible_collections.community.fortios.plugins.module_utils.fortianalyzer.common import FAZCommon
+from ansible_collections.community.fortios.plugins.module_utils.fortianalyzer.common import scrub_dict
+from ansible_collections.community.fortios.plugins.module_utils.fortianalyzer.common import FAZMethods
+
+
+# ACTIVE BUG WITH OUR DEBUG IMPORT CALL - BECAUSE IT'S UNDER MODULE_UTILITIES
+# WHEN module_common.recursive_finder() runs under the module loader, it looks for this namespace debug import
+# and because it's not there, it always fails, regardless of it being under a try/catch here.
+# we're going to move it to a different namespace.
+# # check for debug lib
+# try:
+# from ansible.module_utils.fortianalyzer.fortianalyzer_debug import debug_dump
+# HAS_FAZ_DEBUG = True
+# except:
+# HAS_FAZ_DEBUG = False
+
+
+# BEGIN HANDLER CLASSES
+class FortiAnalyzerHandler(object):
+ def __init__(self, conn, module):
+ self._conn = conn
+ self._module = module
+ self._tools = FAZCommon
+ self._uses_workspace = None
+ self._uses_adoms = None
+ self._locked_adom_list = list()
+ self._lock_info = None
+
+ self.workspace_check()
+ if self._uses_workspace:
+ self.get_lock_info(adom=self._module.paramgram["adom"])
+
+ def process_request(self, url, datagram, method):
+ """
+ Formats and Runs the API Request via Connection Plugin. Streamlined for use from Modules.
+
+ :param url: Connection URL to access
+ :type url: string
+ :param datagram: The prepared payload for the API Request in dictionary format
+ :type datagram: dict
+ :param method: The preferred API Request method (GET, ADD, POST, etc....)
+ :type method: basestring
+
+ :return: Dictionary containing results of the API Request via Connection Plugin.
+ :rtype: dict
+ """
+ try:
+ adom = self._module.paramgram["adom"]
+ if self.uses_workspace and adom not in self._locked_adom_list and method != FAZMethods.GET:
+ self.lock_adom(adom=adom)
+ except BaseException as err:
+ raise FAZBaseException(err)
+
+ data = self._tools.format_request(method, url, **datagram)
+ response = self._conn.send_request(method, data)
+
+ try:
+ adom = self._module.paramgram["adom"]
+ if self.uses_workspace and adom in self._locked_adom_list \
+ and response[0] == 0 and method != FAZMethods.GET:
+ self.commit_changes(adom=adom)
+ except BaseException as err:
+ raise FAZBaseException(err)
+
+ # if HAS_FAZ_DEBUG:
+ # try:
+ # debug_dump(response, datagram, self._module.paramgram, url, method)
+ # except BaseException:
+ # pass
+
+ return response
+
+ def workspace_check(self):
+ """
+ Checks FortiAnalyzer for the use of Workspace mode.
+ """
+ url = "/cli/global/system/global"
+ data = {"fields": ["workspace-mode", "adom-status"]}
+ resp_obj = self.process_request(url, data, FAZMethods.GET)
+ try:
+ if resp_obj[1]["workspace-mode"] in ["workflow", "normal"]:
+ self.uses_workspace = True
+ elif resp_obj[1]["workspace-mode"] == "disabled":
+ self.uses_workspace = False
+ except KeyError:
+ self.uses_workspace = False
+ except BaseException as err:
+ raise FAZBaseException(msg="Couldn't determine workspace-mode in the plugin. Error: " + str(err))
+ try:
+ if resp_obj[1]["adom-status"] in [1, "enable"]:
+ self.uses_adoms = True
+ else:
+ self.uses_adoms = False
+ except KeyError:
+ self.uses_adoms = False
+ except BaseException as err:
+ raise FAZBaseException(msg="Couldn't determine adom-status in the plugin. Error: " + str(err))
+
+ def run_unlock(self):
+ """
+ Checks for ADOM status, if locked, it will unlock
+ """
+ for adom_locked in self._locked_adom_list:
+ self.unlock_adom(adom_locked)
+
+ def lock_adom(self, adom=None):
+ """
+ Locks an ADOM for changes
+ """
+ if not adom or adom == "root":
+ url = "/dvmdb/adom/root/workspace/lock"
+ else:
+ if adom.lower() == "global":
+ url = "/dvmdb/global/workspace/lock/"
+ else:
+ url = "/dvmdb/adom/{adom}/workspace/lock/".format(adom=adom)
+ datagram = {}
+ data = self._tools.format_request(FAZMethods.EXEC, url, **datagram)
+ resp_obj = self._conn.send_request(FAZMethods.EXEC, data)
+ code = resp_obj[0]
+ if code == 0 and resp_obj[1]["status"]["message"].lower() == "ok":
+ self.add_adom_to_lock_list(adom)
+ else:
+ lockinfo = self.get_lock_info(adom=adom)
+ self._module.fail_json(msg=("An error occurred trying to lock the adom. Error: "
+ + str(resp_obj) + ", LOCK INFO: " + str(lockinfo)))
+ return resp_obj
+
+ def unlock_adom(self, adom=None):
+ """
+ Unlocks an ADOM after changes
+ """
+ if not adom or adom == "root":
+ url = "/dvmdb/adom/root/workspace/unlock"
+ else:
+ if adom.lower() == "global":
+ url = "/dvmdb/global/workspace/unlock/"
+ else:
+ url = "/dvmdb/adom/{adom}/workspace/unlock/".format(adom=adom)
+ datagram = {}
+ data = self._tools.format_request(FAZMethods.EXEC, url, **datagram)
+ resp_obj = self._conn.send_request(FAZMethods.EXEC, data)
+ code = resp_obj[0]
+ if code == 0 and resp_obj[1]["status"]["message"].lower() == "ok":
+ self.remove_adom_from_lock_list(adom)
+ else:
+ self._module.fail_json(msg=("An error occurred trying to unlock the adom. Error: " + str(resp_obj)))
+ return resp_obj
+
+ def get_lock_info(self, adom=None):
+ """
+ Gets ADOM lock info so it can be displayed with the error messages. Or if determined to be locked by ansible
+ for some reason, then unlock it.
+ """
+ if not adom or adom == "root":
+ url = "/dvmdb/adom/root/workspace/lockinfo"
+ else:
+ if adom.lower() == "global":
+ url = "/dvmdb/global/workspace/lockinfo/"
+ else:
+ url = "/dvmdb/adom/{adom}/workspace/lockinfo/".format(adom=adom)
+ datagram = {}
+ data = self._tools.format_request(FAZMethods.GET, url, **datagram)
+ resp_obj = self._conn.send_request(FAZMethods.GET, data)
+ code = resp_obj[0]
+ if code != 0:
+ self._module.fail_json(msg=("An error occurred trying to get the ADOM Lock Info. Error: " + str(resp_obj)))
+ elif code == 0:
+ self._lock_info = resp_obj[1]
+ return resp_obj
+
+ def commit_changes(self, adom=None, aux=False):
+ """
+ Commits changes to an ADOM
+ """
+ if not adom or adom == "root":
+ url = "/dvmdb/adom/root/workspace/commit"
+ else:
+ if aux:
+ url = "/pm/config/adom/{adom}/workspace/commit".format(adom=adom)
+ else:
+ if adom.lower() == "global":
+ url = "/dvmdb/global/workspace/commit/"
+ else:
+ url = "/dvmdb/adom/{adom}/workspace/commit".format(adom=adom)
+ datagram = {}
+ data = self._tools.format_request(FAZMethods.EXEC, url, **datagram)
+ resp_obj = self._conn.send_request(FAZMethods.EXEC, data)
+ code = resp_obj[0]
+ if code != 0:
+ self._module.fail_json(msg=("An error occurred trying to commit changes to the adom. Error: "
+ + str(resp_obj)))
+
+ def govern_response(self, module, results, msg=None, good_codes=None,
+ stop_on_fail=None, stop_on_success=None, skipped=None,
+ changed=None, unreachable=None, failed=None, success=None, changed_if_success=None,
+ ansible_facts=None):
+ """
+ This function will attempt to apply default values to canned responses from FortiAnalyzer we know of.
+ This saves time, and turns the response in the module into a "one-liner", while still giving us...
+ the flexibility to directly use return_response in modules if we have too. This function saves repeated code.
+
+ :param module: The Ansible Module CLASS object, used to run fail/exit json
+ :type module: object
+ :param msg: An overridable custom message from the module that called this.
+ :type msg: string
+ :param results: A dictionary object containing an API call results
+ :type results: dict
+ :param good_codes: A list of exit codes considered successful from FortiAnalyzer
+ :type good_codes: list
+ :param stop_on_fail: If true, stops playbook run when return code is NOT IN good codes (default: true)
+ :type stop_on_fail: boolean
+ :param stop_on_success: If true, stops playbook run when return code is IN good codes (default: false)
+ :type stop_on_success: boolean
+ :param changed: If True, tells Ansible that object was changed (default: false)
+ :type skipped: boolean
+ :param skipped: If True, tells Ansible that object was skipped (default: false)
+ :type skipped: boolean
+ :param unreachable: If True, tells Ansible that object was unreachable (default: false)
+ :type unreachable: boolean
+ :param failed: If True, tells Ansible that execution was a failure. Overrides good_codes. (default: false)
+ :type unreachable: boolean
+ :param success: If True, tells Ansible that execution was a success. Overrides good_codes. (default: false)
+ :type unreachable: boolean
+ :param changed_if_success: If True, defaults to changed if successful if you specify or not"
+ :type changed_if_success: boolean
+ :param ansible_facts: A prepared dictionary of ansible facts from the execution.
+ :type ansible_facts: dict
+ """
+ if module is None and results is None:
+ raise FAZBaseException("govern_response() was called without a module and/or results tuple! Fix!")
+ # Get the Return code from results
+ try:
+ rc = results[0]
+ except BaseException:
+ raise FAZBaseException("govern_response() was called without the return code at results[0]")
+
+ # init a few items
+ rc_data = None
+
+ # Get the default values for the said return code.
+ try:
+ rc_codes = FAZ_RC.get('faz_return_codes')
+ rc_data = rc_codes.get(rc)
+ except BaseException:
+ pass
+
+ if not rc_data:
+ rc_data = {}
+ # ONLY add to overrides if not none -- This is very important that the keys aren't added at this stage
+ # if they are empty. And there aren't that many, so let's just do a few if then statements.
+ if good_codes is not None:
+ rc_data["good_codes"] = good_codes
+ if stop_on_fail is not None:
+ rc_data["stop_on_fail"] = stop_on_fail
+ if stop_on_success is not None:
+ rc_data["stop_on_success"] = stop_on_success
+ if skipped is not None:
+ rc_data["skipped"] = skipped
+ if changed is not None:
+ rc_data["changed"] = changed
+ if unreachable is not None:
+ rc_data["unreachable"] = unreachable
+ if failed is not None:
+ rc_data["failed"] = failed
+ if success is not None:
+ rc_data["success"] = success
+ if changed_if_success is not None:
+ rc_data["changed_if_success"] = changed_if_success
+ if results is not None:
+ rc_data["results"] = results
+ if msg is not None:
+ rc_data["msg"] = msg
+ if ansible_facts is None:
+ rc_data["ansible_facts"] = {}
+ else:
+ rc_data["ansible_facts"] = ansible_facts
+
+ return self.return_response(module=module,
+ results=results,
+ msg=rc_data.get("msg", "NULL"),
+ good_codes=rc_data.get("good_codes", (0,)),
+ stop_on_fail=rc_data.get("stop_on_fail", True),
+ stop_on_success=rc_data.get("stop_on_success", False),
+ skipped=rc_data.get("skipped", False),
+ changed=rc_data.get("changed", False),
+ changed_if_success=rc_data.get("changed_if_success", False),
+ unreachable=rc_data.get("unreachable", False),
+ failed=rc_data.get("failed", False),
+ success=rc_data.get("success", False),
+ ansible_facts=rc_data.get("ansible_facts", dict()))
+
+ def return_response(self, module, results, msg="NULL", good_codes=(0,),
+ stop_on_fail=True, stop_on_success=False, skipped=False,
+ changed=False, unreachable=False, failed=False, success=False, changed_if_success=True,
+ ansible_facts=()):
+ """
+ This function controls the logout and error reporting after an method or function runs. The exit_json for
+ ansible comes from logic within this function. If this function returns just the msg, it means to continue
+ execution on the playbook. It is called from the ansible module, or from the self.govern_response function.
+
+ :param module: The Ansible Module CLASS object, used to run fail/exit json
+ :type module: object
+ :param msg: An overridable custom message from the module that called this.
+ :type msg: string
+ :param results: A dictionary object containing an API call results
+ :type results: dict
+ :param good_codes: A list of exit codes considered successful from FortiAnalyzer
+ :type good_codes: list
+ :param stop_on_fail: If true, stops playbook run when return code is NOT IN good codes (default: true)
+ :type stop_on_fail: boolean
+ :param stop_on_success: If true, stops playbook run when return code is IN good codes (default: false)
+ :type stop_on_success: boolean
+ :param changed: If True, tells Ansible that object was changed (default: false)
+ :type skipped: boolean
+ :param skipped: If True, tells Ansible that object was skipped (default: false)
+ :type skipped: boolean
+ :param unreachable: If True, tells Ansible that object was unreachable (default: false)
+ :type unreachable: boolean
+ :param failed: If True, tells Ansible that execution was a failure. Overrides good_codes. (default: false)
+ :type unreachable: boolean
+ :param success: If True, tells Ansible that execution was a success. Overrides good_codes. (default: false)
+ :type unreachable: boolean
+ :param changed_if_success: If True, defaults to changed if successful if you specify or not"
+ :type changed_if_success: boolean
+ :param ansible_facts: A prepared dictionary of ansible facts from the execution.
+ :type ansible_facts: dict
+
+ :return: A string object that contains an error message
+ :rtype: str
+ """
+
+ # VALIDATION ERROR
+ if (len(results) == 0) or (failed and success) or (changed and unreachable):
+ module.exit_json(msg="Handle_response was called with no results, or conflicting failed/success or "
+ "changed/unreachable parameters. Fix the exit code on module. "
+ "Generic Failure", failed=True)
+
+ # IDENTIFY SUCCESS/FAIL IF NOT DEFINED
+ if not failed and not success:
+ if len(results) > 0:
+ if results[0] not in good_codes:
+ failed = True
+ elif results[0] in good_codes:
+ success = True
+
+ if len(results) > 0:
+ # IF NO MESSAGE WAS SUPPLIED, GET IT FROM THE RESULTS, IF THAT DOESN'T WORK, THEN WRITE AN ERROR MESSAGE
+ if msg == "NULL":
+ try:
+ msg = results[1]['status']['message']
+ except BaseException:
+ msg = "No status message returned at results[1][status][message], " \
+ "and none supplied to msg parameter for handle_response."
+
+ if failed:
+ # BECAUSE SKIPPED/FAILED WILL OFTEN OCCUR ON CODES THAT DON'T GET INCLUDED, THEY ARE CONSIDERED FAILURES
+ # HOWEVER, THEY ARE MUTUALLY EXCLUSIVE, SO IF IT IS MARKED SKIPPED OR UNREACHABLE BY THE MODULE LOGIC
+ # THEN REMOVE THE FAILED FLAG SO IT DOESN'T OVERRIDE THE DESIRED STATUS OF SKIPPED OR UNREACHABLE.
+ if failed and skipped:
+ failed = False
+ if failed and unreachable:
+ failed = False
+ if stop_on_fail:
+ if self._uses_workspace:
+ try:
+ self.run_unlock()
+ except BaseException as err:
+ raise FAZBaseException(msg=("Couldn't unlock ADOM! Error: " + str(err)))
+ module.exit_json(msg=msg, failed=failed, changed=changed, unreachable=unreachable, skipped=skipped,
+ results=results[1], ansible_facts=ansible_facts, rc=results[0],
+ invocation={"module_args": ansible_facts["ansible_params"]})
+ elif success:
+ if changed_if_success:
+ changed = True
+ success = False
+ if stop_on_success:
+ if self._uses_workspace:
+ try:
+ self.run_unlock()
+ except BaseException as err:
+ raise FAZBaseException(msg=("Couldn't unlock ADOM! Error: " + str(err)))
+ module.exit_json(msg=msg, success=success, changed=changed, unreachable=unreachable,
+ skipped=skipped, results=results[1], ansible_facts=ansible_facts, rc=results[0],
+ invocation={"module_args": ansible_facts["ansible_params"]})
+ return msg
+
+ @staticmethod
+ def construct_ansible_facts(response, ansible_params, paramgram, *args, **kwargs):
+ """
+ Constructs a dictionary to return to ansible facts, containing various information about the execution.
+
+ :param response: Contains the response from the FortiAnalyzer.
+ :type response: dict
+ :param ansible_params: Contains the parameters Ansible was called with.
+ :type ansible_params: dict
+ :param paramgram: Contains the paramgram passed to the modules' local modify function.
+ :type paramgram: dict
+ :param args: Free-form arguments that could be added.
+ :param kwargs: Free-form keyword arguments that could be added.
+
+ :return: A dictionary containing lots of information to append to Ansible Facts.
+ :rtype: dict
+ """
+
+ facts = {
+ "response": response,
+ "ansible_params": scrub_dict(ansible_params),
+ "paramgram": scrub_dict(paramgram),
+ }
+
+ if args:
+ facts["custom_args"] = args
+ if kwargs:
+ facts.update(kwargs)
+
+ return facts
+
+ @property
+ def uses_workspace(self):
+ return self._uses_workspace
+
+ @uses_workspace.setter
+ def uses_workspace(self, val):
+ self._uses_workspace = val
+
+ @property
+ def uses_adoms(self):
+ return self._uses_adoms
+
+ @uses_adoms.setter
+ def uses_adoms(self, val):
+ self._uses_adoms = val
+
+ def add_adom_to_lock_list(self, adom):
+ if adom not in self._locked_adom_list:
+ self._locked_adom_list.append(adom)
+
+ def remove_adom_from_lock_list(self, adom):
+ if adom in self._locked_adom_list:
+ self._locked_adom_list.remove(adom)
diff --git a/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/faz_device.py b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/faz_device.py
new file mode 100644
index 00000000..07a69557
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/faz_device.py
@@ -0,0 +1,432 @@
+#!/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: faz_device
+author: Luke Weighall (@lweighall)
+short_description: Add or remove device
+description:
+ - Add or remove a device or list of devices to FortiAnalyzer Device Manager. ADOM Capable.
+
+options:
+ adom:
+ description:
+ - The ADOM the configuration should belong to.
+ required: true
+ default: root
+ type: str
+
+ mode:
+ description:
+ - Add or delete devices. Or promote unregistered devices that are in the FortiAnalyzer "waiting pool"
+ required: false
+ default: add
+ choices: ["add", "delete", "promote"]
+ type: str
+
+ device_username:
+ description:
+ - The username of the device being added to FortiAnalyzer.
+ required: false
+ type: str
+
+ device_password:
+ description:
+ - The password of the device being added to FortiAnalyzer.
+ required: false
+ type: str
+
+ device_ip:
+ description:
+ - The IP of the device being added to FortiAnalyzer.
+ required: false
+ type: str
+
+ device_unique_name:
+ description:
+ - The desired "friendly" name of the device being added to FortiAnalyzer.
+ required: false
+ type: str
+
+ device_serial:
+ description:
+ - The serial number of the device being added to FortiAnalyzer.
+ required: false
+ type: str
+
+ os_type:
+ description:
+ - The os type of the device being added (default 0).
+ required: true
+ choices: ["unknown", "fos", "fsw", "foc", "fml", "faz", "fwb", "fch", "fct", "log", "fmg", "fsa", "fdd", "fac"]
+ type: str
+
+ mgmt_mode:
+ description:
+ - Management Mode of the device you are adding.
+ choices: ["unreg", "fmg", "faz", "fmgfaz"]
+ required: true
+ type: str
+
+ os_minor_vers:
+ description:
+ - Minor OS rev of the device.
+ required: true
+ type: str
+
+ os_ver:
+ description:
+ - Major OS rev of the device
+ required: true
+ choices: ["unknown", "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "6.0"]
+ type: str
+
+ platform_str:
+ description:
+ - Required for determine the platform for VM platforms. ie FortiGate-VM64
+ required: false
+ type: str
+
+ faz_quota:
+ description:
+ - Specifies the quota for the device in FAZ
+ required: False
+ type: str
+'''
+
+EXAMPLES = '''
+- name: DISCOVER AND ADD DEVICE A PHYSICAL FORTIGATE
+ community.fortios.faz_device:
+ adom: "root"
+ device_username: "admin"
+ device_password: "admin"
+ device_ip: "10.10.24.201"
+ device_unique_name: "FGT1"
+ device_serial: "FGVM000000117994"
+ state: "present"
+ mgmt_mode: "faz"
+ os_type: "fos"
+ os_ver: "5.0"
+ minor_rev: 6
+
+
+- name: DISCOVER AND ADD DEVICE A VIRTUAL FORTIGATE
+ community.fortios.faz_device:
+ adom: "root"
+ device_username: "admin"
+ device_password: "admin"
+ device_ip: "10.10.24.202"
+ device_unique_name: "FGT2"
+ mgmt_mode: "faz"
+ os_type: "fos"
+ os_ver: "5.0"
+ minor_rev: 6
+ state: "present"
+ platform_str: "FortiGate-VM64"
+
+- name: DELETE DEVICE FGT01
+ community.fortios.faz_device:
+ adom: "root"
+ device_unique_name: "ansible-fgt01"
+ mode: "delete"
+
+- name: DELETE DEVICE FGT02
+ community.fortios.faz_device:
+ adom: "root"
+ device_unique_name: "ansible-fgt02"
+ mode: "delete"
+
+- name: PROMOTE FGT01 IN FAZ BY IP
+ community.fortios.faz_device:
+ adom: "root"
+ device_password: "fortinet"
+ device_ip: "10.7.220.151"
+ device_username: "ansible"
+ mgmt_mode: "faz"
+ mode: "promote"
+
+
+- name: PROMOTE FGT02 IN FAZ
+ community.fortios.faz_device:
+ adom: "root"
+ device_password: "fortinet"
+ device_unique_name: "ansible-fgt02"
+ device_username: "ansible"
+ mgmt_mode: "faz"
+ mode: "promote"
+
+'''
+
+RETURN = """
+api_result:
+ description: full API response, includes status code and message
+ returned: always
+ type: str
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.connection import Connection
+from ansible_collections.community.fortios.plugins.module_utils.fortianalyzer.fortianalyzer import FortiAnalyzerHandler
+from ansible_collections.community.fortios.plugins.module_utils.fortianalyzer.common import FAZBaseException
+from ansible_collections.community.fortios.plugins.module_utils.fortianalyzer.common import FAZCommon
+from ansible_collections.community.fortios.plugins.module_utils.fortianalyzer.common import FAZMethods
+from ansible_collections.community.fortios.plugins.module_utils.fortianalyzer.common import DEFAULT_RESULT_OBJ
+from ansible_collections.community.fortios.plugins.module_utils.fortianalyzer.common import FAIL_SOCKET_MSG
+
+
+def faz_add_device(faz, paramgram):
+ """
+ This method is used to add devices to the faz or delete them
+ """
+
+ datagram = {
+ "adom": paramgram["adom"],
+ "device": {"adm_usr": paramgram["device_username"], "adm_pass": paramgram["device_password"],
+ "ip": paramgram["ip"], "name": paramgram["device_unique_name"],
+ "mgmt_mode": paramgram["mgmt_mode"], "os_type": paramgram["os_type"],
+ "mr": paramgram["os_minor_vers"]}
+ }
+
+ if paramgram["platform_str"] is not None:
+ datagram["device"]["platform_str"] = paramgram["platform_str"]
+
+ if paramgram["sn"] is not None:
+ datagram["device"]["sn"] = paramgram["sn"]
+
+ if paramgram["device_action"] is not None:
+ datagram["device"]["device_action"] = paramgram["device_action"]
+
+ if paramgram["faz.quota"] is not None:
+ datagram["device"]["faz.quota"] = paramgram["faz.quota"]
+
+ url = '/dvm/cmd/add/device/'
+ response = faz.process_request(url, datagram, FAZMethods.EXEC)
+ return response
+
+
+def faz_delete_device(faz, paramgram):
+ """
+ This method deletes a device from the FAZ
+ """
+ datagram = {
+ "adom": paramgram["adom"],
+ "device": paramgram["device_unique_name"],
+ }
+
+ url = '/dvm/cmd/del/device/'
+ response = faz.process_request(url, datagram, FAZMethods.EXEC)
+ return response
+
+
+def faz_get_unknown_devices(faz):
+ """
+ This method gets devices with an unknown management type field
+ """
+
+ faz_filter = ["mgmt_mode", "==", "0"]
+
+ datagram = {
+ "filter": faz_filter
+ }
+
+ url = "/dvmdb/device"
+ response = faz.process_request(url, datagram, FAZMethods.GET)
+
+ return response
+
+
+def faz_approve_unregistered_device_by_ip(faz, paramgram):
+ """
+ This method approves unregistered devices by ip.
+ """
+ # TRY TO FIND DETAILS ON THIS UNREGISTERED DEVICE
+ unknown_devices = faz_get_unknown_devices(faz)
+ target_device = None
+ if unknown_devices[0] == 0:
+ for device in unknown_devices[1]:
+ if device["ip"] == paramgram["ip"]:
+ target_device = device
+ else:
+ return "No devices are waiting to be registered!"
+
+ # now that we have the target device details...fill out the datagram and make the call to promote it
+ if target_device is not None:
+ target_device_paramgram = {
+ "adom": paramgram["adom"],
+ "ip": target_device["ip"],
+ "device_username": paramgram["device_username"],
+ "device_password": paramgram["device_password"],
+ "device_unique_name": paramgram["device_unique_name"],
+ "sn": target_device["sn"],
+ "os_type": target_device["os_type"],
+ "mgmt_mode": paramgram["mgmt_mode"],
+ "os_minor_vers": target_device["mr"],
+ "os_ver": target_device["os_ver"],
+ "platform_str": target_device["platform_str"],
+ "faz.quota": target_device["faz.quota"],
+ "device_action": paramgram["device_action"]
+ }
+
+ add_device = faz_add_device(faz, target_device_paramgram)
+ return add_device
+
+ return str("Couldn't find the desired device with ip: " + str(paramgram["device_ip"]))
+
+
+def faz_approve_unregistered_device_by_name(faz, paramgram):
+ # TRY TO FIND DETAILS ON THIS UNREGISTERED DEVICE
+ unknown_devices = faz_get_unknown_devices(faz)
+ target_device = None
+ if unknown_devices[0] == 0:
+ for device in unknown_devices[1]:
+ if device["name"] == paramgram["device_unique_name"]:
+ target_device = device
+ else:
+ return "No devices are waiting to be registered!"
+
+ # now that we have the target device details...fill out the datagram and make the call to promote it
+ if target_device is not None:
+ target_device_paramgram = {
+ "adom": paramgram["adom"],
+ "ip": target_device["ip"],
+ "device_username": paramgram["device_username"],
+ "device_password": paramgram["device_password"],
+ "device_unique_name": paramgram["device_unique_name"],
+ "sn": target_device["sn"],
+ "os_type": target_device["os_type"],
+ "mgmt_mode": paramgram["mgmt_mode"],
+ "os_minor_vers": target_device["mr"],
+ "os_ver": target_device["os_ver"],
+ "platform_str": target_device["platform_str"],
+ "faz.quota": target_device["faz.quota"],
+ "device_action": paramgram["device_action"]
+ }
+
+ add_device = faz_add_device(faz, target_device_paramgram)
+ return add_device
+
+ return str("Couldn't find the desired device with name: " + str(paramgram["device_unique_name"]))
+
+
+def main():
+ argument_spec = dict(
+ adom=dict(required=False, type="str", default="root"),
+ mode=dict(choices=["add", "delete", "promote"], type="str", default="add"),
+
+ device_ip=dict(required=False, type="str"),
+ device_username=dict(required=False, type="str"),
+ device_password=dict(required=False, type="str", no_log=True),
+ device_unique_name=dict(required=False, type="str"),
+ device_serial=dict(required=False, type="str"),
+
+ os_type=dict(required=False, type="str", choices=["unknown", "fos", "fsw", "foc", "fml",
+ "faz", "fwb", "fch", "fct", "log", "fmg",
+ "fsa", "fdd", "fac"]),
+ mgmt_mode=dict(required=False, type="str", choices=["unreg", "fmg", "faz", "fmgfaz"]),
+ os_minor_vers=dict(required=False, type="str"),
+ os_ver=dict(required=False, type="str", choices=["unknown", "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "6.0"]),
+ platform_str=dict(required=False, type="str"),
+ faz_quota=dict(required=False, type="str")
+ )
+
+ required_if = [
+ ['mode', 'delete', ['device_unique_name']],
+ ['mode', 'add', ['device_serial', 'device_username',
+ 'device_password', 'device_unique_name', 'device_ip', 'mgmt_mode', 'platform_str']]
+
+ ]
+
+ module = AnsibleModule(argument_spec, supports_check_mode=True, required_if=required_if, )
+
+ # START SESSION LOGIC
+ paramgram = {
+ "adom": module.params["adom"],
+ "mode": module.params["mode"],
+ "ip": module.params["device_ip"],
+ "device_username": module.params["device_username"],
+ "device_password": module.params["device_password"],
+ "device_unique_name": module.params["device_unique_name"],
+ "sn": module.params["device_serial"],
+ "os_type": module.params["os_type"],
+ "mgmt_mode": module.params["mgmt_mode"],
+ "os_minor_vers": module.params["os_minor_vers"],
+ "os_ver": module.params["os_ver"],
+ "platform_str": module.params["platform_str"],
+ "faz.quota": module.params["faz_quota"],
+ "device_action": None
+ }
+ # INSERT THE PARAMGRAM INTO THE MODULE SO WHEN WE PASS IT TO MOD_UTILS.FortiManagerHandler IT HAS THAT INFO
+
+ if paramgram["mode"] == "add":
+ paramgram["device_action"] = "add_model"
+ elif paramgram["mode"] == "promote":
+ paramgram["device_action"] = "promote_unreg"
+ module.paramgram = paramgram
+
+ # TRY TO INIT THE CONNECTION SOCKET PATH AND FortiManagerHandler OBJECT AND TOOLS
+ faz = None
+ if module._socket_path:
+ connection = Connection(module._socket_path)
+ faz = FortiAnalyzerHandler(connection, module)
+ faz.tools = FAZCommon()
+ else:
+ module.fail_json(**FAIL_SOCKET_MSG)
+
+ # BEGIN MODULE-SPECIFIC LOGIC -- THINGS NEED TO HAPPEN DEPENDING ON THE ENDPOINT AND OPERATION
+ results = DEFAULT_RESULT_OBJ
+
+ try:
+ if paramgram["mode"] == "add":
+ results = faz_add_device(faz, paramgram)
+ except BaseException as err:
+ raise FAZBaseException(msg="An error occurred trying to add the device. Error: " + str(err))
+
+ try:
+ if paramgram["mode"] == "promote":
+ if paramgram["ip"] is not None:
+ results = faz_approve_unregistered_device_by_ip(faz, paramgram)
+ elif paramgram["device_unique_name"] is not None:
+ results = faz_approve_unregistered_device_by_name(faz, paramgram)
+ except BaseException as err:
+ raise FAZBaseException(msg="An error occurred trying to promote the device. Error: " + str(err))
+
+ try:
+ if paramgram["mode"] == "delete":
+ results = faz_delete_device(faz, paramgram)
+ except BaseException as err:
+ raise FAZBaseException(msg="An error occurred trying to delete the device. Error: " + str(err))
+
+ # PROCESS RESULTS
+ try:
+ faz.govern_response(module=module, results=results,
+ ansible_facts=faz.construct_ansible_facts(results, module.params, paramgram))
+ except BaseException as err:
+ raise FAZBaseException(msg="An error occurred with govern_response(). Error: " + str(err))
+
+ # This should only be hit if faz.govern_response is missed or failed somehow. In fact. It should never be hit.
+ # But it's here JIC.
+ return module.exit_json(**results[1])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_device.py b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_device.py
new file mode 100644
index 00000000..8f0c6045
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_device.py
@@ -0,0 +1,296 @@
+#!/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: fmgr_device
+notes:
+ - Full Documentation at U(https://ftnt-ansible-docs.readthedocs.io/en/latest/).
+author:
+ - Luke Weighall (@lweighall)
+ - Andrew Welsh (@Ghilli3)
+ - Jim Huber (@p4r4n0y1ng)
+short_description: Add or remove device from FortiManager.
+description:
+ - Add or remove a device or list of devices from FortiManager Device Manager using JSON RPC API.
+
+options:
+ adom:
+ description:
+ - The ADOM the configuration should belong to.
+ required: true
+ default: root
+
+ mode:
+ description:
+ - The desired mode of the specified object.
+ required: false
+ default: add
+ choices: ["add", "delete"]
+
+ blind_add:
+ description:
+ - When adding a device, module will check if it exists, and skip if it does.
+ - If enabled, this option will stop the module from checking if it already exists, and blindly add the device.
+ required: false
+ default: "disable"
+ choices: ["enable", "disable"]
+
+ device_username:
+ description:
+ - The username of the device being added to FortiManager.
+ required: false
+
+ device_password:
+ description:
+ - The password of the device being added to FortiManager.
+ required: false
+
+ device_ip:
+ description:
+ - The IP of the device being added to FortiManager. Supports both IPv4 and IPv6.
+ required: false
+
+ device_unique_name:
+ description:
+ - The desired "friendly" name of the device being added to FortiManager.
+ required: false
+
+ device_serial:
+ description:
+ - The serial number of the device being added to FortiManager.
+ required: false
+'''
+
+EXAMPLES = '''
+- name: DISCOVER AND ADD DEVICE FGT1
+ community.fortios.fmgr_device:
+ adom: "root"
+ device_username: "admin"
+ device_password: "admin"
+ device_ip: "10.10.24.201"
+ device_unique_name: "FGT1"
+ device_serial: "FGVM000000117994"
+ mode: "add"
+ blind_add: "enable"
+
+- name: DISCOVER AND ADD DEVICE FGT2
+ community.fortios.fmgr_device:
+ adom: "root"
+ device_username: "admin"
+ device_password: "admin"
+ device_ip: "10.10.24.202"
+ device_unique_name: "FGT2"
+ device_serial: "FGVM000000117992"
+ mode: "delete"
+'''
+
+RETURN = """
+api_result:
+ description: full API response, includes status code and message
+ returned: always
+ type: str
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.connection import Connection
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.fortimanager import FortiManagerHandler
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGBaseException
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRCommon
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRMethods
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import DEFAULT_RESULT_OBJ
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FAIL_SOCKET_MSG
+
+
+def discover_device(fmgr, paramgram):
+ """
+ This method is used to discover devices before adding them to FMGR
+
+ :param fmgr: The fmgr object instance from fmgr_utils.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+
+ datagram = {
+ "odd_request_form": "True",
+ "device": {"adm_usr": paramgram["device_username"],
+ "adm_pass": paramgram["device_password"],
+ "ip": paramgram["device_ip"]}
+ }
+
+ url = '/dvm/cmd/discover/device/'
+
+ response = fmgr.process_request(url, datagram, FMGRMethods.EXEC)
+ return response
+
+
+def add_device(fmgr, paramgram):
+ """
+ This method is used to add devices to the FMGR
+
+ :param fmgr: The fmgr object instance from fmgr_utils.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+
+ datagram = {
+ "adom": paramgram["adom"],
+ "flags": ["create_task", "nonblocking"],
+ "odd_request_form": "True",
+ "device": {"adm_usr": paramgram["device_username"], "adm_pass": paramgram["device_password"],
+ "ip": paramgram["device_ip"], "name": paramgram["device_unique_name"],
+ "sn": paramgram["device_serial"], "mgmt_mode": "fmgfaz", "flags": 24}
+ }
+
+ url = '/dvm/cmd/add/device/'
+ response = fmgr.process_request(url, datagram, FMGRMethods.EXEC)
+ return response
+
+
+def delete_device(fmgr, paramgram):
+ """
+ This method deletes a device from the FMGR
+
+ :param fmgr: The fmgr object instance from fmgr_utils.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ datagram = {
+ "adom": paramgram["adom"],
+ "flags": ["create_task", "nonblocking"],
+ "device": paramgram["device_unique_name"],
+ }
+
+ url = '/dvm/cmd/del/device/'
+ response = fmgr.process_request(url, datagram, FMGRMethods.EXEC)
+ return response
+
+
+def get_device(fmgr, paramgram):
+ """
+ This method attempts to find the firewall on FortiManager to see if it already exists.
+
+ :param fmgr: The fmgr object instance from fmgr_utils.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ datagram = {
+ "adom": paramgram["adom"],
+ "filter": ["name", "==", paramgram["device_unique_name"]],
+ }
+
+ url = '/dvmdb/adom/{adom}/device/{name}'.format(adom=paramgram["adom"],
+ name=paramgram["device_unique_name"])
+ response = fmgr.process_request(url, datagram, FMGRMethods.GET)
+ return response
+
+
+def main():
+ argument_spec = dict(
+ adom=dict(required=False, type="str", default="root"),
+ mode=dict(choices=["add", "delete"], type="str", default="add"),
+ blind_add=dict(choices=["enable", "disable"], type="str", default="disable"),
+ device_ip=dict(required=False, type="str"),
+ device_username=dict(required=False, type="str"),
+ device_password=dict(required=False, type="str", no_log=True),
+ device_unique_name=dict(required=True, type="str"),
+ device_serial=dict(required=False, type="str")
+ )
+
+ # BUILD MODULE OBJECT SO WE CAN BUILD THE PARAMGRAM
+ module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False, )
+
+ # BUILD THE PARAMGRAM
+ paramgram = {
+ "device_ip": module.params["device_ip"],
+ "device_username": module.params["device_username"],
+ "device_password": module.params["device_password"],
+ "device_unique_name": module.params["device_unique_name"],
+ "device_serial": module.params["device_serial"],
+ "adom": module.params["adom"],
+ "mode": module.params["mode"]
+ }
+
+ # INSERT THE PARAMGRAM INTO THE MODULE SO WHEN WE PASS IT TO MOD_UTILS.FortiManagerHandler IT HAS THAT INFO
+ module.paramgram = paramgram
+
+ # TRY TO INIT THE CONNECTION SOCKET PATH AND FortiManagerHandler OBJECT AND TOOLS
+ fmgr = None
+ if module._socket_path:
+ connection = Connection(module._socket_path)
+ fmgr = FortiManagerHandler(connection, module)
+ fmgr.tools = FMGRCommon()
+ else:
+ module.fail_json(**FAIL_SOCKET_MSG)
+
+ # BEGIN MODULE-SPECIFIC LOGIC -- THINGS NEED TO HAPPEN DEPENDING ON THE ENDPOINT AND OPERATION
+ results = DEFAULT_RESULT_OBJ
+ try:
+ if paramgram["mode"] == "add":
+ # CHECK IF DEVICE EXISTS
+ if module.params["blind_add"] == "disable":
+ exists_results = get_device(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=exists_results, good_codes=(0, -3), changed=False,
+ ansible_facts=fmgr.construct_ansible_facts(exists_results,
+ module.params, paramgram))
+
+ discover_results = discover_device(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=discover_results, stop_on_success=False,
+ ansible_facts=fmgr.construct_ansible_facts(discover_results,
+ module.params, paramgram))
+
+ if discover_results[0] == 0:
+ results = add_device(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=discover_results, stop_on_success=True,
+ changed_if_success=True,
+ ansible_facts=fmgr.construct_ansible_facts(discover_results,
+ module.params, paramgram))
+
+ if paramgram["mode"] == "delete":
+ results = delete_device(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ return module.exit_json(**results[1])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_device_config.py b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_device_config.py
new file mode 100644
index 00000000..e36dad95
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_device_config.py
@@ -0,0 +1,231 @@
+#!/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: fmgr_device_config
+notes:
+ - Full Documentation at U(https://ftnt-ansible-docs.readthedocs.io/en/latest/).
+author:
+ - Luke Weighall (@lweighall)
+ - Andrew Welsh (@Ghilli3)
+ - Jim Huber (@p4r4n0y1ng)
+short_description: Edit device configurations
+description:
+ - Edit device configurations from FortiManager Device Manager using JSON RPC API.
+
+options:
+ adom:
+ description:
+ - The ADOM the configuration should belong to.
+ required: false
+ default: root
+
+ device_unique_name:
+ description:
+ - The unique device's name that you are editing. A.K.A. Friendly name of the device in FortiManager.
+ required: True
+
+ device_hostname:
+ description:
+ - The device's new hostname.
+ required: false
+
+ install_config:
+ description:
+ - Tells FMGR to attempt to install the config after making it.
+ required: false
+ default: disable
+
+ interface:
+ description:
+ - The interface/port number you are editing.
+ required: false
+
+ interface_ip:
+ description:
+ - The IP and subnet of the interface/port you are editing.
+ required: false
+
+ interface_allow_access:
+ description:
+ - Specify what protocols are allowed on the interface, comma-separated list (see examples).
+ required: false
+'''
+
+EXAMPLES = '''
+- name: CHANGE HOSTNAME
+ community.fortios.fmgr_device_config:
+ device_hostname: "ChangedbyAnsible"
+ device_unique_name: "FGT1"
+
+- name: EDIT INTERFACE INFORMATION
+ community.fortios.fmgr_device_config:
+ adom: "root"
+ device_unique_name: "FGT2"
+ interface: "port3"
+ interface_ip: "10.1.1.1/24"
+ interface_allow_access: "ping, telnet, https"
+
+- name: INSTALL CONFIG
+ community.fortios.fmgr_device_config:
+ adom: "root"
+ device_unique_name: "FGT1"
+ install_config: "enable"
+'''
+
+RETURN = """
+api_result:
+ description: full API response, includes status code and message
+ returned: always
+ type: str
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.connection import Connection
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.fortimanager import FortiManagerHandler
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGBaseException
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRCommon
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import DEFAULT_RESULT_OBJ
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FAIL_SOCKET_MSG
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRMethods
+
+
+def update_device_hostname(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ datagram = {
+ "hostname": paramgram["device_hostname"]
+ }
+
+ url = "pm/config/device/{device_name}/global/system/global".format(device_name=paramgram["device_unique_name"])
+ response = fmgr.process_request(url, datagram, FMGRMethods.UPDATE)
+ return response
+
+
+def update_device_interface(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ access_list = list()
+ allow_access_list = paramgram["interface_allow_access"].replace(' ', '')
+ access_list = allow_access_list.split(',')
+
+ datagram = {
+ "allowaccess": access_list,
+ "ip": paramgram["interface_ip"]
+ }
+
+ url = "/pm/config/device/{device_name}/global/system/interface" \
+ "/{interface}".format(device_name=paramgram["device_unique_name"], interface=paramgram["interface"])
+ response = fmgr.process_request(url, datagram, FMGRMethods.UPDATE)
+ return response
+
+
+def exec_config(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ datagram = {
+ "scope": {
+ "name": paramgram["device_unique_name"]
+ },
+ "adom": paramgram["adom"],
+ "flags": "none"
+ }
+
+ url = "/securityconsole/install/device"
+ response = fmgr.process_request(url, datagram, FMGRMethods.EXEC)
+ return response
+
+
+def main():
+ argument_spec = dict(
+ adom=dict(required=False, type="str", default="root"),
+ device_unique_name=dict(required=True, type="str"),
+ device_hostname=dict(required=False, type="str"),
+ interface=dict(required=False, type="str"),
+ interface_ip=dict(required=False, type="str"),
+ interface_allow_access=dict(required=False, type="str"),
+ install_config=dict(required=False, type="str", default="disable"),
+ )
+
+ module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False, )
+ paramgram = {
+ "device_unique_name": module.params["device_unique_name"],
+ "device_hostname": module.params["device_hostname"],
+ "interface": module.params["interface"],
+ "interface_ip": module.params["interface_ip"],
+ "interface_allow_access": module.params["interface_allow_access"],
+ "install_config": module.params["install_config"],
+ "adom": module.params["adom"]
+ }
+ module.paramgram = paramgram
+ fmgr = None
+ if module._socket_path:
+ connection = Connection(module._socket_path)
+ fmgr = FortiManagerHandler(connection, module)
+ fmgr.tools = FMGRCommon()
+ else:
+ module.fail_json(**FAIL_SOCKET_MSG)
+
+ # BEGIN MODULE-SPECIFIC LOGIC -- THINGS NEED TO HAPPEN DEPENDING ON THE ENDPOINT AND OPERATION
+ results = DEFAULT_RESULT_OBJ
+ try:
+ if paramgram["device_hostname"] is not None:
+ results = update_device_hostname(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+
+ if paramgram["interface_ip"] is not None or paramgram["interface_allow_access"] is not None:
+ results = update_device_interface(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+
+ if paramgram["install_config"] == "enable":
+ results = exec_config(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ return module.exit_json(**results[1])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_device_group.py b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_device_group.py
new file mode 100644
index 00000000..9c8c0ad6
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_device_group.py
@@ -0,0 +1,323 @@
+#!/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: fmgr_device_group
+notes:
+ - Full Documentation at U(https://ftnt-ansible-docs.readthedocs.io/en/latest/).
+author:
+ - Luke Weighall (@lweighall)
+ - Andrew Welsh (@Ghilli3)
+ - Jim Huber (@p4r4n0y1ng)
+short_description: Alter FortiManager device groups.
+description:
+ - Add or edit device groups and assign devices to device groups FortiManager Device Manager using JSON RPC API.
+
+options:
+ adom:
+ description:
+ - The ADOM the configuration should belong to.
+ required: false
+ default: root
+
+ vdom:
+ description:
+ - The VDOM of the Fortigate you want to add, must match the device in FMGR. Usually root.
+ required: false
+ default: root
+
+ mode:
+ description:
+ - Sets one of three modes for managing the object.
+ - Allows use of soft-adds instead of overwriting existing values
+ choices: ['add', 'set', 'delete', 'update']
+ required: false
+ default: add
+
+ grp_name:
+ description:
+ - The name of the device group.
+ required: false
+
+ grp_desc:
+ description:
+ - The description of the device group.
+ required: false
+
+ grp_members:
+ description:
+ - A comma separated list of device names or device groups to be added as members to the device group.
+ - If Group Members are defined, and mode="delete", only group members will be removed.
+ - If you want to delete a group itself, you must omit this parameter from the task in playbook.
+ required: false
+
+'''
+
+
+EXAMPLES = '''
+- name: CREATE DEVICE GROUP
+ community.fortios.fmgr_device_group:
+ grp_name: "TestGroup"
+ grp_desc: "CreatedbyAnsible"
+ adom: "ansible"
+ mode: "add"
+
+- name: CREATE DEVICE GROUP 2
+ community.fortios.fmgr_device_group:
+ grp_name: "AnsibleGroup"
+ grp_desc: "CreatedbyAnsible"
+ adom: "ansible"
+ mode: "add"
+
+- name: ADD DEVICES TO DEVICE GROUP
+ community.fortios.fmgr_device_group:
+ mode: "add"
+ grp_name: "TestGroup"
+ grp_members: "FGT1,FGT2"
+ adom: "ansible"
+ vdom: "root"
+
+- name: REMOVE DEVICES TO DEVICE GROUP
+ community.fortios.fmgr_device_group:
+ mode: "delete"
+ grp_name: "TestGroup"
+ grp_members: "FGT1,FGT2"
+ adom: "ansible"
+
+- name: DELETE DEVICE GROUP
+ community.fortios.fmgr_device_group:
+ grp_name: "AnsibleGroup"
+ grp_desc: "CreatedbyAnsible"
+ mode: "delete"
+ adom: "ansible"
+'''
+
+RETURN = """
+api_result:
+ description: full API response, includes status code and message
+ returned: always
+ type: str
+"""
+
+from ansible.module_utils.basic import AnsibleModule, env_fallback
+from ansible.module_utils.connection import Connection
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.fortimanager import FortiManagerHandler
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGBaseException
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRCommon
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRMethods
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import DEFAULT_RESULT_OBJ
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FAIL_SOCKET_MSG
+
+
+def get_groups(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+
+ datagram = {
+ "method": "get"
+ }
+
+ url = '/dvmdb/adom/{adom}/group'.format(adom=paramgram["adom"])
+ response = fmgr.process_request(url, datagram, FMGRMethods.GET)
+ return response
+
+
+def add_device_group(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ # INIT A BASIC OBJECTS
+ response = DEFAULT_RESULT_OBJ
+ url = ""
+ mode = paramgram["mode"]
+
+ datagram = {
+ "name": paramgram["grp_name"],
+ "desc": paramgram["grp_desc"],
+ "os_type": "fos"
+ }
+
+ url = '/dvmdb/adom/{adom}/group'.format(adom=paramgram["adom"])
+
+ # IF MODE = SET -- USE THE 'SET' API CALL MODE
+ if mode == "set":
+ response = fmgr.process_request(url, datagram, FMGRMethods.SET)
+ # IF MODE = UPDATE -- USER THE 'UPDATE' API CALL MODE
+ elif mode == "update":
+ response = fmgr.process_request(url, datagram, FMGRMethods.UPDATE)
+ # IF MODE = ADD -- USE THE 'ADD' API CALL MODE
+ elif mode == "add":
+ response = fmgr.process_request(url, datagram, FMGRMethods.ADD)
+
+ return response
+
+
+def delete_device_group(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ # INIT A BASIC OBJECTS
+ response = DEFAULT_RESULT_OBJ
+ url = ""
+
+ datagram = {
+ "adom": paramgram["adom"],
+ "name": paramgram["grp_name"]
+ }
+
+ url = '/dvmdb/adom/{adom}/group/{grp_name}'.format(adom=paramgram["adom"], grp_name=paramgram["grp_name"])
+ response = fmgr.process_request(url, datagram, FMGRMethods.DELETE)
+ return response
+
+
+def add_group_member(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ # INIT A BASIC OBJECTS
+ response = DEFAULT_RESULT_OBJ
+ url = ""
+ device_member_list = paramgram["grp_members"].replace(' ', '')
+ device_member_list = device_member_list.split(',')
+
+ for dev_name in device_member_list:
+ datagram = {'name': dev_name, 'vdom': paramgram["vdom"]}
+
+ url = '/dvmdb/adom/{adom}/group/{grp_name}/object member'.format(adom=paramgram["adom"],
+ grp_name=paramgram["grp_name"])
+ response = fmgr.process_request(url, datagram, FMGRMethods.ADD)
+
+ return response
+
+
+def delete_group_member(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ # INIT A BASIC OBJECTS
+ response = DEFAULT_RESULT_OBJ
+ url = ""
+ device_member_list = paramgram["grp_members"].replace(' ', '')
+ device_member_list = device_member_list.split(',')
+
+ for dev_name in device_member_list:
+ datagram = {'name': dev_name, 'vdom': paramgram["vdom"]}
+
+ url = '/dvmdb/adom/{adom}/group/{grp_name}/object member'.format(adom=paramgram["adom"],
+ grp_name=paramgram["grp_name"])
+ response = fmgr.process_request(url, datagram, FMGRMethods.DELETE)
+
+ return response
+
+
+def main():
+ argument_spec = dict(
+ adom=dict(required=False, type="str", default="root"),
+ vdom=dict(required=False, type="str", default="root"),
+ mode=dict(choices=["add", "set", "delete", "update"], type="str", default="add"),
+ grp_desc=dict(required=False, type="str"),
+ grp_name=dict(required=True, type="str"),
+ grp_members=dict(required=False, type="str"),
+ )
+
+ module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False, )
+ paramgram = {
+ "mode": module.params["mode"],
+ "grp_name": module.params["grp_name"],
+ "grp_desc": module.params["grp_desc"],
+ "grp_members": module.params["grp_members"],
+ "adom": module.params["adom"],
+ "vdom": module.params["vdom"]
+ }
+ module.paramgram = paramgram
+ fmgr = None
+ if module._socket_path:
+ connection = Connection(module._socket_path)
+ fmgr = FortiManagerHandler(connection, module)
+ fmgr.tools = FMGRCommon()
+ else:
+ module.fail_json(**FAIL_SOCKET_MSG)
+
+ # BEGIN MODULE-SPECIFIC LOGIC -- THINGS NEED TO HAPPEN DEPENDING ON THE ENDPOINT AND OPERATION
+ results = DEFAULT_RESULT_OBJ
+ try:
+ # PROCESS THE GROUP ADDS FIRST
+ if paramgram["grp_name"] is not None and paramgram["mode"] in ["add", "set", "update"]:
+ # add device group
+ results = add_device_group(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+
+ # PROCESS THE GROUP MEMBER ADDS
+ if paramgram["grp_members"] is not None and paramgram["mode"] in ["add", "set", "update"]:
+ # assign devices to device group
+ results = add_group_member(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+
+ # PROCESS THE GROUP MEMBER DELETES
+ if paramgram["grp_members"] is not None and paramgram["mode"] == "delete":
+ # remove devices grom a group
+ results = delete_group_member(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+
+ # PROCESS THE GROUP DELETES, ONLY IF GRP_MEMBERS IS NOT NULL TOO
+ if paramgram["grp_name"] is not None and paramgram["mode"] == "delete" and paramgram["grp_members"] is None:
+ # delete device group
+ results = delete_device_group(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ return module.exit_json(**results[1])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_device_provision_template.py b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_device_provision_template.py
new file mode 100644
index 00000000..c7188694
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_device_provision_template.py
@@ -0,0 +1,1546 @@
+#!/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: fmgr_device_provision_template
+notes:
+ - Full Documentation at U(https://ftnt-ansible-docs.readthedocs.io/en/latest/).
+author:
+ - Luke Weighall (@lweighall)
+ - Andrew Welsh (@Ghilli3)
+ - Jim Huber (@p4r4n0y1ng)
+short_description: Manages Device Provisioning Templates in FortiManager.
+description:
+ - Allows the editing and assignment of device provisioning templates in FortiManager.
+
+options:
+ adom:
+ description:
+ - The ADOM the configuration should belong to.
+ required: true
+
+ mode:
+ description:
+ - Sets one of three modes for managing the object.
+ - Allows use of soft-adds instead of overwriting existing values.
+ choices: ['add', 'set', 'delete', 'update']
+ required: false
+ default: add
+
+ device_unique_name:
+ description:
+ - The unique device's name that you are editing.
+ required: True
+
+ provisioning_template:
+ description:
+ - The provisioning template you want to apply (default = default).
+ required: True
+
+ provision_targets:
+ description:
+ - The friendly names of devices in FortiManager to assign the provisioning template to. CSV separated list.
+ required: True
+
+ snmp_status:
+ description:
+ - Enables or disables SNMP globally.
+ required: False
+ choices: ["enable", "disable"]
+
+ snmp_v2c_query_port:
+ description:
+ - Sets the snmp v2c community query port.
+ required: False
+
+ snmp_v2c_trap_port:
+ description:
+ - Sets the snmp v2c community trap port.
+ required: False
+
+ snmp_v2c_status:
+ description:
+ - Enables or disables the v2c community specified.
+ required: False
+ choices: ["enable", "disable"]
+
+ snmp_v2c_trap_status:
+ description:
+ - Enables or disables the v2c community specified for traps.
+ required: False
+ choices: ["enable", "disable"]
+
+ snmp_v2c_query_status:
+ description:
+ - Enables or disables the v2c community specified for queries.
+ required: False
+ choices: ["enable", "disable"]
+
+ snmp_v2c_name:
+ description:
+ - Specifies the v2c community name.
+ required: False
+
+ snmp_v2c_id:
+ description:
+ - Primary key for the snmp community. this must be unique!
+ required: False
+
+ snmp_v2c_trap_src_ipv4:
+ description:
+ - Source ip the traps should come from IPv4.
+ required: False
+
+ snmp_v2c_trap_hosts_ipv4:
+ description: >
+ - IPv4 addresses of the hosts that should get SNMP v2c traps, comma separated, must include mask
+ ("10.7.220.59 255.255.255.255, 10.7.220.60 255.255.255.255").
+ required: False
+
+ snmp_v2c_query_hosts_ipv4:
+ description: >
+ - IPv4 addresses or subnets that are allowed to query SNMP v2c, comma separated
+ ("10.7.220.59 255.255.255.0, 10.7.220.0 255.255.255.0").
+ required: False
+
+ snmpv3_auth_proto:
+ description:
+ - SNMPv3 auth protocol.
+ required: False
+ choices: ["md5", "sha"]
+
+ snmpv3_auth_pwd:
+ description:
+ - SNMPv3 auth pwd __ currently not encrypted! ensure this file is locked down permissions wise!
+ required: False
+
+ snmpv3_name:
+ description:
+ - SNMPv3 user name.
+ required: False
+
+ snmpv3_notify_hosts:
+ description:
+ - List of ipv4 hosts to send snmpv3 traps to. Comma separated IPv4 list.
+ required: False
+
+ snmpv3_priv_proto:
+ description:
+ - SNMPv3 priv protocol.
+ required: False
+ choices: ["aes", "des", "aes256", "aes256cisco"]
+
+ snmpv3_priv_pwd:
+ description:
+ - SNMPv3 priv pwd currently not encrypted! ensure this file is locked down permissions wise!
+ required: False
+
+ snmpv3_queries:
+ description:
+ - Allow snmpv3_queries.
+ required: False
+ choices: ["enable", "disable"]
+
+ snmpv3_query_port:
+ description:
+ - SNMPv3 query port.
+ required: False
+
+ snmpv3_security_level:
+ description:
+ - SNMPv3 security level.
+ required: False
+ choices: ["no-auth-no-priv", "auth-no-priv", "auth-priv"]
+
+ snmpv3_source_ip:
+ description:
+ - SNMPv3 source ipv4 address for traps.
+ required: False
+
+ snmpv3_status:
+ description:
+ - SNMPv3 user is enabled or disabled.
+ required: False
+ choices: ["enable", "disable"]
+
+ snmpv3_trap_rport:
+ description:
+ - SNMPv3 trap remote port.
+ required: False
+
+ snmpv3_trap_status:
+ description:
+ - SNMPv3 traps is enabled or disabled.
+ required: False
+ choices: ["enable", "disable"]
+
+ syslog_port:
+ description:
+ - Syslog port that will be set.
+ required: False
+
+ syslog_server:
+ description:
+ - Server the syslogs will be sent to.
+ required: False
+
+ syslog_status:
+ description:
+ - Enables or disables syslogs.
+ required: False
+ choices: ["enable", "disable"]
+
+ syslog_mode:
+ description:
+ - Remote syslog logging over UDP/Reliable TCP.
+ - choice | udp | Enable syslogging over UDP.
+ - choice | legacy-reliable | Enable legacy reliable syslogging by RFC3195 (Reliable Delivery for Syslog).
+ - choice | reliable | Enable reliable syslogging by RFC6587 (Transmission of Syslog Messages over TCP).
+ required: false
+ choices: ["udp", "legacy-reliable", "reliable"]
+ default: "udp"
+
+ syslog_filter:
+ description:
+ - Sets the logging level for syslog.
+ required: False
+ choices: ["emergency", "alert", "critical", "error", "warning", "notification", "information", "debug"]
+
+ syslog_facility:
+ description:
+ - Remote syslog facility.
+ - choice | kernel | Kernel messages.
+ - choice | user | Random user-level messages.
+ - choice | mail | Mail system.
+ - choice | daemon | System daemons.
+ - choice | auth | Security/authorization messages.
+ - choice | syslog | Messages generated internally by syslog.
+ - choice | lpr | Line printer subsystem.
+ - choice | news | Network news subsystem.
+ - choice | uucp | Network news subsystem.
+ - choice | cron | Clock daemon.
+ - choice | authpriv | Security/authorization messages (private).
+ - choice | ftp | FTP daemon.
+ - choice | ntp | NTP daemon.
+ - choice | audit | Log audit.
+ - choice | alert | Log alert.
+ - choice | clock | Clock daemon.
+ - choice | local0 | Reserved for local use.
+ - choice | local1 | Reserved for local use.
+ - choice | local2 | Reserved for local use.
+ - choice | local3 | Reserved for local use.
+ - choice | local4 | Reserved for local use.
+ - choice | local5 | Reserved for local use.
+ - choice | local6 | Reserved for local use.
+ - choice | local7 | Reserved for local use.
+ required: false
+ choices: ["kernel", "user", "mail", "daemon", "auth", "syslog",
+ "lpr", "news", "uucp", "cron", "authpriv", "ftp", "ntp", "audit",
+ "alert", "clock", "local0", "local1", "local2", "local3", "local4", "local5", "local6", "local7"]
+ default: "syslog"
+
+ syslog_enc_algorithm:
+ description:
+ - Enable/disable reliable syslogging with TLS encryption.
+ - choice | high | SSL communication with high encryption algorithms.
+ - choice | low | SSL communication with low encryption algorithms.
+ - choice | disable | Disable SSL communication.
+ - choice | high-medium | SSL communication with high and medium encryption algorithms.
+ required: false
+ choices: ["high", "low", "disable", "high-medium"]
+ default: "disable"
+
+ syslog_certificate:
+ description:
+ - Certificate used to communicate with Syslog server if encryption on.
+ required: false
+
+ ntp_status:
+ description:
+ - Enables or disables ntp.
+ required: False
+ choices: ["enable", "disable"]
+
+ ntp_sync_interval:
+ description:
+ - Sets the interval in minutes for ntp sync.
+ required: False
+
+ ntp_type:
+ description:
+ - Enables fortiguard servers or custom servers are the ntp source.
+ required: False
+ choices: ["fortiguard", "custom"]
+
+ ntp_server:
+ description:
+ - Only used with custom ntp_type -- specifies IP of server to sync to -- comma separated ip addresses for multiples.
+ required: False
+
+ ntp_auth:
+ description:
+ - Enables or disables ntp authentication.
+ required: False
+ choices: ["enable", "disable"]
+
+ ntp_auth_pwd:
+ description:
+ - Sets the ntp auth password.
+ required: False
+
+ ntp_v3:
+ description:
+ - Enables or disables ntpv3 (default is ntpv4).
+ required: False
+ choices: ["enable", "disable"]
+
+ admin_https_redirect:
+ description:
+ - Enables or disables https redirect from http.
+ required: False
+ choices: ["enable", "disable"]
+
+ admin_https_port:
+ description:
+ - SSL admin gui port number.
+ required: False
+
+ admin_http_port:
+ description:
+ - Non-SSL admin gui port number.
+ required: False
+
+ admin_timeout:
+ description:
+ - Admin timeout in minutes.
+ required: False
+
+ admin_language:
+ description:
+ - Sets the admin gui language.
+ required: False
+ choices: ["english", "simch", "japanese", "korean", "spanish", "trach", "french", "portuguese"]
+
+ admin_switch_controller:
+ description:
+ - Enables or disables the switch controller.
+ required: False
+ choices: ["enable", "disable"]
+
+ admin_gui_theme:
+ description:
+ - Changes the admin gui theme.
+ required: False
+ choices: ["green", "red", "blue", "melongene", "mariner"]
+
+ admin_enable_fortiguard:
+ description:
+ - Enables FortiGuard security updates to their default settings.
+ required: False
+ choices: ["none", "direct", "this-fmg"]
+
+ admin_fortianalyzer_target:
+ description:
+ - Configures faz target.
+ required: False
+
+ admin_fortiguard_target:
+ description:
+ - Configures fortiguard target.
+ - admin_enable_fortiguard must be set to "direct".
+ required: False
+
+ smtp_username:
+ description:
+ - SMTP auth username.
+ required: False
+
+ smtp_password:
+ description:
+ - SMTP password.
+ required: False
+
+ smtp_port:
+ description:
+ - SMTP port number.
+ required: False
+
+ smtp_replyto:
+ description:
+ - SMTP reply to address.
+ required: False
+
+ smtp_conn_sec:
+ description:
+ - defines the ssl level for smtp.
+ required: False
+ choices: ["none", "starttls", "smtps"]
+
+ smtp_server:
+ description:
+ - SMTP server ipv4 address.
+ required: False
+
+ smtp_source_ipv4:
+ description:
+ - SMTP source ip address.
+ required: False
+
+ smtp_validate_cert:
+ description:
+ - Enables or disables valid certificate checking for smtp.
+ required: False
+ choices: ["enable", "disable"]
+
+ dns_suffix:
+ description:
+ - Sets the local dns domain suffix.
+ required: False
+
+ dns_primary_ipv4:
+ description:
+ - primary ipv4 dns forwarder.
+ required: False
+
+ dns_secondary_ipv4:
+ description:
+ - secondary ipv4 dns forwarder.
+ required: False
+
+ delete_provisioning_template:
+ description:
+ - If specified, all other options are ignored. The specified provisioning template will be deleted.
+ required: False
+
+'''
+
+
+EXAMPLES = '''
+- name: SET SNMP SYSTEM INFO
+ community.fortios.fmgr_device_provision_template:
+ provisioning_template: "default"
+ snmp_status: "enable"
+ mode: "set"
+
+- name: SET SNMP SYSTEM INFO ANSIBLE ADOM
+ community.fortios.fmgr_device_provision_template:
+ provisioning_template: "default"
+ snmp_status: "enable"
+ mode: "set"
+ adom: "ansible"
+
+- name: SET SNMP SYSTEM INFO different template (SNMPv2)
+ community.fortios.fmgr_device_provision_template:
+ provisioning_template: "ansibleTest"
+ snmp_status: "enable"
+ mode: "set"
+ adom: "ansible"
+ snmp_v2c_query_port: "162"
+ snmp_v2c_trap_port: "161"
+ snmp_v2c_status: "enable"
+ snmp_v2c_trap_status: "enable"
+ snmp_v2c_query_status: "enable"
+ snmp_v2c_name: "ansibleV2c"
+ snmp_v2c_id: "1"
+ snmp_v2c_trap_src_ipv4: "10.7.220.41"
+ snmp_v2c_trap_hosts_ipv4: "10.7.220.59 255.255.255.255, 10.7.220.60 255.255.255.255"
+ snmp_v2c_query_hosts_ipv4: "10.7.220.59 255.255.255.255, 10.7.220.0 255.255.255.0"
+
+- name: SET SNMP SYSTEM INFO different template (SNMPv3)
+ community.fortios.fmgr_device_provision_template:
+ provisioning_template: "ansibleTest"
+ snmp_status: "enable"
+ mode: "set"
+ adom: "ansible"
+ snmpv3_auth_proto: "sha"
+ snmpv3_auth_pwd: "fortinet"
+ snmpv3_name: "ansibleSNMPv3"
+ snmpv3_notify_hosts: "10.7.220.59,10.7.220.60"
+ snmpv3_priv_proto: "aes256"
+ snmpv3_priv_pwd: "fortinet"
+ snmpv3_queries: "enable"
+ snmpv3_query_port: "161"
+ snmpv3_security_level: "auth_priv"
+ snmpv3_source_ip: "0.0.0.0"
+ snmpv3_status: "enable"
+ snmpv3_trap_rport: "162"
+ snmpv3_trap_status: "enable"
+
+- name: SET SYSLOG INFO
+ community.fortios.fmgr_device_provision_template:
+ provisioning_template: "ansibleTest"
+ mode: "set"
+ adom: "ansible"
+ syslog_server: "10.7.220.59"
+ syslog_port: "514"
+ syslog_mode: "disable"
+ syslog_status: "enable"
+ syslog_filter: "information"
+
+- name: SET NTP TO FORTIGUARD
+ community.fortios.fmgr_device_provision_template:
+ provisioning_template: "ansibleTest"
+ mode: "set"
+ adom: "ansible"
+ ntp_status: "enable"
+ ntp_sync_interval: "60"
+ type: "fortiguard"
+
+- name: SET NTP TO CUSTOM SERVER
+ community.fortios.fmgr_device_provision_template:
+ provisioning_template: "ansibleTest"
+ mode: "set"
+ adom: "ansible"
+ ntp_status: "enable"
+ ntp_sync_interval: "60"
+ ntp_type: "custom"
+ ntp_server: "10.7.220.32,10.7.220.1"
+ ntp_auth: "enable"
+ ntp_auth_pwd: "fortinet"
+ ntp_v3: "disable"
+
+- name: SET ADMIN GLOBAL SETTINGS
+ community.fortios.fmgr_device_provision_template:
+ provisioning_template: "ansibleTest"
+ mode: "set"
+ adom: "ansible"
+ admin_https_redirect: "enable"
+ admin_https_port: "4433"
+ admin_http_port: "8080"
+ admin_timeout: "30"
+ admin_language: "english"
+ admin_switch_controller: "enable"
+ admin_gui_theme: "blue"
+ admin_enable_fortiguard: "direct"
+ admin_fortiguard_target: "10.7.220.128"
+ admin_fortianalyzer_target: "10.7.220.61"
+
+- name: SET CUSTOM SMTP SERVER
+ community.fortios.fmgr_device_provision_template:
+ provisioning_template: "ansibleTest"
+ mode: "set"
+ adom: "ansible"
+ smtp_username: "ansible"
+ smtp_password: "fortinet"
+ smtp_port: "25"
+ smtp_replyto: "ansible@do-not-reply.com"
+ smtp_conn_sec: "starttls"
+ smtp_server: "10.7.220.32"
+ smtp_source_ipv4: "0.0.0.0"
+ smtp_validate_cert: "disable"
+
+- name: SET DNS SERVERS
+ community.fortios.fmgr_device_provision_template:
+ provisioning_template: "ansibleTest"
+ mode: "set"
+ adom: "ansible"
+ dns_suffix: "ansible.local"
+ dns_primary_ipv4: "8.8.8.8"
+ dns_secondary_ipv4: "4.4.4.4"
+
+- name: SET PROVISIONING TEMPLATE DEVICE TARGETS IN FORTIMANAGER
+ community.fortios.fmgr_device_provision_template:
+ provisioning_template: "ansibleTest"
+ mode: "set"
+ adom: "ansible"
+ provision_targets: "FGT1, FGT2"
+
+- name: DELETE ENTIRE PROVISIONING TEMPLATE
+ community.fortios.fmgr_device_provision_template:
+ delete_provisioning_template: "ansibleTest"
+ mode: "delete"
+ adom: "ansible"
+
+'''
+RETURN = """
+api_result:
+ description: full API response, includes status code and message
+ returned: always
+ type: str
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.connection import Connection
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.fortimanager import FortiManagerHandler
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGBaseException
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRCommon
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRMethods
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import DEFAULT_RESULT_OBJ
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FAIL_SOCKET_MSG
+
+
+def get_devprof(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+
+ response = DEFAULT_RESULT_OBJ
+ datagram = {}
+
+ url = "/pm/devprof/adom/{adom}/{name}".format(adom=paramgram["adom"], name=paramgram["provisioning_template"])
+ response = fmgr.process_request(url, datagram, FMGRMethods.GET)
+
+ return response
+
+
+def set_devprof(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+
+ response = DEFAULT_RESULT_OBJ
+ if paramgram["mode"] in ['set', 'add', 'update']:
+ datagram = {
+ "name": paramgram["provisioning_template"],
+ "type": "devprof",
+ "description": "CreatedByAnsible",
+ }
+ url = "/pm/devprof/adom/{adom}".format(adom=paramgram["adom"])
+
+ elif paramgram["mode"] == "delete":
+ datagram = {}
+
+ url = "/pm/devprof/adom/{adom}/{name}".format(adom=paramgram["adom"],
+ name=paramgram["delete_provisioning_template"])
+
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+ return response
+
+
+def get_devprof_scope(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+
+ response = DEFAULT_RESULT_OBJ
+ datagram = {
+ "name": paramgram["provisioning_template"],
+ "type": "devprof",
+ "description": "CreatedByAnsible",
+ }
+
+ url = "/pm/devprof/adom/{adom}".format(adom=paramgram["adom"])
+ response = fmgr.process_request(url, datagram, FMGRMethods.GET)
+
+ return response
+
+
+def set_devprof_scope(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+
+ response = DEFAULT_RESULT_OBJ
+ if paramgram["mode"] in ['set', 'add', 'update']:
+ datagram = {
+ "name": paramgram["provisioning_template"],
+ "type": "devprof",
+ "description": "CreatedByAnsible",
+ }
+
+ targets = []
+ for target in paramgram["provision_targets"].split(","):
+ # split the host on the space to get the mask out
+ new_target = {"name": target.strip()}
+ targets.append(new_target)
+
+ datagram["scope member"] = targets
+
+ url = "/pm/devprof/adom/{adom}".format(adom=paramgram["adom"])
+
+ elif paramgram["mode"] == "delete":
+ datagram = {
+ "name": paramgram["provisioning_template"],
+ "type": "devprof",
+ "description": "CreatedByAnsible",
+ "scope member": paramgram["targets_to_add"]
+ }
+
+ url = "/pm/devprof/adom/{adom}".format(adom=paramgram["adom"])
+
+ response = fmgr.process_request(url, datagram, FMGRMethods.SET)
+ return response
+
+
+def set_devprof_snmp(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ paramgram["mode"] = paramgram["mode"]
+ adom = paramgram["adom"]
+
+ response = DEFAULT_RESULT_OBJ
+ datagram = {
+ "status": paramgram["snmp_status"]
+ }
+ url = "/pm/config/adom/{adom}/devprof/" \
+ "{provisioning_template}/system/snmp/sysinfo".format(adom=adom,
+ provisioning_template=paramgram["provisioning_template"])
+
+ response = fmgr.process_request(url, datagram, FMGRMethods.SET)
+ return response
+
+
+def set_devprof_snmp_v2c(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ paramgram["mode"] = paramgram["mode"]
+ adom = paramgram["adom"]
+
+ response = DEFAULT_RESULT_OBJ
+ if paramgram["mode"] in ['set', 'add', 'update']:
+ datagram = {
+ "query-v2c-port": paramgram["snmp_v2c_query_port"],
+ "trap-v2c-rport": paramgram["snmp_v2c_trap_port"],
+ "status": paramgram["snmp_v2c_status"],
+ "trap-v2c-status": paramgram["snmp_v2c_trap_status"],
+ "query-v2c-status": paramgram["snmp_v2c_query_status"],
+ "name": paramgram["snmp_v2c_name"],
+ "id": paramgram["snmp_v2c_id"],
+ "meta fields": dict(),
+ "hosts": list(),
+ "events": 411578417151,
+ "query-v1-status": 0,
+ "query-v1-port": 161,
+ "trap-v1-status": 0,
+ "trap-v1-lport": 162,
+ "trap-v1-rport": 162,
+ "trap-v2c-lport": 162,
+ }
+
+ # BUILD THE HOST STRINGS
+ id_counter = 1
+ if paramgram["snmp_v2c_trap_hosts_ipv4"] or paramgram["snmp_v2c_query_hosts_ipv4"]:
+ hosts = []
+ if paramgram["snmp_v2c_query_hosts_ipv4"]:
+ for ipv4_host in paramgram["snmp_v2c_query_hosts_ipv4"].strip().split(","):
+ # split the host on the space to get the mask out
+ new_ipv4_host = {"ha-direct": "enable",
+ "host-type": "query",
+ "id": id_counter,
+ "ip": ipv4_host.strip().split(),
+ "meta fields": {},
+ "source-ip": "0.0.0.0"}
+ hosts.append(new_ipv4_host)
+ id_counter += 1
+
+ if paramgram["snmp_v2c_trap_hosts_ipv4"]:
+ for ipv4_host in paramgram["snmp_v2c_trap_hosts_ipv4"].strip().split(","):
+ # split the host on the space to get the mask out
+ new_ipv4_host = {"ha-direct": "enable",
+ "host-type": "trap",
+ "id": id_counter,
+ "ip": ipv4_host.strip().split(),
+ "meta fields": {},
+ "source-ip": paramgram["snmp_v2c_trap_src_ipv4"]}
+ hosts.append(new_ipv4_host)
+ id_counter += 1
+ datagram["hosts"] = hosts
+
+ url = "/pm/config/adom/{adom}/devprof/" \
+ "{provisioning_template}/system/snmp/community".format(adom=adom,
+ provisioning_template=paramgram[
+ "provisioning_template"])
+ elif paramgram["mode"] == "delete":
+ datagram = {
+ "confirm": 1
+ }
+
+ url = "/pm/config/adom/{adom}/" \
+ "devprof/{provisioning_template}/" \
+ "system/snmp/community/{snmp_v2c_id}".format(adom=adom,
+ provisioning_template=paramgram["provisioning_template"],
+ snmp_v2c_id=paramgram["snmp_v2c_id"])
+
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+ return response
+
+
+def set_devprof_snmp_v3(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ paramgram["mode"] = paramgram["mode"]
+ adom = paramgram["adom"]
+
+ response = DEFAULT_RESULT_OBJ
+ if paramgram["mode"] in ['set', 'add', 'update']:
+ datagram = {}
+ datagram["auth-pwd"] = paramgram["snmpv3_auth_pwd"]
+ datagram["priv-pwd"] = paramgram["snmpv3_priv_pwd"]
+ datagram["trap-rport"] = paramgram["snmpv3_trap_rport"]
+ datagram["query-port"] = paramgram["snmpv3_query_port"]
+ datagram["name"] = paramgram["snmpv3_name"]
+ datagram["notify-hosts"] = paramgram["snmpv3_notify_hosts"].strip().split(",")
+ datagram["events"] = 1647387997183
+ datagram["trap-lport"] = 162
+
+ datagram["source-ip"] = paramgram["snmpv3_source_ip"]
+ datagram["ha-direct"] = 0
+
+ url = "/pm/config/adom/{adom}/" \
+ "devprof/{provisioning_template}/" \
+ "system/snmp/user".format(adom=adom,
+ provisioning_template=paramgram["provisioning_template"])
+ elif paramgram["mode"] == "delete":
+ datagram = {
+ "confirm": 1
+ }
+
+ url = "/pm/config/adom/{adom}/devprof/" \
+ "{provisioning_template}/system/snmp" \
+ "/user/{snmpv3_name}".format(adom=adom,
+ provisioning_template=paramgram["provisioning_template"],
+ snmpv3_name=paramgram["snmpv3_name"])
+
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+ return response
+
+
+def set_devprof_syslog(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ paramgram["mode"] = paramgram["mode"]
+ adom = paramgram["adom"]
+
+ response = DEFAULT_RESULT_OBJ
+
+ datagram = {
+ "status": paramgram["syslog_status"],
+ "port": paramgram["syslog_port"],
+ "server": paramgram["syslog_server"],
+ "mode": paramgram["syslog_mode"],
+ "facility": paramgram["syslog_facility"]
+ }
+
+ if paramgram["mode"] in ['set', 'add', 'update']:
+ if paramgram["syslog_enc_algorithm"] in ["high", "low", "high-medium"] \
+ and paramgram["syslog_certificate"] is not None:
+ datagram["certificate"] = paramgram["certificate"]
+ datagram["enc-algorithm"] = paramgram["syslog_enc_algorithm"]
+
+ url = "/pm/config/adom/{adom}/" \
+ "devprof/{provisioning_template}/" \
+ "log/syslogd/setting".format(adom=adom,
+ provisioning_template=paramgram["provisioning_template"])
+ elif paramgram["mode"] == "delete":
+ url = "/pm/config/adom/{adom}/" \
+ "devprof/{provisioning_template}/" \
+ "log/syslogd/setting".format(adom=adom,
+ provisioning_template=paramgram["provisioning_template"])
+
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+ return response
+
+
+def set_devprof_syslog_filter(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ paramgram["mode"] = paramgram["mode"]
+ adom = paramgram["adom"]
+ datagram = {
+ "severity": paramgram["syslog_filter"]
+ }
+ response = DEFAULT_RESULT_OBJ
+
+ url = "/pm/config/adom/{adom}" \
+ "/devprof/{provisioning_template}" \
+ "/log/syslogd/filter".format(adom=adom,
+ provisioning_template=paramgram["provisioning_template"])
+
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+ return response
+
+
+def set_devprof_ntp(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ paramgram["mode"] = paramgram["mode"]
+ adom = paramgram["adom"]
+
+ response = DEFAULT_RESULT_OBJ
+
+ # IF SET TO FORTIGUARD, BUILD A STRING SPECIFIC TO THAT
+ if paramgram["ntp_type"] == "fortiguard":
+ datagram = {}
+ if paramgram["ntp_status"] == "enable":
+ datagram["ntpsync"] = 1
+ if paramgram["ntp_status"] == "disable":
+ datagram["ntpsync"] = 0
+ if paramgram["ntp_sync_interval"] is None:
+ datagram["syncinterval"] = 1
+ else:
+ datagram["syncinterval"] = paramgram["ntp_sync_interval"]
+
+ datagram["type"] = 0
+
+ # IF THE NTP TYPE IS CUSTOM BUILD THE SERVER LIST
+ if paramgram["ntp_type"] == "custom":
+ id_counter = 0
+ key_counter = 0
+ ntpservers = []
+ datagram = {}
+ if paramgram["ntp_status"] == "enable":
+ datagram["ntpsync"] = 1
+ if paramgram["ntp_status"] == "disable":
+ datagram["ntpsync"] = 0
+ try:
+ datagram["syncinterval"] = paramgram["ntp_sync_interval"]
+ except BaseException:
+ datagram["syncinterval"] = 1
+ datagram["type"] = 1
+
+ for server in paramgram["ntp_server"].strip().split(","):
+ id_counter += 1
+ server_fields = dict()
+
+ key_counter += 1
+ if paramgram["ntp_auth"] == "enable":
+ server_fields["authentication"] = 1
+ server_fields["key"] = paramgram["ntp_auth_pwd"]
+ server_fields["key-id"] = key_counter
+ else:
+ server_fields["authentication"] = 0
+ server_fields["key"] = ""
+ server_fields["key-id"] = key_counter
+
+ if paramgram["ntp_v3"] == "enable":
+ server_fields["ntp_v3"] = 1
+ else:
+ server_fields["ntp_v3"] = 0
+
+ # split the host on the space to get the mask out
+ new_ntp_server = {"authentication": server_fields["authentication"],
+ "id": id_counter, "key": server_fields["key"],
+ "key-id": id_counter, "ntpv3": server_fields["ntp_v3"],
+ "server": server}
+ ntpservers.append(new_ntp_server)
+ datagram["ntpserver"] = ntpservers
+
+ url = "/pm/config/adom/{adom}" \
+ "/devprof/{provisioning_template}" \
+ "/system/ntp".format(adom=adom,
+ provisioning_template=paramgram["provisioning_template"])
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+ return response
+
+
+def set_devprof_admin(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ paramgram["mode"] = paramgram["mode"]
+ adom = paramgram["adom"]
+
+ response = DEFAULT_RESULT_OBJ
+ datagram = {
+ "admin-https-redirect": paramgram["admin_https_redirect"],
+ "admin-port": paramgram["admin_http_port"],
+ "admin-sport": paramgram["admin_https_port"],
+ "admintimeout": paramgram["admin_timeout"],
+ "language": paramgram["admin_language"],
+ "gui-theme": paramgram["admin_gui_theme"],
+ "switch-controller": paramgram["admin_switch_controller"],
+ }
+ url = "/pm/config/adom/{adom}" \
+ "/devprof/{provisioning_template}" \
+ "/system/global".format(adom=adom,
+ provisioning_template=paramgram["provisioning_template"])
+
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+ return response
+
+
+def set_devprof_smtp(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ paramgram["mode"] = paramgram["mode"]
+ adom = paramgram["adom"]
+
+ response = DEFAULT_RESULT_OBJ
+ datagram = {
+ "port": paramgram["smtp_port"],
+ "reply-to": paramgram["smtp_replyto"],
+ "server": paramgram["smtp_server"],
+ "source-ip": paramgram["smtp_source_ipv4"]
+ }
+
+ if paramgram["smtp_username"]:
+ datagram["authenticate"] = 1
+ datagram["username"] = paramgram["smtp_username"]
+ datagram["password"] = paramgram["smtp_password"]
+
+ if paramgram["smtp_conn_sec"] == "none":
+ datagram["security"] = 0
+ if paramgram["smtp_conn_sec"] == "starttls":
+ datagram["security"] = 1
+ if paramgram["smtp_conn_sec"] == "smtps":
+ datagram["security"] = 2
+
+ if paramgram["smtp_validate_cert"] == "enable":
+ datagram["validate-server"] = 1
+ else:
+ datagram["validate-server"] = 0
+
+ url = "/pm/config/adom/{adom}" \
+ "/devprof/{provisioning_template}" \
+ "/system/email-server".format(adom=adom,
+ provisioning_template=paramgram["provisioning_template"])
+
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+ return response
+
+
+def set_devprof_dns(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ paramgram["mode"] = paramgram["mode"]
+ adom = paramgram["adom"]
+
+ response = DEFAULT_RESULT_OBJ
+ datagram = {
+ "domain": paramgram["dns_suffix"],
+ "primary": paramgram["dns_primary_ipv4"],
+ "secondary": paramgram["dns_secondary_ipv4"],
+ }
+ url = "/pm/config/adom/{adom}" \
+ "/devprof/{provisioning_template}" \
+ "/system/dns".format(adom=adom,
+ provisioning_template=paramgram["provisioning_template"])
+
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+ return response
+
+
+def set_devprof_toggle_fg(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ paramgram["mode"] = paramgram["mode"]
+ adom = paramgram["adom"]
+ response = DEFAULT_RESULT_OBJ
+ datagram = {}
+ if paramgram["admin_enable_fortiguard"] in ["direct", "this-fmg"]:
+ datagram["include-default-servers"] = "enable"
+ elif paramgram["admin_enable_fortiguard"] == "none":
+ datagram["include-default-servers"] = "disable"
+
+ datagram["server-list"] = list()
+
+ url = "/pm/config/adom/{adom}" \
+ "/devprof/{provisioning_template}" \
+ "/system/central-management".format(adom=adom,
+ provisioning_template=paramgram["provisioning_template"])
+ response = fmgr.process_request(url, datagram, FMGRMethods.SET)
+
+ return response
+
+
+def set_devprof_fg(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ paramgram["mode"] = paramgram["mode"]
+ adom = paramgram["adom"]
+
+ response = DEFAULT_RESULT_OBJ
+ datagram = {
+ "target": paramgram["admin_enable_fortiguard"],
+ "target-ip": None
+ }
+
+ if paramgram["mode"] in ['set', 'add', 'update']:
+ if paramgram["admin_fortiguard_target"] is not None and datagram["target"] == "direct":
+ datagram["target-ip"] = paramgram["admin_fortiguard_target"]
+
+ url = "/pm/config/adom/{adom}" \
+ "/devprof/{provisioning_template}" \
+ "/device/profile/fortiguard".format(adom=adom,
+ provisioning_template=paramgram["provisioning_template"])
+
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+ return response
+
+
+def set_devprof_faz(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ paramgram["mode"] = paramgram["mode"]
+ adom = paramgram["adom"]
+ response = DEFAULT_RESULT_OBJ
+ datagram = {
+ "target-ip": paramgram["admin_fortianalyzer_target"],
+ "target": "others",
+ }
+ url = "/pm/config/adom/{adom}" \
+ "/devprof/{provisioning_template}" \
+ "/device/profile/fortianalyzer".format(adom=adom,
+ provisioning_template=paramgram["provisioning_template"])
+ if paramgram["mode"] == "delete":
+ datagram["hastarget"] = "False"
+
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+ return response
+
+
+def main():
+ argument_spec = dict(
+ adom=dict(required=False, type="str"),
+ mode=dict(choices=["add", "set", "delete", "update"], type="str", default="add"),
+
+ provisioning_template=dict(required=False, type="str"),
+ provision_targets=dict(required=False, type="str"),
+
+ device_unique_name=dict(required=False, type="str"),
+ snmp_status=dict(required=False, type="str", choices=["enable", "disable"]),
+ snmp_v2c_query_port=dict(required=False, type="int"),
+ snmp_v2c_trap_port=dict(required=False, type="int"),
+ snmp_v2c_status=dict(required=False, type="str", choices=["enable", "disable"]),
+ snmp_v2c_trap_status=dict(required=False, type="str", choices=["enable", "disable"]),
+ snmp_v2c_query_status=dict(required=False, type="str", choices=["enable", "disable"]),
+ snmp_v2c_name=dict(required=False, type="str", no_log=True),
+ snmp_v2c_id=dict(required=False, type="int"),
+ snmp_v2c_trap_src_ipv4=dict(required=False, type="str"),
+ snmp_v2c_trap_hosts_ipv4=dict(required=False, type="str"),
+ snmp_v2c_query_hosts_ipv4=dict(required=False, type="str"),
+
+ snmpv3_auth_proto=dict(required=False, type="str", choices=["md5", "sha"]),
+ snmpv3_auth_pwd=dict(required=False, type="str", no_log=True),
+ snmpv3_name=dict(required=False, type="str"),
+ snmpv3_notify_hosts=dict(required=False, type="str"),
+ snmpv3_priv_proto=dict(required=False, type="str", choices=["aes", "des", "aes256", "aes256cisco"]),
+ snmpv3_priv_pwd=dict(required=False, type="str", no_log=True),
+ snmpv3_queries=dict(required=False, type="str", choices=["enable", "disable"]),
+ snmpv3_query_port=dict(required=False, type="int"),
+ snmpv3_security_level=dict(required=False, type="str",
+ choices=["no-auth-no-priv", "auth-no-priv", "auth-priv"]),
+ snmpv3_source_ip=dict(required=False, type="str"),
+ snmpv3_status=dict(required=False, type="str", choices=["enable", "disable"]),
+ snmpv3_trap_rport=dict(required=False, type="int"),
+ snmpv3_trap_status=dict(required=False, type="str", choices=["enable", "disable"]),
+
+ syslog_port=dict(required=False, type="int"),
+ syslog_server=dict(required=False, type="str"),
+ syslog_mode=dict(required=False, type="str", choices=["udp", "legacy-reliable", "reliable"], default="udp"),
+ syslog_status=dict(required=False, type="str", choices=["enable", "disable"]),
+ syslog_filter=dict(required=False, type="str", choices=["emergency", "alert", "critical", "error",
+ "warning", "notification", "information", "debug"]),
+ syslog_enc_algorithm=dict(required=False, type="str", choices=["high", "low", "disable", "high-medium"],
+ default="disable"),
+ syslog_facility=dict(required=False, type="str", choices=["kernel", "user", "mail", "daemon", "auth",
+ "syslog", "lpr", "news", "uucp", "cron", "authpriv",
+ "ftp", "ntp", "audit", "alert", "clock", "local0",
+ "local1", "local2", "local3", "local4", "local5",
+ "local6", "local7"], default="syslog"),
+ syslog_certificate=dict(required=False, type="str"),
+
+ ntp_status=dict(required=False, type="str", choices=["enable", "disable"]),
+ ntp_sync_interval=dict(required=False, type="int"),
+ ntp_type=dict(required=False, type="str", choices=["fortiguard", "custom"]),
+ ntp_server=dict(required=False, type="str"),
+ ntp_auth=dict(required=False, type="str", choices=["enable", "disable"]),
+ ntp_auth_pwd=dict(required=False, type="str", no_log=True),
+ ntp_v3=dict(required=False, type="str", choices=["enable", "disable"]),
+
+ admin_https_redirect=dict(required=False, type="str", choices=["enable", "disable"]),
+ admin_https_port=dict(required=False, type="int"),
+ admin_http_port=dict(required=False, type="int"),
+ admin_timeout=dict(required=False, type="int"),
+ admin_language=dict(required=False, type="str",
+ choices=["english", "simch", "japanese", "korean",
+ "spanish", "trach", "french", "portuguese"]),
+ admin_switch_controller=dict(required=False, type="str", choices=["enable", "disable"]),
+ admin_gui_theme=dict(required=False, type="str", choices=["green", "red", "blue", "melongene", "mariner"]),
+ admin_enable_fortiguard=dict(required=False, type="str", choices=["none", "direct", "this-fmg"]),
+ admin_fortianalyzer_target=dict(required=False, type="str"),
+ admin_fortiguard_target=dict(required=False, type="str"),
+
+ smtp_username=dict(required=False, type="str"),
+ smtp_password=dict(required=False, type="str", no_log=True),
+ smtp_port=dict(required=False, type="int"),
+ smtp_replyto=dict(required=False, type="str"),
+ smtp_conn_sec=dict(required=False, type="str", choices=["none", "starttls", "smtps"]),
+ smtp_server=dict(required=False, type="str"),
+ smtp_source_ipv4=dict(required=False, type="str"),
+ smtp_validate_cert=dict(required=False, type="str", choices=["enable", "disable"]),
+
+ dns_suffix=dict(required=False, type="str"),
+ dns_primary_ipv4=dict(required=False, type="str"),
+ dns_secondary_ipv4=dict(required=False, type="str"),
+ delete_provisioning_template=dict(required=False, type="str")
+ )
+
+ module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False, )
+ paramgram = {
+ "adom": module.params["adom"],
+ "mode": module.params["mode"],
+ "provision_targets": module.params["provision_targets"],
+ "provisioning_template": module.params["provisioning_template"],
+
+ "snmp_status": module.params["snmp_status"],
+ "snmp_v2c_query_port": module.params["snmp_v2c_query_port"],
+ "snmp_v2c_trap_port": module.params["snmp_v2c_trap_port"],
+ "snmp_v2c_status": module.params["snmp_v2c_status"],
+ "snmp_v2c_trap_status": module.params["snmp_v2c_trap_status"],
+ "snmp_v2c_query_status": module.params["snmp_v2c_query_status"],
+ "snmp_v2c_name": module.params["snmp_v2c_name"],
+ "snmp_v2c_id": module.params["snmp_v2c_id"],
+ "snmp_v2c_trap_src_ipv4": module.params["snmp_v2c_trap_src_ipv4"],
+ "snmp_v2c_trap_hosts_ipv4": module.params["snmp_v2c_trap_hosts_ipv4"],
+ "snmp_v2c_query_hosts_ipv4": module.params["snmp_v2c_query_hosts_ipv4"],
+
+ "snmpv3_auth_proto": module.params["snmpv3_auth_proto"],
+ "snmpv3_auth_pwd": module.params["snmpv3_auth_pwd"],
+ "snmpv3_name": module.params["snmpv3_name"],
+ "snmpv3_notify_hosts": module.params["snmpv3_notify_hosts"],
+ "snmpv3_priv_proto": module.params["snmpv3_priv_proto"],
+ "snmpv3_priv_pwd": module.params["snmpv3_priv_pwd"],
+ "snmpv3_queries": module.params["snmpv3_queries"],
+ "snmpv3_query_port": module.params["snmpv3_query_port"],
+ "snmpv3_security_level": module.params["snmpv3_security_level"],
+ "snmpv3_source_ip": module.params["snmpv3_source_ip"],
+ "snmpv3_status": module.params["snmpv3_status"],
+ "snmpv3_trap_rport": module.params["snmpv3_trap_rport"],
+ "snmpv3_trap_status": module.params["snmpv3_trap_status"],
+
+ "syslog_port": module.params["syslog_port"],
+ "syslog_server": module.params["syslog_server"],
+ "syslog_mode": module.params["syslog_mode"],
+ "syslog_status": module.params["syslog_status"],
+ "syslog_filter": module.params["syslog_filter"],
+ "syslog_facility": module.params["syslog_facility"],
+ "syslog_enc_algorithm": module.params["syslog_enc_algorithm"],
+ "syslog_certificate": module.params["syslog_certificate"],
+
+ "ntp_status": module.params["ntp_status"],
+ "ntp_sync_interval": module.params["ntp_sync_interval"],
+ "ntp_type": module.params["ntp_type"],
+ "ntp_server": module.params["ntp_server"],
+ "ntp_auth": module.params["ntp_auth"],
+ "ntp_auth_pwd": module.params["ntp_auth_pwd"],
+ "ntp_v3": module.params["ntp_v3"],
+
+ "admin_https_redirect": module.params["admin_https_redirect"],
+ "admin_https_port": module.params["admin_https_port"],
+ "admin_http_port": module.params["admin_http_port"],
+ "admin_timeout": module.params["admin_timeout"],
+ "admin_language": module.params["admin_language"],
+ "admin_switch_controller": module.params["admin_switch_controller"],
+ "admin_gui_theme": module.params["admin_gui_theme"],
+ "admin_enable_fortiguard": module.params["admin_enable_fortiguard"],
+ "admin_fortianalyzer_target": module.params["admin_fortianalyzer_target"],
+ "admin_fortiguard_target": module.params["admin_fortiguard_target"],
+
+ "smtp_username": module.params["smtp_username"],
+ "smtp_password": module.params["smtp_password"],
+ "smtp_port": module.params["smtp_port"],
+ "smtp_replyto": module.params["smtp_replyto"],
+ "smtp_conn_sec": module.params["smtp_conn_sec"],
+ "smtp_server": module.params["smtp_server"],
+ "smtp_source_ipv4": module.params["smtp_source_ipv4"],
+ "smtp_validate_cert": module.params["smtp_validate_cert"],
+
+ "dns_suffix": module.params["dns_suffix"],
+ "dns_primary_ipv4": module.params["dns_primary_ipv4"],
+ "dns_secondary_ipv4": module.params["dns_secondary_ipv4"],
+ "delete_provisioning_template": module.params["delete_provisioning_template"]
+ }
+ module.paramgram = paramgram
+ fmgr = None
+ if module._socket_path:
+ connection = Connection(module._socket_path)
+ fmgr = FortiManagerHandler(connection, module)
+ fmgr.tools = FMGRCommon()
+ else:
+ module.fail_json(**FAIL_SOCKET_MSG)
+
+ results = DEFAULT_RESULT_OBJ
+ try:
+ # CHECK IF WE ARE DELETING AN ENTIRE TEMPLATE. IF THAT'S THE CASE DO IT FIRST AND IGNORE THE REST.
+ if paramgram["delete_provisioning_template"] is not None:
+ results = set_devprof(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results, good_codes=[0, -10, -1],
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram),
+ stop_on_success=True)
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ try:
+ # CHECK TO SEE IF THE DEVPROF TEMPLATE EXISTS
+ devprof = get_devprof(fmgr, paramgram)
+ if devprof[0] != 0:
+ results = set_devprof(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results, good_codes=[0, -2], stop_on_success=False,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ try:
+ # PROCESS THE SNMP SETTINGS IF THE SNMP_STATUS VARIABLE IS SET
+ if paramgram["snmp_status"] is not None:
+ results = set_devprof_snmp(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results, good_codes=[0], stop_on_success=False,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+
+ # PROCESS THE SNMP V2C COMMUNITY SETTINGS IF THEY ARE ALL HERE
+ if all(v is not None for v in (paramgram["snmp_v2c_query_port"], paramgram["snmp_v2c_trap_port"],
+ paramgram["snmp_v2c_status"], paramgram["snmp_v2c_trap_status"],
+ paramgram["snmp_v2c_query_status"], paramgram["snmp_v2c_name"],
+ paramgram["snmp_v2c_id"])):
+ results = set_devprof_snmp_v2c(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results, good_codes=[0, -10033], stop_on_success=True,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+
+ # PROCESS THE SNMPV3 USER IF THERE
+ if all(v is not None for v in (
+ [paramgram["snmpv3_auth_proto"], paramgram["snmpv3_auth_pwd"], paramgram["snmpv3_name"],
+ paramgram["snmpv3_notify_hosts"], paramgram["snmpv3_priv_proto"],
+ paramgram["snmpv3_priv_pwd"],
+ paramgram["snmpv3_queries"],
+ paramgram["snmpv3_query_port"], paramgram["snmpv3_security_level"],
+ paramgram["snmpv3_source_ip"],
+ paramgram["snmpv3_status"], paramgram["snmpv3_trap_rport"], paramgram["snmpv3_trap_status"]])):
+
+ results = set_devprof_snmp_v3(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results, good_codes=[0, -10033, -10000, -3],
+ stop_on_success=True,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ try:
+ # PROCESS THE SYSLOG SETTINGS IF THE ALL THE NEEDED SYSLOG VARIABLES ARE PRESENT
+ if all(v is not None for v in [paramgram["syslog_port"], paramgram["syslog_mode"],
+ paramgram["syslog_server"], paramgram["syslog_status"]]):
+ # enable syslog in the devprof template
+ results = set_devprof_syslog(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results, good_codes=[0, -10033, -10000, -3],
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ try:
+ # IF THE SYSLOG FILTER IS PRESENT THEN RUN THAT
+ if paramgram["syslog_filter"] is not None:
+ results = set_devprof_syslog_filter(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results, good_codes=[0],
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ try:
+ # PROCESS NTP OPTIONS
+ if paramgram["ntp_status"]:
+ # VALIDATE INPUT
+ if paramgram["ntp_type"] == "custom" and paramgram["ntp_server"] is None:
+ module.exit_json(msg="You requested custom NTP type but did not provide ntp_server parameter.")
+ if paramgram["ntp_auth"] == "enable" and paramgram["ntp_auth_pwd"] is None:
+ module.exit_json(
+ msg="You requested NTP Authentication but did not provide ntp_auth_pwd parameter.")
+
+ results = set_devprof_ntp(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results, good_codes=[0],
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+ except Exception as err:
+ raise FMGBaseException(err)
+ try:
+ # PROCESS THE ADMIN OPTIONS
+ if any(v is not None for v in (
+ paramgram["admin_https_redirect"], paramgram["admin_https_port"], paramgram["admin_http_port"],
+ paramgram["admin_timeout"],
+ paramgram["admin_language"], paramgram["admin_switch_controller"],
+ paramgram["admin_gui_theme"])):
+
+ results = set_devprof_admin(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results, good_codes=[0], stop_on_success=False,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ try:
+ # PROCESS FORTIGUARD OPTIONS
+ if paramgram["admin_enable_fortiguard"] is not None:
+
+ results = set_devprof_toggle_fg(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results, good_codes=[0], stop_on_success=False,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+ results = set_devprof_fg(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results, good_codes=[0], stop_on_success=False,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ try:
+ # PROCESS THE SMTP OPTIONS
+ if all(v is not None for v in (
+ paramgram["smtp_username"], paramgram["smtp_password"], paramgram["smtp_port"],
+ paramgram["smtp_replyto"],
+ paramgram["smtp_conn_sec"], paramgram["smtp_server"],
+ paramgram["smtp_source_ipv4"], paramgram["smtp_validate_cert"])):
+
+ results = set_devprof_smtp(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results, good_codes=[0], stop_on_success=False,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ try:
+ # PROCESS THE DNS OPTIONS
+ if any(v is not None for v in
+ (paramgram["dns_suffix"], paramgram["dns_primary_ipv4"], paramgram["dns_secondary_ipv4"])):
+ results = set_devprof_dns(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results, good_codes=[0], stop_on_success=False,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ try:
+ # PROCESS THE admin_fortianalyzer_target OPTIONS
+ if paramgram["admin_fortianalyzer_target"] is not None:
+
+ results = set_devprof_faz(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results, good_codes=[0], stop_on_success=False,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ try:
+ # PROCESS THE PROVISIONING TEMPLATE TARGET PARAMETER
+ if paramgram["provision_targets"] is not None:
+ if paramgram["mode"] != "delete":
+ results = set_devprof_scope(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results, good_codes=[0], stop_on_success=False,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+
+ if paramgram["mode"] == "delete":
+ # WE NEED TO FIGURE OUT WHAT'S THERE FIRST, BEFORE WE CAN RUN THIS
+ targets_to_add = list()
+ try:
+ current_scope = get_devprof_scope(fmgr, paramgram)
+ targets_to_remove = paramgram["provision_targets"].strip().split(",")
+ targets = current_scope[1][1]["scope member"]
+ for target in targets:
+ if target["name"] not in targets_to_remove:
+ target_append = {"name": target["name"]}
+ targets_to_add.append(target_append)
+ except BaseException:
+ pass
+ paramgram["targets_to_add"] = targets_to_add
+ results = set_devprof_scope(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results, good_codes=[0, -10033, -10000, -3],
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ return module.exit_json(**results[1])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_fwobj_address.py b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_fwobj_address.py
new file mode 100644
index 00000000..c060c00d
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_fwobj_address.py
@@ -0,0 +1,661 @@
+#!/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: fmgr_fwobj_address
+notes:
+ - Full Documentation at U(https://ftnt-ansible-docs.readthedocs.io/en/latest/).
+author:
+ - Luke Weighall (@lweighall)
+ - Andrew Welsh (@Ghilli3)
+ - Jim Huber (@p4r4n0y1ng)
+short_description: Allows the management of firewall objects in FortiManager
+description:
+ - Allows for the management of IPv4, IPv6, and multicast address objects within FortiManager.
+
+options:
+ adom:
+ description:
+ - The ADOM the configuration should belong to.
+ required: false
+ default: root
+
+ allow_routing:
+ description:
+ - Enable/disable use of this address in the static route configuration.
+ choices: ['enable', 'disable']
+ default: 'disable'
+
+ associated_interface:
+ description:
+ - Associated interface name.
+
+ cache_ttl:
+ description:
+ - Minimal TTL of individual IP addresses in FQDN cache. Only applies when type = wildcard-fqdn.
+
+ color:
+ description:
+ - Color of the object in FortiManager GUI.
+ - Takes integers 1-32
+ default: 22
+
+ comment:
+ description:
+ - Comment for the object in FortiManager.
+
+ country:
+ description:
+ - Country name. Required if type = geographic.
+
+ end_ip:
+ description:
+ - End IP. Only used when ipv4 = iprange.
+
+ group_members:
+ description:
+ - Address group member. If this is defined w/out group_name, the operation will fail.
+
+ group_name:
+ description:
+ - Address group name. If this is defined in playbook task, all other options are ignored.
+
+ ipv4:
+ description:
+ - Type of IPv4 Object.
+ - Must not be specified with either multicast or IPv6 parameters.
+ choices: ['ipmask', 'iprange', 'fqdn', 'wildcard', 'geography', 'wildcard-fqdn', 'group']
+
+ ipv4addr:
+ description:
+ - IP and network mask. If only defining one IP use this parameter. (i.e. 10.7.220.30/255.255.255.255)
+ - Can also define subnets (i.e. 10.7.220.0/255.255.255.0)
+ - Also accepts CIDR (i.e. 10.7.220.0/24)
+ - If Netmask is omitted after IP address, /32 is assumed.
+ - When multicast is set to Broadcast Subnet the ipv4addr parameter is used to specify the subnet.
+
+ ipv6:
+ description:
+ - Puts module into IPv6 mode.
+ - Must not be specified with either ipv4 or multicast parameters.
+ choices: ['ip', 'iprange', 'group']
+
+ ipv6addr:
+ description:
+ - IPv6 address in full. (i.e. 2001:0db8:85a3:0000:0000:8a2e:0370:7334)
+
+ fqdn:
+ description:
+ - Fully qualified domain name.
+
+ mode:
+ description:
+ - Sets one of three modes for managing the object.
+ choices: ['add', 'set', 'delete']
+ default: add
+
+ multicast:
+ description:
+ - Manages Multicast Address Objects.
+ - Sets either a Multicast IP Range or a Broadcast Subnet.
+ - Must not be specified with either ipv4 or ipv6 parameters.
+ - When set to Broadcast Subnet the ipv4addr parameter is used to specify the subnet.
+ - Can create IPv4 Multicast Objects (multicastrange and broadcastmask options -- uses start/end-ip and ipv4addr).
+ choices: ['multicastrange', 'broadcastmask', 'ip6']
+
+ name:
+ description:
+ - Friendly Name Address object name in FortiManager.
+
+ obj_id:
+ description:
+ - Object ID for NSX.
+
+ start_ip:
+ description:
+ - Start IP. Only used when ipv4 = iprange.
+
+ visibility:
+ description:
+ - Enable/disable address visibility.
+ choices: ['enable', 'disable']
+ default: 'enable'
+
+ wildcard:
+ description:
+ - IP address and wildcard netmask. Required if ipv4 = wildcard.
+
+ wildcard_fqdn:
+ description:
+ - Wildcard FQDN. Required if ipv4 = wildcard-fqdn.
+'''
+
+EXAMPLES = '''
+- name: ADD IPv4 IP ADDRESS OBJECT
+ community.fortios.fmgr_fwobj_address:
+ ipv4: "ipmask"
+ ipv4addr: "10.7.220.30/32"
+ name: "ansible_v4Obj"
+ comment: "Created by Ansible"
+ color: "6"
+
+- name: ADD IPv4 IP ADDRESS OBJECT MORE OPTIONS
+ community.fortios.fmgr_fwobj_address:
+ ipv4: "ipmask"
+ ipv4addr: "10.7.220.34/32"
+ name: "ansible_v4Obj_MORE"
+ comment: "Created by Ansible"
+ color: "6"
+ allow_routing: "enable"
+ cache_ttl: "180"
+ associated_interface: "port1"
+ obj_id: "123"
+
+- name: ADD IPv4 IP ADDRESS SUBNET OBJECT
+ community.fortios.fmgr_fwobj_address:
+ ipv4: "ipmask"
+ ipv4addr: "10.7.220.0/255.255.255.128"
+ name: "ansible_subnet"
+ comment: "Created by Ansible"
+ mode: "set"
+
+- name: ADD IPv4 IP ADDRESS RANGE OBJECT
+ community.fortios.fmgr_fwobj_address:
+ ipv4: "iprange"
+ start_ip: "10.7.220.1"
+ end_ip: "10.7.220.125"
+ name: "ansible_range"
+ comment: "Created by Ansible"
+
+- name: ADD IPv4 IP ADDRESS WILDCARD OBJECT
+ community.fortios.fmgr_fwobj_address:
+ ipv4: "wildcard"
+ wildcard: "10.7.220.30/255.255.255.255"
+ name: "ansible_wildcard"
+ comment: "Created by Ansible"
+
+- name: ADD IPv4 IP ADDRESS WILDCARD FQDN OBJECT
+ community.fortios.fmgr_fwobj_address:
+ ipv4: "wildcard-fqdn"
+ wildcard_fqdn: "*.myds.com"
+ name: "Synology myds DDNS service"
+ comment: "Created by Ansible"
+
+- name: ADD IPv4 IP ADDRESS FQDN OBJECT
+ community.fortios.fmgr_fwobj_address:
+ ipv4: "fqdn"
+ fqdn: "ansible.com"
+ name: "ansible_fqdn"
+ comment: "Created by Ansible"
+
+- name: ADD IPv4 IP ADDRESS GEO OBJECT
+ community.fortios.fmgr_fwobj_address:
+ ipv4: "geography"
+ country: "usa"
+ name: "ansible_geo"
+ comment: "Created by Ansible"
+
+- name: ADD IPv6 ADDRESS
+ community.fortios.fmgr_fwobj_address:
+ ipv6: "ip"
+ ipv6addr: "2001:0db8:85a3:0000:0000:8a2e:0370:7334"
+ name: "ansible_v6Obj"
+ comment: "Created by Ansible"
+
+- name: ADD IPv6 ADDRESS RANGE
+ community.fortios.fmgr_fwobj_address:
+ ipv6: "iprange"
+ start_ip: "2001:0db8:85a3:0000:0000:8a2e:0370:7334"
+ end_ip: "2001:0db8:85a3:0000:0000:8a2e:0370:7446"
+ name: "ansible_v6range"
+ comment: "Created by Ansible"
+
+- name: ADD IPv4 IP ADDRESS GROUP
+ community.fortios.fmgr_fwobj_address:
+ ipv4: "group"
+ group_name: "ansibleIPv4Group"
+ group_members: "ansible_fqdn, ansible_wildcard, ansible_range"
+
+- name: ADD IPv6 IP ADDRESS GROUP
+ community.fortios.fmgr_fwobj_address:
+ ipv6: "group"
+ group_name: "ansibleIPv6Group"
+ group_members: "ansible_v6Obj, ansible_v6range"
+
+- name: ADD MULTICAST RANGE
+ community.fortios.fmgr_fwobj_address:
+ multicast: "multicastrange"
+ start_ip: "224.0.0.251"
+ end_ip: "224.0.0.251"
+ name: "ansible_multicastrange"
+ comment: "Created by Ansible"
+
+- name: ADD BROADCAST SUBNET
+ community.fortios.fmgr_fwobj_address:
+ multicast: "broadcastmask"
+ ipv4addr: "10.7.220.0/24"
+ name: "ansible_broadcastSubnet"
+ comment: "Created by Ansible"
+'''
+
+RETURN = """
+api_result:
+ description: full API response, includes status code and message
+ returned: always
+ type: str
+"""
+
+
+import re
+from ansible.module_utils.basic import AnsibleModule, env_fallback
+from ansible.module_utils.connection import Connection
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.fortimanager import FortiManagerHandler
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGBaseException
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRCommon
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import DEFAULT_RESULT_OBJ
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FAIL_SOCKET_MSG
+
+
+def fmgr_fwobj_ipv4(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ # EVAL THE MODE PARAMETER FOR SET OR ADD
+ if paramgram["mode"] in ['set', 'add']:
+ # CREATE THE DATAGRAM DICTIONARY
+ # ENSURE THE DATAGRAM KEYS MATCH THE JSON API GUIDE ATTRIBUTES, NOT WHAT IS IN ANSIBLE
+ # SOME PARAMETERS SHOWN IN THIS DICTIONARY WE DON'T EVEN ASK THE USER FOR IN PLAYBOOKS BUT ARE REQUIRED
+ datagram = {
+ "comment": paramgram["comment"],
+ "associated-interface": paramgram["associated-interface"],
+ "cache-ttl": paramgram["cache-ttl"],
+ "name": paramgram["name"],
+ "allow-routing": paramgram["allow-routing"],
+ "color": paramgram["color"],
+ "meta fields": {},
+ "dynamic_mapping": [],
+ "visibility": paramgram["allow-routing"],
+ "type": paramgram["ipv4"],
+ }
+
+ # SET THE CORRECT URL BASED ON THE TYPE (WE'RE DOING GROUPS IN THIS METHOD, TOO)
+ if datagram["type"] == "group":
+ url = '/pm/config/adom/{adom}/obj/firewall/addrgrp'.format(adom=paramgram["adom"])
+ else:
+ url = '/pm/config/adom/{adom}/obj/firewall/address'.format(adom=paramgram["adom"])
+
+ #########################
+ # IF type = 'ipmask'
+ #########################
+ if datagram["type"] == "ipmask":
+ # CREATE THE SUBNET LIST OBJECT
+ subnet = []
+ # EVAL THE IPV4ADDR INPUT AND SPLIT THE IP ADDRESS FROM THE MASK AND APPEND THEM TO THE SUBNET LIST
+ for subnets in paramgram["ipv4addr"].split("/"):
+ subnet.append(subnets)
+
+ # CHECK THAT THE SECOND ENTRY IN THE SUBNET LIST (WHAT WAS TO THE RIGHT OF THE / CHARACTER)
+ # IS IN SUBNET MASK FORMAT AND NOT CIDR FORMAT.
+ # IF IT IS IN CIDR FORMAT, WE NEED TO CONVERT IT TO SUBNET BIT MASK FORMAT FOR THE JSON API
+ if not re.match(r'\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}', subnet[1]):
+ # IF THE SUBNET PARAMETER INPUT DIDN'T LOOK LIKE xxx.xxx.xxx.xxx TO REGEX...
+ # ... RUN IT THROUGH THE CIDR_TO_NETMASK() FUNCTION
+ mask = fmgr._tools.cidr_to_netmask(subnet[1])
+ # AND THEN UPDATE THE SUBNET LIST OBJECT
+ subnet[1] = mask
+
+ # INCLUDE THE SUBNET LIST OBJECT IN THE DATAGRAM DICTIONARY TO BE SUBMITTED
+ datagram["subnet"] = subnet
+
+ #########################
+ # IF type = 'iprange'
+ #########################
+ if datagram["type"] == "iprange":
+ datagram["start-ip"] = paramgram["start-ip"]
+ datagram["end-ip"] = paramgram["end-ip"]
+ datagram["subnet"] = ["0.0.0.0", "0.0.0.0"]
+
+ #########################
+ # IF type = 'geography'
+ #########################
+ if datagram["type"] == "geography":
+ datagram["country"] = paramgram["country"]
+
+ #########################
+ # IF type = 'wildcard'
+ #########################
+ if datagram["type"] == "wildcard":
+
+ subnet = []
+ for subnets in paramgram["wildcard"].split("/"):
+ subnet.append(subnets)
+
+ if not re.match(r'\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}', subnet[1]):
+ mask = fmgr._tools.cidr_to_netmask(subnet[1])
+ subnet[1] = mask
+
+ datagram["wildcard"] = subnet
+
+ #########################
+ # IF type = 'wildcard-fqdn'
+ #########################
+ if datagram["type"] == "wildcard-fqdn":
+ datagram["wildcard-fqdn"] = paramgram["wildcard-fqdn"]
+
+ #########################
+ # IF type = 'fqdn'
+ #########################
+ if datagram["type"] == "fqdn":
+ datagram["fqdn"] = paramgram["fqdn"]
+
+ #########################
+ # IF type = 'group'
+ #########################
+ if datagram["type"] == "group":
+ datagram = {
+ "comment": paramgram["comment"],
+ "name": paramgram["group_name"],
+ "color": paramgram["color"],
+ "meta fields": {},
+ "dynamic_mapping": [],
+ "visibility": paramgram["visibility"]
+ }
+
+ members = []
+ group_members = paramgram["group_members"].replace(" ", "")
+ try:
+ for member in group_members.split(","):
+ members.append(member)
+ except Exception:
+ pass
+
+ datagram["member"] = members
+
+ # EVAL THE MODE PARAMETER FOR DELETE
+ if paramgram["mode"] == "delete":
+ # IF A GROUP, SET THE CORRECT NAME AND URL FOR THE GROUP ENDPOINT
+ if paramgram["ipv4"] == "group":
+ datagram = {}
+ url = '/pm/config/adom/{adom}/obj/firewall/addrgrp/{name}'.format(adom=paramgram["adom"],
+ name=paramgram["group_name"])
+ # OTHERWISE WE'RE JUST GOING TO USE THE ADDRESS ENDPOINT
+ else:
+ datagram = {}
+ url = '/pm/config/adom/{adom}/obj/firewall/address/{name}'.format(adom=paramgram["adom"],
+ name=paramgram["name"])
+
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+ return response
+
+
+def fmgr_fwobj_ipv6(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ # EVAL THE MODE PARAMETER FOR SET OR ADD
+ if paramgram["mode"] in ['set', 'add']:
+ # CREATE THE DATAGRAM DICTIONARY
+ # ENSURE THE DATAGRAM KEYS MATCH THE JSON API GUIDE ATTRIBUTES, NOT WHAT IS IN ANSIBLE
+ # SOME PARAMETERS SHOWN IN THIS DICTIONARY WE DON'T EVEN ASK THE USER FOR IN PLAYBOOKS BUT ARE REQUIRED
+ datagram = {
+ "comment": paramgram["comment"],
+ "name": paramgram["name"],
+ "color": paramgram["color"],
+ "dynamic_mapping": [],
+ "visibility": paramgram["visibility"],
+ "type": paramgram["ipv6"]
+ }
+
+ # SET THE CORRECT URL BASED ON THE TYPE (WE'RE DOING GROUPS IN THIS METHOD, TOO)
+ if datagram["type"] == "group":
+ url = '/pm/config/adom/{adom}/obj/firewall/addrgrp6'.format(adom=paramgram["adom"])
+ else:
+ url = '/pm/config/adom/{adom}/obj/firewall/address6'.format(adom=paramgram["adom"])
+
+ #########################
+ # IF type = 'ip'
+ #########################
+ if datagram["type"] == "ip":
+ datagram["type"] = "ipprefix"
+ datagram["ip6"] = paramgram["ipv6addr"]
+
+ #########################
+ # IF type = 'iprange'
+ #########################
+ if datagram["type"] == "iprange":
+ datagram["start-ip"] = paramgram["start-ip"]
+ datagram["end-ip"] = paramgram["end-ip"]
+
+ #########################
+ # IF type = 'group'
+ #########################
+ if datagram["type"] == "group":
+ datagram = None
+ datagram = {
+ "comment": paramgram["comment"],
+ "name": paramgram["group_name"],
+ "color": paramgram["color"],
+ "visibility": paramgram["visibility"]
+ }
+
+ members = []
+ group_members = paramgram["group_members"].replace(" ", "")
+ try:
+ for member in group_members.split(","):
+ members.append(member)
+ except Exception:
+ pass
+
+ datagram["member"] = members
+
+ # EVAL THE MODE PARAMETER FOR DELETE
+ if paramgram["mode"] == "delete":
+ # IF A GROUP, SET THE CORRECT NAME AND URL FOR THE GROUP ENDPOINT
+ if paramgram["ipv6"] == "group":
+ datagram = {}
+ url = '/pm/config/adom/{adom}/obj/firewall/addrgrp6/{name}'.format(adom=paramgram["adom"],
+ name=paramgram["group_name"])
+ # OTHERWISE WE'RE JUST GOING TO USE THE ADDRESS ENDPOINT
+ else:
+ datagram = {}
+ url = '/pm/config/adom/{adom}/obj/firewall/address6/{name}'.format(adom=paramgram["adom"],
+ name=paramgram["name"])
+
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+ return response
+
+
+def fmgr_fwobj_multicast(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ # EVAL THE MODE PARAMETER FOR SET OR ADD
+ if paramgram["mode"] in ['set', 'add']:
+ # CREATE THE DATAGRAM DICTIONARY
+ # ENSURE THE DATAGRAM KEYS MATCH THE JSON API GUIDE ATTRIBUTES, NOT WHAT IS IN ANSIBLE
+ # SOME PARAMETERS SHOWN IN THIS DICTIONARY WE DON'T EVEN ASK THE USER FOR IN PLAYBOOKS BUT ARE REQUIRED
+ datagram = {
+ "associated-interface": paramgram["associated-interface"],
+ "comment": paramgram["comment"],
+ "name": paramgram["name"],
+ "color": paramgram["color"],
+ "type": paramgram["multicast"],
+ "visibility": paramgram["visibility"],
+ }
+
+ # SET THE CORRECT URL
+ url = '/pm/config/adom/{adom}/obj/firewall/multicast-address'.format(adom=paramgram["adom"])
+
+ #########################
+ # IF type = 'multicastrange'
+ #########################
+ if paramgram["multicast"] == "multicastrange":
+ datagram["start-ip"] = paramgram["start-ip"]
+ datagram["end-ip"] = paramgram["end-ip"]
+ datagram["subnet"] = ["0.0.0.0", "0.0.0.0"]
+
+ #########################
+ # IF type = 'broadcastmask'
+ #########################
+ if paramgram["multicast"] == "broadcastmask":
+ # EVAL THE IPV4ADDR INPUT AND SPLIT THE IP ADDRESS FROM THE MASK AND APPEND THEM TO THE SUBNET LIST
+ subnet = []
+ for subnets in paramgram["ipv4addr"].split("/"):
+ subnet.append(subnets)
+ # CHECK THAT THE SECOND ENTRY IN THE SUBNET LIST (WHAT WAS TO THE RIGHT OF THE / CHARACTER)
+ # IS IN SUBNET MASK FORMAT AND NOT CIDR FORMAT.
+ # IF IT IS IN CIDR FORMAT, WE NEED TO CONVERT IT TO SUBNET BIT MASK FORMAT FOR THE JSON API
+ if not re.match(r'\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}', subnet[1]):
+ # IF THE SUBNET PARAMETER INPUT DIDN'T LOOK LIKE 255.255.255.255 TO REGEX...
+ # ... RUN IT THROUGH THE fmgr_cidr_to_netmask() FUNCTION
+ mask = fmgr._tools.cidr_to_netmask(subnet[1])
+ # AND THEN UPDATE THE SUBNET LIST OBJECT
+ subnet[1] = mask
+
+ # INCLUDE THE SUBNET LIST OBJECT IN THE DATAGRAM DICTIONARY TO BE SUBMITTED
+ datagram["subnet"] = subnet
+
+ # EVAL THE MODE PARAMETER FOR DELETE
+ if paramgram["mode"] == "delete":
+ datagram = {
+ "name": paramgram["name"]
+ }
+ # SET THE CORRECT URL FOR DELETE
+ url = '/pm/config/adom/{adom}/obj/firewall/multicast-address/{name}'.format(adom=paramgram["adom"],
+ name=paramgram["name"])
+
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+ return response
+
+
+def main():
+ argument_spec = dict(
+ adom=dict(required=False, type="str", default="root"),
+ mode=dict(choices=["add", "set", "delete"], type="str", default="add"),
+
+ allow_routing=dict(required=False, type="str", choices=['enable', 'disable'], default="disable"),
+ associated_interface=dict(required=False, type="str"),
+ cache_ttl=dict(required=False, type="str"),
+ color=dict(required=False, type="str", default=22),
+ comment=dict(required=False, type="str"),
+ country=dict(required=False, type="str"),
+ fqdn=dict(required=False, type="str"),
+ name=dict(required=False, type="str"),
+ start_ip=dict(required=False, type="str"),
+ end_ip=dict(required=False, type="str"),
+ ipv4=dict(required=False, type="str", choices=['ipmask', 'iprange', 'fqdn', 'wildcard',
+ 'geography', 'wildcard-fqdn', 'group']),
+ visibility=dict(required=False, type="str", choices=['enable', 'disable'], default="enable"),
+ wildcard=dict(required=False, type="str"),
+ wildcard_fqdn=dict(required=False, type="str"),
+ ipv6=dict(required=False, type="str", choices=['ip', 'iprange', 'group']),
+ group_members=dict(required=False, type="str"),
+ group_name=dict(required=False, type="str"),
+ ipv4addr=dict(required=False, type="str"),
+ ipv6addr=dict(required=False, type="str"),
+ multicast=dict(required=False, type="str", choices=['multicastrange', 'broadcastmask', 'ip6']),
+ obj_id=dict(required=False, type="str"),
+
+ )
+
+ module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False,
+ mutually_exclusive=[
+ ['ipv4', 'ipv6'],
+ ['ipv4', 'multicast'],
+ ['ipv6', 'multicast']
+ ])
+ paramgram = {
+ "adom": module.params["adom"],
+ "allow-routing": module.params["allow_routing"],
+ "associated-interface": module.params["associated_interface"],
+ "cache-ttl": module.params["cache_ttl"],
+ "color": module.params["color"],
+ "comment": module.params["comment"],
+ "country": module.params["country"],
+ "end-ip": module.params["end_ip"],
+ "fqdn": module.params["fqdn"],
+ "name": module.params["name"],
+ "start-ip": module.params["start_ip"],
+ "visibility": module.params["visibility"],
+ "wildcard": module.params["wildcard"],
+ "wildcard-fqdn": module.params["wildcard_fqdn"],
+ "ipv6": module.params["ipv6"],
+ "ipv4": module.params["ipv4"],
+ "group_members": module.params["group_members"],
+ "group_name": module.params["group_name"],
+ "ipv4addr": module.params["ipv4addr"],
+ "ipv6addr": module.params["ipv6addr"],
+ "multicast": module.params["multicast"],
+ "mode": module.params["mode"],
+ "obj-id": module.params["obj_id"],
+ }
+
+ module.paramgram = paramgram
+ fmgr = None
+ if module._socket_path:
+ connection = Connection(module._socket_path)
+ fmgr = FortiManagerHandler(connection, module)
+ fmgr._tools = FMGRCommon()
+ else:
+ module.fail_json(**FAIL_SOCKET_MSG)
+
+ results = DEFAULT_RESULT_OBJ
+ try:
+ if paramgram["ipv4"]:
+ results = fmgr_fwobj_ipv4(fmgr, paramgram)
+
+ elif paramgram["ipv6"]:
+ results = fmgr_fwobj_ipv6(fmgr, paramgram)
+
+ elif paramgram["multicast"]:
+ results = fmgr_fwobj_multicast(fmgr, paramgram)
+
+ fmgr.govern_response(module=module, results=results,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ if results is not None:
+ return module.exit_json(**results[1])
+ else:
+ return module.exit_json(msg="Couldn't find a proper ipv4 or ipv6 or multicast parameter "
+ "to run in the logic tree. Exiting...")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_fwobj_ippool.py b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_fwobj_ippool.py
new file mode 100644
index 00000000..a0b39ab1
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_fwobj_ippool.py
@@ -0,0 +1,442 @@
+#!/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: fmgr_fwobj_ippool
+notes:
+ - Full Documentation at U(https://ftnt-ansible-docs.readthedocs.io/en/latest/).
+author:
+ - Luke Weighall (@lweighall)
+ - Andrew Welsh (@Ghilli3)
+ - Jim Huber (@p4r4n0y1ng)
+short_description: Allows the editing of IP Pool Objects within FortiManager.
+description:
+ - Allows users to add/edit/delete IP Pool Objects.
+
+options:
+ adom:
+ description:
+ - The ADOM the configuration should belong to.
+ required: false
+ default: root
+
+ mode:
+ description:
+ - Sets one of three modes for managing the object.
+ - Allows use of soft-adds instead of overwriting existing values
+ choices: ['add', 'set', 'delete', 'update']
+ required: false
+ default: add
+
+ type:
+ description:
+ - IP pool type (overload, one-to-one, fixed port range, or port block allocation).
+ - choice | overload | IP addresses in the IP pool can be shared by clients.
+ - choice | one-to-one | One to one mapping.
+ - choice | fixed-port-range | Fixed port range.
+ - choice | port-block-allocation | Port block allocation.
+ required: false
+ choices: ["overload", "one-to-one", "fixed-port-range", "port-block-allocation"]
+
+ startip:
+ description:
+ - First IPv4 address (inclusive) in the range for the address pool (format xxx.xxx.xxx.xxx, Default| 0.0.0.0).
+ required: false
+
+ source_startip:
+ description:
+ - First IPv4 address (inclusive) in the range of the source addresses to be translated (format xxx.xxx.xxx.xxx,
+ Default| 0.0.0.0).
+ required: false
+
+ source_endip:
+ description:
+ - Final IPv4 address (inclusive) in the range of the source addresses to be translated (format xxx.xxx.xxx.xxx,
+ Default| 0.0.0.0).
+ required: false
+
+ permit_any_host:
+ description:
+ - Enable/disable full cone NAT.
+ - choice | disable | Disable full cone NAT.
+ - choice | enable | Enable full cone NAT.
+ required: false
+ choices: ["disable", "enable"]
+
+ pba_timeout:
+ description:
+ - Port block allocation timeout (seconds).
+ required: false
+
+ num_blocks_per_user:
+ description:
+ - Number of addresses blocks that can be used by a user (1 to 128, default = 8).
+ required: false
+
+ name:
+ description:
+ - IP pool name.
+ required: false
+
+ endip:
+ description:
+ - Final IPv4 address (inclusive) in the range for the address pool (format xxx.xxx.xxx.xxx, Default| 0.0.0.0).
+ required: false
+
+ comments:
+ description:
+ - Comment.
+ required: false
+
+ block_size:
+ description:
+ - Number of addresses in a block (64 to 4096, default = 128).
+ required: false
+
+ associated_interface:
+ description:
+ - Associated interface name.
+ required: false
+
+ arp_reply:
+ description:
+ - Enable/disable replying to ARP requests when an IP Pool is added to a policy (default = enable).
+ - choice | disable | Disable ARP reply.
+ - choice | enable | Enable ARP reply.
+ required: false
+ choices: ["disable", "enable"]
+
+ arp_intf:
+ description:
+ - Select an interface from available options that will reply to ARP requests. (If blank, any is selected).
+ required: false
+
+ dynamic_mapping:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameter.ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ dynamic_mapping_arp_intf:
+ description:
+ - Dynamic Mapping clone of original suffixed parameter.
+ required: false
+
+ dynamic_mapping_arp_reply:
+ description:
+ - Dynamic Mapping clone of original suffixed parameter.
+ required: false
+ choices: ["disable", "enable"]
+
+ dynamic_mapping_associated_interface:
+ description:
+ - Dynamic Mapping clone of original suffixed parameter.
+ required: false
+
+ dynamic_mapping_block_size:
+ description:
+ - Dynamic Mapping clone of original suffixed parameter.
+ required: false
+
+ dynamic_mapping_comments:
+ description:
+ - Dynamic Mapping clone of original suffixed parameter.
+ required: false
+
+ dynamic_mapping_endip:
+ description:
+ - Dynamic Mapping clone of original suffixed parameter.
+ required: false
+
+ dynamic_mapping_num_blocks_per_user:
+ description:
+ - Dynamic Mapping clone of original suffixed parameter.
+ required: false
+
+ dynamic_mapping_pba_timeout:
+ description:
+ - Dynamic Mapping clone of original suffixed parameter.
+ required: false
+
+ dynamic_mapping_permit_any_host:
+ description:
+ - Dynamic Mapping clone of original suffixed parameter.
+ required: false
+ choices: ["disable", "enable"]
+
+ dynamic_mapping_source_endip:
+ description:
+ - Dynamic Mapping clone of original suffixed parameter.
+ required: false
+
+ dynamic_mapping_source_startip:
+ description:
+ - Dynamic Mapping clone of original suffixed parameter.
+ required: false
+
+ dynamic_mapping_startip:
+ description:
+ - Dynamic Mapping clone of original suffixed parameter.
+ required: false
+
+ dynamic_mapping_type:
+ description:
+ - Dynamic Mapping clone of original suffixed parameter.
+ required: false
+ choices: ["overload", "one-to-one", "fixed-port-range", "port-block-allocation"]
+
+
+'''
+
+EXAMPLES = '''
+- name: ADD FMGR_FIREWALL_IPPOOL Overload
+ community.fortios.fmgr_fwobj_ippool:
+ mode: "add"
+ adom: "ansible"
+ name: "Ansible_pool4_overload"
+ comments: "Created by ansible"
+ type: "overload"
+
+ # OPTIONS FOR ALL MODES
+ startip: "10.10.10.10"
+ endip: "10.10.10.100"
+ arp_reply: "enable"
+
+- name: ADD FMGR_FIREWALL_IPPOOL one-to-one
+ community.fortios.fmgr_fwobj_ippool:
+ mode: "add"
+ adom: "ansible"
+ name: "Ansible_pool4_121"
+ comments: "Created by ansible"
+ type: "one-to-one"
+
+ # OPTIONS FOR ALL MODES
+ startip: "10.10.20.10"
+ endip: "10.10.20.100"
+ arp_reply: "enable"
+
+- name: ADD FMGR_FIREWALL_IPPOOL FIXED PORT RANGE
+ community.fortios.fmgr_fwobj_ippool:
+ mode: "add"
+ adom: "ansible"
+ name: "Ansible_pool4_fixed_port"
+ comments: "Created by ansible"
+ type: "fixed-port-range"
+
+ # OPTIONS FOR ALL MODES
+ startip: "10.10.40.10"
+ endip: "10.10.40.100"
+ arp_reply: "enable"
+ # FIXED PORT RANGE OPTIONS
+ source_startip: "192.168.20.1"
+ source_endip: "192.168.20.20"
+
+- name: ADD FMGR_FIREWALL_IPPOOL PORT BLOCK ALLOCATION
+ community.fortios.fmgr_fwobj_ippool:
+ mode: "add"
+ adom: "ansible"
+ name: "Ansible_pool4_port_block_allocation"
+ comments: "Created by ansible"
+ type: "port-block-allocation"
+
+ # OPTIONS FOR ALL MODES
+ startip: "10.10.30.10"
+ endip: "10.10.30.100"
+ arp_reply: "enable"
+ # PORT BLOCK ALLOCATION OPTIONS
+ block_size: "128"
+ num_blocks_per_user: "1"
+'''
+
+RETURN = """
+api_result:
+ description: full API response, includes status code and message
+ returned: always
+ type: str
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.connection import Connection
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.fortimanager import FortiManagerHandler
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGBaseException
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRCommon
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import DEFAULT_RESULT_OBJ
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FAIL_SOCKET_MSG
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import prepare_dict
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import scrub_dict
+
+
+###############
+# START METHODS
+###############
+
+
+def fmgr_fwobj_ippool_modify(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+
+ mode = paramgram["mode"]
+ adom = paramgram["adom"]
+ # INIT A BASIC OBJECTS
+ response = DEFAULT_RESULT_OBJ
+ url = ""
+ datagram = {}
+
+ # EVAL THE MODE PARAMETER FOR SET OR ADD
+ if mode in ['set', 'add', 'update']:
+ url = '/pm/config/adom/{adom}/obj/firewall/ippool'.format(adom=adom)
+ datagram = scrub_dict(prepare_dict(paramgram))
+
+ # EVAL THE MODE PARAMETER FOR DELETE
+ elif mode == "delete":
+ # SET THE CORRECT URL FOR DELETE
+ url = '/pm/config/adom/{adom}/obj/firewall/ippool/{name}'.format(adom=adom, name=paramgram["name"])
+ datagram = {}
+
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+
+ return response
+
+
+#############
+# END METHODS
+#############
+
+
+def main():
+ argument_spec = dict(
+ adom=dict(type="str", default="root"),
+ mode=dict(choices=["add", "set", "delete", "update"], type="str", default="add"),
+
+ type=dict(required=False, type="str", choices=["overload",
+ "one-to-one",
+ "fixed-port-range",
+ "port-block-allocation"]),
+ startip=dict(required=False, type="str"),
+ source_startip=dict(required=False, type="str"),
+ source_endip=dict(required=False, type="str"),
+ permit_any_host=dict(required=False, type="str", choices=["disable", "enable"]),
+ pba_timeout=dict(required=False, type="int"),
+ num_blocks_per_user=dict(required=False, type="int"),
+ name=dict(required=False, type="str"),
+ endip=dict(required=False, type="str"),
+ comments=dict(required=False, type="str"),
+ block_size=dict(required=False, type="int"),
+ associated_interface=dict(required=False, type="str"),
+ arp_reply=dict(required=False, type="str", choices=["disable", "enable"]),
+ arp_intf=dict(required=False, type="str"),
+ dynamic_mapping=dict(required=False, type="list"),
+ dynamic_mapping_arp_intf=dict(required=False, type="str"),
+ dynamic_mapping_arp_reply=dict(required=False, type="str", choices=["disable", "enable"]),
+ dynamic_mapping_associated_interface=dict(required=False, type="str"),
+ dynamic_mapping_block_size=dict(required=False, type="int"),
+ dynamic_mapping_comments=dict(required=False, type="str"),
+ dynamic_mapping_endip=dict(required=False, type="str"),
+ dynamic_mapping_num_blocks_per_user=dict(required=False, type="int"),
+ dynamic_mapping_pba_timeout=dict(required=False, type="int"),
+ dynamic_mapping_permit_any_host=dict(required=False, type="str", choices=["disable", "enable"]),
+ dynamic_mapping_source_endip=dict(required=False, type="str"),
+ dynamic_mapping_source_startip=dict(required=False, type="str"),
+ dynamic_mapping_startip=dict(required=False, type="str"),
+ dynamic_mapping_type=dict(required=False, type="str", choices=["overload",
+ "one-to-one",
+ "fixed-port-range",
+ "port-block-allocation"]),
+
+ )
+
+ module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False, )
+ # MODULE PARAMGRAM
+ paramgram = {
+ "mode": module.params["mode"],
+ "adom": module.params["adom"],
+ "type": module.params["type"],
+ "startip": module.params["startip"],
+ "source-startip": module.params["source_startip"],
+ "source-endip": module.params["source_endip"],
+ "permit-any-host": module.params["permit_any_host"],
+ "pba-timeout": module.params["pba_timeout"],
+ "num-blocks-per-user": module.params["num_blocks_per_user"],
+ "name": module.params["name"],
+ "endip": module.params["endip"],
+ "comments": module.params["comments"],
+ "block-size": module.params["block_size"],
+ "associated-interface": module.params["associated_interface"],
+ "arp-reply": module.params["arp_reply"],
+ "arp-intf": module.params["arp_intf"],
+ "dynamic_mapping": {
+ "arp-intf": module.params["dynamic_mapping_arp_intf"],
+ "arp-reply": module.params["dynamic_mapping_arp_reply"],
+ "associated-interface": module.params["dynamic_mapping_associated_interface"],
+ "block-size": module.params["dynamic_mapping_block_size"],
+ "comments": module.params["dynamic_mapping_comments"],
+ "endip": module.params["dynamic_mapping_endip"],
+ "num-blocks-per-user": module.params["dynamic_mapping_num_blocks_per_user"],
+ "pba-timeout": module.params["dynamic_mapping_pba_timeout"],
+ "permit-any-host": module.params["dynamic_mapping_permit_any_host"],
+ "source-endip": module.params["dynamic_mapping_source_endip"],
+ "source-startip": module.params["dynamic_mapping_source_startip"],
+ "startip": module.params["dynamic_mapping_startip"],
+ "type": module.params["dynamic_mapping_type"],
+ }
+ }
+
+ module.paramgram = paramgram
+ fmgr = None
+ if module._socket_path:
+ connection = Connection(module._socket_path)
+ fmgr = FortiManagerHandler(connection, module)
+ fmgr.tools = FMGRCommon()
+ else:
+ module.fail_json(**FAIL_SOCKET_MSG)
+
+ list_overrides = ['dynamic_mapping']
+ paramgram = fmgr.tools.paramgram_child_list_override(list_overrides=list_overrides,
+ paramgram=paramgram, module=module)
+ # UPDATE THE CHANGED PARAMGRAM
+ module.paramgram = paramgram
+
+ results = DEFAULT_RESULT_OBJ
+ try:
+ results = fmgr_fwobj_ippool_modify(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ return module.exit_json(**results[1])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_fwobj_ippool6.py b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_fwobj_ippool6.py
new file mode 100644
index 00000000..15e8977f
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_fwobj_ippool6.py
@@ -0,0 +1,223 @@
+#!/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: fmgr_fwobj_ippool6
+notes:
+ - Full Documentation at U(https://ftnt-ansible-docs.readthedocs.io/en/latest/).
+author:
+ - Luke Weighall (@lweighall)
+ - Andrew Welsh (@Ghilli3)
+ - Jim Huber (@p4r4n0y1ng)
+short_description: Allows the editing of IP Pool Objects within FortiManager.
+description:
+ - Allows users to add/edit/delete IPv6 Pool Objects.
+
+options:
+ adom:
+ description:
+ - The ADOM the configuration should belong to.
+ required: false
+ default: root
+
+ mode:
+ description:
+ - Sets one of three modes for managing the object.
+ - Allows use of soft-adds instead of overwriting existing values
+ choices: ['add', 'set', 'delete', 'update']
+ required: false
+ default: add
+
+ startip:
+ description:
+ - First IPv6 address (inclusive) in the range for the address pool.
+ required: false
+
+ name:
+ description:
+ - IPv6 IP pool name.
+ required: false
+
+ endip:
+ description:
+ - Final IPv6 address (inclusive) in the range for the address pool.
+ required: false
+
+ comments:
+ description:
+ - Comment.
+ required: false
+
+ dynamic_mapping:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ dynamic_mapping_comments:
+ description:
+ - Dynamic Mapping clone of original suffixed parameter.
+ required: false
+
+ dynamic_mapping_endip:
+ description:
+ - Dynamic Mapping clone of original suffixed parameter.
+ required: false
+
+ dynamic_mapping_startip:
+ description:
+ - Dynamic Mapping clone of original suffixed parameter.
+ required: false
+
+
+'''
+
+EXAMPLES = '''
+- name: ADD FMGR_FIREWALL_IPPOOL6
+ fmgr_firewall_ippool6:
+ mode: "add"
+ adom: "ansible"
+ startip:
+ name: "IPv6 IPPool"
+ endip:
+ comments: "Created by Ansible"
+
+- name: DELETE FMGR_FIREWALL_IPPOOL6
+ fmgr_firewall_ippool6:
+ mode: "delete"
+ adom: "ansible"
+ name: "IPv6 IPPool"
+'''
+
+RETURN = """
+api_result:
+ description: full API response, includes status code and message
+ returned: always
+ type: str
+"""
+
+from ansible.module_utils.basic import AnsibleModule, env_fallback
+from ansible.module_utils.connection import Connection
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.fortimanager import FortiManagerHandler
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGBaseException
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRCommon
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import DEFAULT_RESULT_OBJ
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FAIL_SOCKET_MSG
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import prepare_dict
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import scrub_dict
+
+
+def fmgr_fwobj_ippool6_modify(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+
+ mode = paramgram["mode"]
+ adom = paramgram["adom"]
+ # INIT A BASIC OBJECTS
+ response = DEFAULT_RESULT_OBJ
+ url = ""
+ datagram = {}
+
+ # EVAL THE MODE PARAMETER FOR SET OR ADD
+ if mode in ['set', 'add', 'update']:
+ url = '/pm/config/adom/{adom}/obj/firewall/ippool6'.format(adom=adom)
+ datagram = scrub_dict(prepare_dict(paramgram))
+
+ # EVAL THE MODE PARAMETER FOR DELETE
+ elif mode == "delete":
+ # SET THE CORRECT URL FOR DELETE
+ url = '/pm/config/adom/{adom}/obj/firewall/ippool6/{name}'.format(adom=adom, name=paramgram["name"])
+ datagram = {}
+
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+ return response
+
+
+def main():
+ argument_spec = dict(
+ adom=dict(type="str", default="root"),
+ mode=dict(choices=["add", "set", "delete", "update"], type="str", default="add"),
+ startip=dict(required=False, type="str"),
+ name=dict(required=False, type="str"),
+ endip=dict(required=False, type="str"),
+ comments=dict(required=False, type="str"),
+ dynamic_mapping=dict(required=False, type="list"),
+ dynamic_mapping_comments=dict(required=False, type="str"),
+ dynamic_mapping_endip=dict(required=False, type="str"),
+ dynamic_mapping_startip=dict(required=False, type="str"),
+
+ )
+
+ module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False, )
+ # MODULE PARAMGRAM
+ paramgram = {
+ "mode": module.params["mode"],
+ "adom": module.params["adom"],
+ "startip": module.params["startip"],
+ "name": module.params["name"],
+ "endip": module.params["endip"],
+ "comments": module.params["comments"],
+ "dynamic_mapping": {
+ "comments": module.params["dynamic_mapping_comments"],
+ "endip": module.params["dynamic_mapping_endip"],
+ "startip": module.params["dynamic_mapping_startip"],
+ }
+ }
+ module.paramgram = paramgram
+ fmgr = None
+ if module._socket_path:
+ connection = Connection(module._socket_path)
+ fmgr = FortiManagerHandler(connection, module)
+ fmgr.tools = FMGRCommon()
+ else:
+ module.fail_json(**FAIL_SOCKET_MSG)
+
+ list_overrides = ['dynamic_mapping']
+ paramgram = fmgr.tools.paramgram_child_list_override(list_overrides=list_overrides,
+ paramgram=paramgram, module=module)
+
+ results = DEFAULT_RESULT_OBJ
+
+ try:
+ results = fmgr_fwobj_ippool6_modify(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ return module.exit_json(**results[1])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_fwobj_service.py b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_fwobj_service.py
new file mode 100644
index 00000000..fb8a3597
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_fwobj_service.py
@@ -0,0 +1,617 @@
+#!/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: fmgr_fwobj_service
+notes:
+ - Full Documentation at U(https://ftnt-ansible-docs.readthedocs.io/en/latest/).
+author:
+ - Luke Weighall (@lweighall)
+ - Andrew Welsh (@Ghilli3)
+ - Jim Huber (@p4r4n0y1ng)
+short_description: Manages FortiManager Firewall Service Objects.
+description:
+ - Manages FortiManager Firewall Service Objects.
+
+options:
+ adom:
+ description:
+ -The ADOM the configuration should belong to.
+ required: false
+ default: root
+
+ app_category:
+ description:
+ - Application category ID.
+ required: false
+
+ app_service_type:
+ description:
+ - Application service type.
+ required: false
+
+ application:
+ description:
+ - Application ID.
+ required: false
+
+ category:
+ description:
+ - Service category.
+ required: false
+
+ check_reset_range:
+ description:
+ - Enable disable RST check.
+ required: false
+
+ color:
+ description:
+ - GUI icon color.
+ required: false
+ default: 22
+
+ comment:
+ description:
+ - Comment.
+ required: false
+
+ custom_type:
+ description:
+ - Tells module what kind of custom service to be added.
+ choices: ['tcp_udp_sctp', 'icmp', 'icmp6', 'ip', 'http', 'ftp', 'connect', 'socks_tcp', 'socks_udp', 'all']
+ default: all
+ required: false
+
+ explicit_proxy:
+ description:
+ - Enable/disable explicit web proxy service.
+ choices: ['enable', 'disable']
+ default: 'disable'
+ required: false
+
+ fqdn:
+ description:
+ - Fully qualified domain name.
+ required: false
+ default: ""
+
+ group_name:
+ description:
+ - Name of the Service Group.
+ required: false
+
+ group_member:
+ description:
+ - Comma-Seperated list of members' names.
+ required: false
+
+ icmp_code:
+ description:
+ - ICMP code.
+ required: false
+
+ icmp_type:
+ description:
+ - ICMP type.
+ required: false
+
+ iprange:
+ description:
+ - Start IP-End IP.
+ required: false
+ default: "0.0.0.0"
+
+ name:
+ description:
+ - Custom service name.
+ required: false
+
+ mode:
+ description:
+ - Sets one of three modes for managing the object.
+ choices: ['add', 'set', 'delete']
+ default: add
+ required: false
+
+ object_type:
+ description:
+ - Tells module if we are adding a custom service, category, or group.
+ choices: ['custom', 'group', 'category']
+ required: false
+
+ protocol:
+ description:
+ - Protocol type.
+ required: false
+
+ protocol_number:
+ description:
+ - IP protocol number.
+ required: false
+
+ sctp_portrange:
+ description:
+ - Multiple SCTP port ranges. Comma separated list of destination ports to add (i.e. '443,80').
+ - Syntax is <destPort:sourcePort>
+ - If no sourcePort is defined, it assumes all of them.
+ - Ranges can be defined with a hyphen -
+ - Examples -- '443' (destPort 443 only) '443:1000-2000' (destPort 443 from source ports 1000-2000).
+ - String multiple together in same quotes, comma separated. ('443:1000-2000, 80:1000-2000').
+ required: false
+
+ session_ttl:
+ description:
+ - Session TTL (300 - 604800, 0 = default).
+ required: false
+ default: 0
+
+ tcp_halfclose_timer:
+ description:
+ - TCP half close timeout (1 - 86400 sec, 0 = default).
+ required: false
+ default: 0
+
+ tcp_halfopen_timer:
+ description:
+ - TCP half close timeout (1 - 86400 sec, 0 = default).
+ required: false
+ default: 0
+
+ tcp_portrange:
+ description:
+ - Comma separated list of destination ports to add (i.e. '443,80').
+ - Syntax is <destPort:sourcePort>
+ - If no sourcePort is defined, it assumes all of them.
+ - Ranges can be defined with a hyphen -
+ - Examples -- '443' (destPort 443 only) '443:1000-2000' (destPort 443 from source ports 1000-2000).
+ - String multiple together in same quotes, comma separated. ('443:1000-2000, 80:1000-2000').
+ required: false
+
+ tcp_timewait_timer:
+ description:
+ - TCP half close timeout (1 - 300 sec, 0 = default).
+ required: false
+ default: 0
+
+ udp_idle_timer:
+ description:
+ - TCP half close timeout (0 - 86400 sec, 0 = default).
+ required: false
+ default: 0
+
+ udp_portrange:
+ description:
+ - Comma separated list of destination ports to add (i.e. '443,80').
+ - Syntax is <destPort:sourcePort>
+ - If no sourcePort is defined, it assumes all of them.
+ - Ranges can be defined with a hyphen -
+ - Examples -- '443' (destPort 443 only) '443:1000-2000' (destPort 443 from source ports 1000-2000).
+ - String multiple together in same quotes, comma separated. ('443:1000-2000, 80:1000-2000').
+ required: false
+
+ visibility:
+ description:
+ - Enable/disable service visibility.
+ required: false
+ choices: ["enable", "disable"]
+ default: "enable"
+
+'''
+
+EXAMPLES = '''
+- name: ADD A CUSTOM SERVICE FOR TCP/UDP/SCP
+ community.fortios.fmgr_fwobj_service:
+ adom: "ansible"
+ name: "ansible_custom_service"
+ object_type: "custom"
+ custom_type: "tcp_udp_sctp"
+ tcp_portrange: "443"
+ udp_portrange: "51"
+ sctp_portrange: "100"
+
+- name: ADD A CUSTOM SERVICE FOR TCP/UDP/SCP WITH SOURCE RANGES AND MULTIPLES
+ community.fortios.fmgr_fwobj_service:
+ adom: "ansible"
+ name: "ansible_custom_serviceWithSource"
+ object_type: "custom"
+ custom_type: "tcp_udp_sctp"
+ tcp_portrange: "443:2000-1000,80-82:10000-20000"
+ udp_portrange: "51:100-200,162:200-400"
+ sctp_portrange: "100:2000-2500"
+
+- name: ADD A CUSTOM SERVICE FOR ICMP
+ community.fortios.fmgr_fwobj_service:
+ adom: "ansible"
+ name: "ansible_custom_icmp"
+ object_type: "custom"
+ custom_type: "icmp"
+ icmp_type: "8"
+ icmp_code: "3"
+
+- name: ADD A CUSTOM SERVICE FOR ICMP6
+ community.fortios.fmgr_fwobj_service:
+ adom: "ansible"
+ name: "ansible_custom_icmp6"
+ object_type: "custom"
+ custom_type: "icmp6"
+ icmp_type: "5"
+ icmp_code: "1"
+
+- name: ADD A CUSTOM SERVICE FOR IP - GRE
+ community.fortios.fmgr_fwobj_service:
+ adom: "ansible"
+ name: "ansible_custom_icmp6"
+ object_type: "custom"
+ custom_type: "ip"
+ protocol_number: "47"
+
+- name: ADD A CUSTOM PROXY FOR ALL WITH SOURCE RANGES AND MULTIPLES
+ community.fortios.fmgr_fwobj_service:
+ adom: "ansible"
+ name: "ansible_custom_proxy_all"
+ object_type: "custom"
+ custom_type: "all"
+ explicit_proxy: "enable"
+ tcp_portrange: "443:2000-1000,80-82:10000-20000"
+ iprange: "www.ansible.com"
+'''
+
+RETURN = """
+api_result:
+ description: full API response, includes status code and message
+ returned: always
+ type: str
+"""
+
+from ansible.module_utils.basic import AnsibleModule, env_fallback
+from ansible.module_utils.connection import Connection
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.fortimanager import FortiManagerHandler
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGBaseException
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRCommon
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import DEFAULT_RESULT_OBJ
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FAIL_SOCKET_MSG
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import scrub_dict
+
+
+def fmgr_fwobj_service_custom(fmgr, paramgram):
+ """
+ description:
+ - the tcp and udp-portrange parameters are in a list when there are multiple. they are not in a list when they
+ singular or by themselves (only 1 was listed)
+ - the syntax for this is (destPort:sourcePort). Ranges are (xxxx-xxxx) i.e. 443:443, or 443:1000-2000.
+ - if you leave out the second field after the colon (source port) it assumes any source port (which is usual)
+ - multiples would look like ['443:1000-2000','80']
+ - a single would look simple like "443:1000-2000" without the list around it ( a string!)
+ - the protocol parameter is the protocol NUMBER, not the string of it.
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ response = DEFAULT_RESULT_OBJ
+ if paramgram["mode"] in ['set', 'add']:
+ # SET THE URL FOR ADD / SET
+ url = '/pm/config/adom/{adom}/obj/firewall/service/custom'.format(adom=paramgram["adom"])
+ # BUILD THE DEFAULT DATAGRAM
+ datagram = {
+ # ADVANCED OPTIONS
+ "app-category": paramgram["app-category"],
+ "app-service-type": paramgram["app-service-type"],
+ "application": paramgram["application"],
+ "category": paramgram["category"],
+ "check-reset-range": paramgram["check-reset-range"],
+ "color": paramgram["color"],
+ "session-ttl": paramgram["session-ttl"],
+ "tcp-halfclose-timer": paramgram["tcp-halfclose-timer"],
+ "tcp-halfopen-timer": paramgram["tcp-halfopen-timer"],
+ "tcp-timewait-timer": paramgram["tcp-timewait-timer"],
+ "udp-idle-timer": paramgram["udp-idle-timer"],
+ "visibility": paramgram["visibility"],
+ "comment": paramgram["comment"],
+ "proxy": paramgram["explicit-proxy"],
+ "name": paramgram["name"]
+ }
+
+ if datagram["proxy"] == "disable":
+ #######################################
+ # object-type = "TCP/UDP/SCTP"
+ #######################################
+ if paramgram["custom_type"] == "tcp_udp_sctp":
+ datagram["protocol"] = "TCP/UDP/SCTP"
+ # PROCESS PORT RANGES TO PUT INTO THE PROPER SYNTAX
+ if paramgram["tcp-portrange"] is not None:
+ tcp_list = []
+ for tcp in paramgram["tcp-portrange"].split(","):
+ tcp = tcp.strip()
+ tcp_list.append(tcp)
+ datagram["tcp-portrange"] = tcp_list
+
+ if paramgram["udp-portrange"] is not None:
+ udp_list = []
+ for udp in paramgram["udp-portrange"].split(","):
+ udp = udp.strip()
+ udp_list.append(udp)
+ datagram["udp-portrange"] = udp_list
+
+ if paramgram["sctp-portrange"] is not None:
+ sctp_list = []
+ for sctp in paramgram["sctp-portrange"].split(","):
+ sctp = sctp.strip()
+ sctp_list.append(sctp)
+ datagram["sctp-portrange"] = sctp_list
+
+ #######################################
+ # object-type = "ICMP"
+ #######################################
+ if paramgram["custom_type"] == "icmp":
+ datagram["icmpcode"] = paramgram["icmp_code"]
+ datagram["icmptype"] = paramgram["icmp_type"]
+ datagram["protocol"] = "ICMP"
+
+ #######################################
+ # object-type = "ICMP6"
+ #######################################
+ if paramgram["custom_type"] == "icmp6":
+ datagram["icmpcode"] = paramgram["icmp_code"]
+ datagram["icmptype"] = paramgram["icmp_type"]
+ datagram["protocol"] = "ICMP6"
+
+ #######################################
+ # object-type = "IP"
+ #######################################
+ if paramgram["custom_type"] == "ip":
+ datagram["protocol"] = "IP"
+ datagram["protocol-number"] = paramgram["protocol-number"]
+
+ #######################################
+ # object-type in any of the explicit proxy options
+ #######################################
+ if datagram["proxy"] == "enable":
+ datagram["protocol"] = paramgram["custom_type"].upper()
+ datagram["iprange"] = paramgram["iprange"]
+
+ # PROCESS PROXY TCP PORT RANGES TO PUT INTO THE PROPER SYNTAX
+ if paramgram["tcp-portrange"] is not None:
+ tcp_list = []
+ for tcp in paramgram["tcp-portrange"].split(","):
+ tcp = tcp.strip()
+ tcp_list.append(tcp)
+ datagram["tcp-portrange"] = tcp_list
+
+ if paramgram["mode"] == "delete":
+ datagram = {
+ "name": paramgram["name"]
+ }
+ # SET DELETE URL
+ url = '/pm/config/adom/{adom}/obj/firewall/service/custom' \
+ '/{name}'.format(adom=paramgram["adom"], name=paramgram["name"])
+
+ datagram = scrub_dict(datagram)
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+ return response
+
+
+def fmgr_fwobj_service_group(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ response = DEFAULT_RESULT_OBJ
+ if paramgram["mode"] in ['set', 'add']:
+ url = '/pm/config/adom/{adom}/obj/firewall/service/group'.format(adom=paramgram["adom"])
+ datagram = {
+ "name": paramgram["group-name"],
+ "comment": paramgram["comment"],
+ "proxy": paramgram["explicit-proxy"],
+ "color": paramgram["color"]
+ }
+
+ members = paramgram["group-member"]
+ member = []
+ for obj in members.split(","):
+ member.append(obj.strip())
+ datagram["member"] = member
+
+ if paramgram["mode"] == "delete":
+ datagram = {
+ "name": paramgram["name"]
+ }
+ # SET DELETE URL
+ url = '/pm/config/adom/{adom}/obj/firewall/service/group' \
+ '/{name}'.format(adom=paramgram["adom"], name=paramgram["group-name"])
+
+ datagram = scrub_dict(datagram)
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+ return response
+
+
+def fmgr_fwobj_service_category(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ response = DEFAULT_RESULT_OBJ
+ if paramgram["mode"] in ['set', 'add']:
+ url = '/pm/config/adom/{adom}/obj/firewall/service/category'.format(adom=paramgram["adom"])
+ # GET RID OF ANY WHITESPACE
+ category = paramgram["category"]
+ category = category.strip()
+
+ datagram = {
+ "name": paramgram["category"],
+ "comment": "Created by Ansible"
+ }
+
+ # IF MODE = DELETE
+ if paramgram["mode"] == "delete":
+ datagram = {
+ "name": paramgram["name"]
+ }
+ # SET DELETE URL
+ url = '/pm/config/adom/{adom}/obj/firewall/service/category' \
+ '/{name}'.format(adom=paramgram["adom"], name=paramgram["category"])
+
+ datagram = scrub_dict(datagram)
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+ return response
+
+
+def main():
+ argument_spec = dict(
+ adom=dict(required=False, type="str", default="root"),
+ mode=dict(required=False, type="str", choices=['add', 'set', 'delete'], default="add"),
+ app_category=dict(required=False, type="str"),
+ app_service_type=dict(required=False, type="str"),
+ application=dict(required=False, type="str"),
+ category=dict(required=False, type="str"),
+ check_reset_range=dict(required=False, type="str"),
+ color=dict(required=False, type="int", default=22),
+ comment=dict(required=False, type="str"),
+ custom_type=dict(required=False, type="str", choices=['tcp_udp_sctp', 'icmp', 'icmp6', 'ip', 'http', 'ftp',
+ 'connect', 'socks_tcp', 'socks_udp', 'all'],
+ default="all"),
+ explicit_proxy=dict(required=False, type="str", choices=['enable', 'disable'], default="disable"),
+ fqdn=dict(required=False, type="str", default=""),
+ group_name=dict(required=False, type="str"),
+ group_member=dict(required=False, type="str"),
+ icmp_code=dict(required=False, type="int"),
+ icmp_type=dict(required=False, type="int"),
+ iprange=dict(required=False, type="str", default="0.0.0.0"),
+ name=dict(required=False, type="str"),
+ protocol=dict(required=False, type="str"),
+ protocol_number=dict(required=False, type="int"),
+ sctp_portrange=dict(required=False, type="str"),
+ session_ttl=dict(required=False, type="int", default=0),
+ object_type=dict(required=False, type="str", choices=['custom', 'group', 'category']),
+ tcp_halfclose_timer=dict(required=False, type="int", default=0),
+ tcp_halfopen_timer=dict(required=False, type="int", default=0),
+ tcp_portrange=dict(required=False, type="str"),
+ tcp_timewait_timer=dict(required=False, type="int", default=0),
+ udp_idle_timer=dict(required=False, type="int", default=0),
+ udp_portrange=dict(required=False, type="str"),
+ visibility=dict(required=False, type="str", default="enable", choices=["enable", "disable"]),
+
+ )
+
+ module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False, )
+ # MODULE DATAGRAM
+ paramgram = {
+ "adom": module.params["adom"],
+ "app-category": module.params["app_category"],
+ "app-service-type": module.params["app_service_type"],
+ "application": module.params["application"],
+ "category": module.params["category"],
+ "check-reset-range": module.params["check_reset_range"],
+ "color": module.params["color"],
+ "comment": module.params["comment"],
+ "custom_type": module.params["custom_type"],
+ "explicit-proxy": module.params["explicit_proxy"],
+ "fqdn": module.params["fqdn"],
+ "group-name": module.params["group_name"],
+ "group-member": module.params["group_member"],
+ "icmp_code": module.params["icmp_code"],
+ "icmp_type": module.params["icmp_type"],
+ "iprange": module.params["iprange"],
+ "name": module.params["name"],
+ "mode": module.params["mode"],
+ "protocol": module.params["protocol"],
+ "protocol-number": module.params["protocol_number"],
+ "sctp-portrange": module.params["sctp_portrange"],
+ "object_type": module.params["object_type"],
+ "session-ttl": module.params["session_ttl"],
+ "tcp-halfclose-timer": module.params["tcp_halfclose_timer"],
+ "tcp-halfopen-timer": module.params["tcp_halfopen_timer"],
+ "tcp-portrange": module.params["tcp_portrange"],
+ "tcp-timewait-timer": module.params["tcp_timewait_timer"],
+ "udp-idle-timer": module.params["udp_idle_timer"],
+ "udp-portrange": module.params["udp_portrange"],
+ "visibility": module.params["visibility"],
+ }
+ module.paramgram = paramgram
+ fmgr = None
+ if module._socket_path:
+ connection = Connection(module._socket_path)
+ fmgr = FortiManagerHandler(connection, module)
+ fmgr.tools = FMGRCommon()
+ else:
+ module.fail_json(**FAIL_SOCKET_MSG)
+
+ results = DEFAULT_RESULT_OBJ
+
+ try:
+ # CHECK FOR CATEGORIES TO ADD
+ # THIS IS ONLY WHEN OBJECT_TYPE ISN'T SPECIFICALLY ADDING A CATEGORY!
+ # WE NEED TO ADD THE CATEGORY BEFORE ADDING THE OBJECT
+ # IF ANY category ARE DEFINED AND MODE IS ADD OR SET LETS ADD THOSE
+ # THIS IS A "BLIND ADD" AND THE EXIT CODE FOR OBJECT ALREADY EXISTS IS TREATED AS A PASS
+ if paramgram["category"] is not None and paramgram["mode"] in ['add', 'set'] \
+ and paramgram["object_type"] != "category":
+ category_add = fmgr_fwobj_service_category(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=category_add,
+ ansible_facts=fmgr.construct_ansible_facts(category_add, module.params, paramgram))
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ try:
+ # IF OBJECT_TYPE IS CATEGORY...
+ if paramgram["object_type"] == 'category':
+ results = fmgr_fwobj_service_category(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results, good_codes=[0, -2, -3],
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ try:
+ # IF OBJECT_TYPE IS CUSTOM...
+ if paramgram["object_type"] == 'custom':
+ results = fmgr_fwobj_service_custom(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results, good_codes=[0, -2, -3],
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ try:
+ # IF OBJECT_TYPE IS GROUP...
+ if paramgram["object_type"] == 'group':
+ results = fmgr_fwobj_service_group(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results, good_codes=[0, -2, -3],
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ return module.exit_json(**results[1])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_fwobj_vip.py b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_fwobj_vip.py
new file mode 100644
index 00000000..adba2e49
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_fwobj_vip.py
@@ -0,0 +1,2424 @@
+#!/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: fmgr_fwobj_vip
+notes:
+ - Full Documentation at U(https://ftnt-ansible-docs.readthedocs.io/en/latest/).
+author:
+ - Luke Weighall (@lweighall)
+ - Andrew Welsh (@Ghilli3)
+ - Jim Huber (@p4r4n0y1ng)
+short_description: Manages Virtual IPs objects in FortiManager
+description:
+ - Manages Virtual IP objects in FortiManager for IPv4
+
+options:
+ adom:
+ description:
+ - The ADOM the configuration should belong to.
+ required: false
+ default: root
+
+ mode:
+ description:
+ - Sets one of three modes for managing the object.
+ - Allows use of soft-adds instead of overwriting existing values
+ choices: ['add', 'set', 'delete', 'update']
+ required: false
+ default: add
+
+ websphere_server:
+ description:
+ - Enable to add an HTTP header to indicate SSL offloading for a WebSphere server.
+ - choice | disable | Do not add HTTP header indicating SSL offload for WebSphere server.
+ - choice | enable | Add HTTP header indicating SSL offload for WebSphere server.
+ required: false
+ choices: ["disable", "enable"]
+
+ weblogic_server:
+ description:
+ - Enable to add an HTTP header to indicate SSL offloading for a WebLogic server.
+ - choice | disable | Do not add HTTP header indicating SSL offload for WebLogic server.
+ - choice | enable | Add HTTP header indicating SSL offload for WebLogic server.
+ required: false
+ choices: ["disable", "enable"]
+
+ type:
+ description:
+ - Configure a static NAT, load balance, server load balance, DNS translation, or FQDN VIP.
+ - choice | static-nat | Static NAT.
+ - choice | load-balance | Load balance.
+ - choice | server-load-balance | Server load balance.
+ - choice | dns-translation | DNS translation.
+ - choice | fqdn | FQDN Translation
+ required: false
+ choices: ["static-nat", "load-balance", "server-load-balance", "dns-translation", "fqdn"]
+
+ ssl_server_session_state_type:
+ description:
+ - How to expire SSL sessions for the segment of the SSL connection between the server and the FortiGate.
+ - choice | disable | Do not keep session states.
+ - choice | time | Expire session states after this many minutes.
+ - choice | count | Expire session states when this maximum is reached.
+ - choice | both | Expire session states based on time or count, whichever occurs first.
+ required: false
+ choices: ["disable", "time", "count", "both"]
+
+ ssl_server_session_state_timeout:
+ description:
+ - Number of minutes to keep FortiGate to Server SSL session state.
+ required: false
+
+ ssl_server_session_state_max:
+ description:
+ - Maximum number of FortiGate to Server SSL session states to keep.
+ required: false
+
+ ssl_server_min_version:
+ description:
+ - Lowest SSL/TLS version acceptable from a server. Use the client setting by default.
+ - choice | ssl-3.0 | SSL 3.0.
+ - choice | tls-1.0 | TLS 1.0.
+ - choice | tls-1.1 | TLS 1.1.
+ - choice | tls-1.2 | TLS 1.2.
+ - choice | client | Use same value as client configuration.
+ required: false
+ choices: ["ssl-3.0", "tls-1.0", "tls-1.1", "tls-1.2", "client"]
+
+ ssl_server_max_version:
+ description:
+ - Highest SSL/TLS version acceptable from a server. Use the client setting by default.
+ - choice | ssl-3.0 | SSL 3.0.
+ - choice | tls-1.0 | TLS 1.0.
+ - choice | tls-1.1 | TLS 1.1.
+ - choice | tls-1.2 | TLS 1.2.
+ - choice | client | Use same value as client configuration.
+ required: false
+ choices: ["ssl-3.0", "tls-1.0", "tls-1.1", "tls-1.2", "client"]
+
+ ssl_server_algorithm:
+ description:
+ - Permitted encryption algorithms for the server side of SSL full mode sessions according to encryption strength
+ - choice | high | High encryption. Allow only AES and ChaCha.
+ - choice | low | Low encryption. Allow AES, ChaCha, 3DES, RC4, and DES.
+ - choice | medium | Medium encryption. Allow AES, ChaCha, 3DES, and RC4.
+ - choice | custom | Custom encryption. Use ssl-server-cipher-suites to select the cipher suites that are allowed.
+ - choice | client | Use the same encryption algorithms for both client and server sessions.
+ required: false
+ choices: ["high", "low", "medium", "custom", "client"]
+
+ ssl_send_empty_frags:
+ description:
+ - Enable/disable sending empty fragments to avoid CBC IV attacks (SSL 3.0 &amp; TLS 1.0 only).
+ - choice | disable | Do not send empty fragments.
+ - choice | enable | Send empty fragments.
+ required: false
+ choices: ["disable", "enable"]
+
+ ssl_pfs:
+ description:
+ - Select the cipher suites that can be used for SSL perfect forward secrecy (PFS).
+ - choice | require | Allow only Diffie-Hellman cipher-suites, so PFS is applied.
+ - choice | deny | Allow only non-Diffie-Hellman cipher-suites, so PFS is not applied.
+ - choice | allow | Allow use of any cipher suite so PFS may or may not be used depending on the cipher suite
+ required: false
+ choices: ["require", "deny", "allow"]
+
+ ssl_mode:
+ description:
+ - Apply SSL offloading mode
+ - choice | half | Client to FortiGate SSL.
+ - choice | full | Client to FortiGate and FortiGate to Server SSL.
+ required: false
+ choices: ["half", "full"]
+
+ ssl_min_version:
+ description:
+ - Lowest SSL/TLS version acceptable from a client.
+ - choice | ssl-3.0 | SSL 3.0.
+ - choice | tls-1.0 | TLS 1.0.
+ - choice | tls-1.1 | TLS 1.1.
+ - choice | tls-1.2 | TLS 1.2.
+ required: false
+ choices: ["ssl-3.0", "tls-1.0", "tls-1.1", "tls-1.2"]
+
+ ssl_max_version:
+ description:
+ - Highest SSL/TLS version acceptable from a client.
+ - choice | ssl-3.0 | SSL 3.0.
+ - choice | tls-1.0 | TLS 1.0.
+ - choice | tls-1.1 | TLS 1.1.
+ - choice | tls-1.2 | TLS 1.2.
+ required: false
+ choices: ["ssl-3.0", "tls-1.0", "tls-1.1", "tls-1.2"]
+
+ ssl_http_match_host:
+ description:
+ - Enable/disable HTTP host matching for location conversion.
+ - choice | disable | Do not match HTTP host.
+ - choice | enable | Match HTTP host in response header.
+ required: false
+ choices: ["disable", "enable"]
+
+ ssl_http_location_conversion:
+ description:
+ - Enable to replace HTTP with HTTPS in the reply's Location HTTP header field.
+ - choice | disable | Disable HTTP location conversion.
+ - choice | enable | Enable HTTP location conversion.
+ required: false
+ choices: ["disable", "enable"]
+
+ ssl_hsts_include_subdomains:
+ description:
+ - Indicate that HSTS header applies to all subdomains.
+ - choice | disable | HSTS header does not apply to subdomains.
+ - choice | enable | HSTS header applies to subdomains.
+ required: false
+ choices: ["disable", "enable"]
+
+ ssl_hsts_age:
+ description:
+ - Number of seconds the client should honour the HSTS setting.
+ required: false
+
+ ssl_hsts:
+ description:
+ - Enable/disable including HSTS header in response.
+ - choice | disable | Do not add a HSTS header to each a HTTP response.
+ - choice | enable | Add a HSTS header to each HTTP response.
+ required: false
+ choices: ["disable", "enable"]
+
+ ssl_hpkp_report_uri:
+ description:
+ - URL to report HPKP violations to.
+ required: false
+
+ ssl_hpkp_primary:
+ description:
+ - Certificate to generate primary HPKP pin from.
+ required: false
+
+ ssl_hpkp_include_subdomains:
+ description:
+ - Indicate that HPKP header applies to all subdomains.
+ - choice | disable | HPKP header does not apply to subdomains.
+ - choice | enable | HPKP header applies to subdomains.
+ required: false
+ choices: ["disable", "enable"]
+
+ ssl_hpkp_backup:
+ description:
+ - Certificate to generate backup HPKP pin from.
+ required: false
+
+ ssl_hpkp_age:
+ description:
+ - Number of seconds the client should honour the HPKP setting.
+ required: false
+
+ ssl_hpkp:
+ description:
+ - Enable/disable including HPKP header in response.
+ - choice | disable | Do not add a HPKP header to each HTTP response.
+ - choice | enable | Add a HPKP header to each a HTTP response.
+ - choice | report-only | Add a HPKP Report-Only header to each HTTP response.
+ required: false
+ choices: ["disable", "enable", "report-only"]
+
+ ssl_dh_bits:
+ description:
+ - Number of bits to use in the Diffie-Hellman exchange for RSA encryption of SSL sessions.
+ - choice | 768 | 768-bit Diffie-Hellman prime.
+ - choice | 1024 | 1024-bit Diffie-Hellman prime.
+ - choice | 1536 | 1536-bit Diffie-Hellman prime.
+ - choice | 2048 | 2048-bit Diffie-Hellman prime.
+ - choice | 3072 | 3072-bit Diffie-Hellman prime.
+ - choice | 4096 | 4096-bit Diffie-Hellman prime.
+ required: false
+ choices: ["768", "1024", "1536", "2048", "3072", "4096"]
+
+ ssl_client_session_state_type:
+ description:
+ - How to expire SSL sessions for the segment of the SSL connection between the client and the FortiGate.
+ - choice | disable | Do not keep session states.
+ - choice | time | Expire session states after this many minutes.
+ - choice | count | Expire session states when this maximum is reached.
+ - choice | both | Expire session states based on time or count, whichever occurs first.
+ required: false
+ choices: ["disable", "time", "count", "both"]
+
+ ssl_client_session_state_timeout:
+ description:
+ - Number of minutes to keep client to FortiGate SSL session state.
+ required: false
+
+ ssl_client_session_state_max:
+ description:
+ - Maximum number of client to FortiGate SSL session states to keep.
+ required: false
+
+ ssl_client_renegotiation:
+ description:
+ - Allow, deny, or require secure renegotiation of client sessions to comply with RFC 5746.
+ - choice | deny | Abort any client initiated SSL re-negotiation attempt.
+ - choice | allow | Allow a SSL client to renegotiate.
+ - choice | secure | Abort any client initiated SSL re-negotiation attempt that does not use RFC 5746.
+ required: false
+ choices: ["deny", "allow", "secure"]
+
+ ssl_client_fallback:
+ description:
+ - Enable/disable support for preventing Downgrade Attacks on client connections (RFC 7507).
+ - choice | disable | Disable.
+ - choice | enable | Enable.
+ required: false
+ choices: ["disable", "enable"]
+
+ ssl_certificate:
+ description:
+ - The name of the SSL certificate to use for SSL acceleration.
+ required: false
+
+ ssl_algorithm:
+ description:
+ - Permitted encryption algorithms for SSL sessions according to encryption strength.
+ - choice | high | High encryption. Allow only AES and ChaCha.
+ - choice | medium | Medium encryption. Allow AES, ChaCha, 3DES, and RC4.
+ - choice | low | Low encryption. Allow AES, ChaCha, 3DES, RC4, and DES.
+ - choice | custom | Custom encryption. Use config ssl-cipher-suites to select the cipher suites that are allowed.
+ required: false
+ choices: ["high", "medium", "low", "custom"]
+
+ srcintf_filter:
+ description:
+ - Interfaces to which the VIP applies. Separate the names with spaces.
+ required: false
+
+ src_filter:
+ description:
+ - Source address filter. Each address must be either an IP/subnet (x.x.x.x/n) or a range (x.x.x.x-y.y.y.y).
+ - Separate addresses with spaces.
+ required: false
+
+ service:
+ description:
+ - Service name.
+ required: false
+
+ server_type:
+ description:
+ - Protocol to be load balanced by the virtual server (also called the server load balance virtual IP).
+ - choice | http | HTTP
+ - choice | https | HTTPS
+ - choice | ssl | SSL
+ - choice | tcp | TCP
+ - choice | udp | UDP
+ - choice | ip | IP
+ - choice | imaps | IMAPS
+ - choice | pop3s | POP3S
+ - choice | smtps | SMTPS
+ required: false
+ choices: ["http", "https", "ssl", "tcp", "udp", "ip", "imaps", "pop3s", "smtps"]
+
+ protocol:
+ description:
+ - Protocol to use when forwarding packets.
+ - choice | tcp | TCP.
+ - choice | udp | UDP.
+ - choice | sctp | SCTP.
+ - choice | icmp | ICMP.
+ required: false
+ choices: ["tcp", "udp", "sctp", "icmp"]
+
+ portmapping_type:
+ description:
+ - Port mapping type.
+ - choice | 1-to-1 | One to one.
+ - choice | m-to-n | Many to many.
+ required: false
+ choices: ["1-to-1", "m-to-n"]
+
+ portforward:
+ description:
+ - Enable/disable port forwarding.
+ - choice | disable | Disable port forward.
+ - choice | enable | Enable port forward.
+ required: false
+ choices: ["disable", "enable"]
+
+ persistence:
+ description:
+ - Configure how to make sure that clients connect to the same server every time they make a request that is part
+ - of the same session.
+ - choice | none | None.
+ - choice | http-cookie | HTTP cookie.
+ - choice | ssl-session-id | SSL session ID.
+ required: false
+ choices: ["none", "http-cookie", "ssl-session-id"]
+
+ outlook_web_access:
+ description:
+ - Enable to add the Front-End-Https header for Microsoft Outlook Web Access.
+ - choice | disable | Disable Outlook Web Access support.
+ - choice | enable | Enable Outlook Web Access support.
+ required: false
+ choices: ["disable", "enable"]
+
+ nat_source_vip:
+ description:
+ - Enable to prevent unintended servers from using a virtual IP.
+ - Disable to use the actual IP address of the server as the source address.
+ - choice | disable | Do not force to NAT as VIP.
+ - choice | enable | Force to NAT as VIP.
+ required: false
+ choices: ["disable", "enable"]
+
+ name:
+ description:
+ - Virtual IP name.
+ required: false
+
+ monitor:
+ description:
+ - Name of the health check monitor to use when polling to determine a virtual server's connectivity status.
+ required: false
+
+ max_embryonic_connections:
+ description:
+ - Maximum number of incomplete connections.
+ required: false
+
+ mappedport:
+ description:
+ - Port number range on the destination network to which the external port number range is mapped.
+ required: false
+
+ mappedip:
+ description:
+ - IP address or address range on the destination network to which the external IP address is mapped.
+ required: false
+
+ mapped_addr:
+ description:
+ - Mapped FQDN address name.
+ required: false
+
+ ldb_method:
+ description:
+ - Method used to distribute sessions to real servers.
+ - choice | static | Distribute to server based on source IP.
+ - choice | round-robin | Distribute to server based round robin order.
+ - choice | weighted | Distribute to server based on weight.
+ - choice | least-session | Distribute to server with lowest session count.
+ - choice | least-rtt | Distribute to server with lowest Round-Trip-Time.
+ - choice | first-alive | Distribute to the first server that is alive.
+ - choice | http-host | Distribute to server based on host field in HTTP header.
+ required: false
+ choices: ["static", "round-robin", "weighted", "least-session", "least-rtt", "first-alive", "http-host"]
+
+ https_cookie_secure:
+ description:
+ - Enable/disable verification that inserted HTTPS cookies are secure.
+ - choice | disable | Do not mark cookie as secure, allow sharing between an HTTP and HTTPS connection.
+ - choice | enable | Mark inserted cookie as secure, cookie can only be used for HTTPS a connection.
+ required: false
+ choices: ["disable", "enable"]
+
+ http_multiplex:
+ description:
+ - Enable/disable HTTP multiplexing.
+ - choice | disable | Disable HTTP session multiplexing.
+ - choice | enable | Enable HTTP session multiplexing.
+ required: false
+ choices: ["disable", "enable"]
+
+ http_ip_header_name:
+ description:
+ - For HTTP multiplexing, enter a custom HTTPS header name. The orig client IP address is added to this header.
+ - If empty, X-Forwarded-For is used.
+ required: false
+
+ http_ip_header:
+ description:
+ - For HTTP multiplexing, enable to add the original client IP address in the XForwarded-For HTTP header.
+ - choice | disable | Disable adding HTTP header.
+ - choice | enable | Enable adding HTTP header.
+ required: false
+ choices: ["disable", "enable"]
+
+ http_cookie_share:
+ description:
+ - Control sharing of cookies across virtual servers. same-ip means a cookie from one virtual server can be used
+ - by another. Disable stops cookie sharing.
+ - choice | disable | Only allow HTTP cookie to match this virtual server.
+ - choice | same-ip | Allow HTTP cookie to match any virtual server with same IP.
+ required: false
+ choices: ["disable", "same-ip"]
+
+ http_cookie_path:
+ description:
+ - Limit HTTP cookie persistence to the specified path.
+ required: false
+
+ http_cookie_generation:
+ description:
+ - Generation of HTTP cookie to be accepted. Changing invalidates all existing cookies.
+ required: false
+
+ http_cookie_domain_from_host:
+ description:
+ - Enable/disable use of HTTP cookie domain from host field in HTTP.
+ - choice | disable | Disable use of HTTP cookie domain from host field in HTTP (use http-cooke-domain setting).
+ - choice | enable | Enable use of HTTP cookie domain from host field in HTTP.
+ required: false
+ choices: ["disable", "enable"]
+
+ http_cookie_domain:
+ description:
+ - Domain that HTTP cookie persistence should apply to.
+ required: false
+
+ http_cookie_age:
+ description:
+ - Time in minutes that client web browsers should keep a cookie. Default is 60 seconds. 0 = no time limit.
+ required: false
+
+ gratuitous_arp_interval:
+ description:
+ - Enable to have the VIP send gratuitous ARPs. 0=disabled. Set from 5 up to 8640000 seconds to enable.
+ required: false
+
+ extport:
+ description:
+ - Incoming port number range that you want to map to a port number range on the destination network.
+ required: false
+
+ extip:
+ description:
+ - IP address or address range on the external interface that you want to map to an address or address range on t
+ - he destination network.
+ required: false
+
+ extintf:
+ description:
+ - Interface connected to the source network that receives the packets that will be forwarded to the destination
+ - network.
+ required: false
+
+ extaddr:
+ description:
+ - External FQDN address name.
+ required: false
+
+ dns_mapping_ttl:
+ description:
+ - DNS mapping TTL (Set to zero to use TTL in DNS response, default = 0).
+ required: false
+
+ comment:
+ description:
+ - Comment.
+ required: false
+
+ color:
+ description:
+ - Color of icon on the GUI.
+ required: false
+
+ arp_reply:
+ description:
+ - Enable to respond to ARP requests for this virtual IP address. Enabled by default.
+ - choice | disable | Disable ARP reply.
+ - choice | enable | Enable ARP reply.
+ required: false
+ choices: ["disable", "enable"]
+
+ dynamic_mapping:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ dynamic_mapping_arp_reply:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | disable |
+ - choice | enable |
+ required: false
+ choices: ["disable", "enable"]
+
+ dynamic_mapping_color:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_comment:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_dns_mapping_ttl:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_extaddr:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_extintf:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_extip:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_extport:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_gratuitous_arp_interval:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_http_cookie_age:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_http_cookie_domain:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_http_cookie_domain_from_host:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | disable |
+ - choice | enable |
+ required: false
+ choices: ["disable", "enable"]
+
+ dynamic_mapping_http_cookie_generation:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_http_cookie_path:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_http_cookie_share:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | disable |
+ - choice | same-ip |
+ required: false
+ choices: ["disable", "same-ip"]
+
+ dynamic_mapping_http_ip_header:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | disable |
+ - choice | enable |
+ required: false
+ choices: ["disable", "enable"]
+
+ dynamic_mapping_http_ip_header_name:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_http_multiplex:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | disable |
+ - choice | enable |
+ required: false
+ choices: ["disable", "enable"]
+
+ dynamic_mapping_https_cookie_secure:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | disable |
+ - choice | enable |
+ required: false
+ choices: ["disable", "enable"]
+
+ dynamic_mapping_ldb_method:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | static |
+ - choice | round-robin |
+ - choice | weighted |
+ - choice | least-session |
+ - choice | least-rtt |
+ - choice | first-alive |
+ - choice | http-host |
+ required: false
+ choices: ["static", "round-robin", "weighted", "least-session", "least-rtt", "first-alive", "http-host"]
+
+ dynamic_mapping_mapped_addr:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_mappedip:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_mappedport:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_max_embryonic_connections:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_monitor:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_nat_source_vip:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | disable |
+ - choice | enable |
+ required: false
+ choices: ["disable", "enable"]
+
+ dynamic_mapping_outlook_web_access:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | disable |
+ - choice | enable |
+ required: false
+ choices: ["disable", "enable"]
+
+ dynamic_mapping_persistence:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | none |
+ - choice | http-cookie |
+ - choice | ssl-session-id |
+ required: false
+ choices: ["none", "http-cookie", "ssl-session-id"]
+
+ dynamic_mapping_portforward:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | disable |
+ - choice | enable |
+ required: false
+ choices: ["disable", "enable"]
+
+ dynamic_mapping_portmapping_type:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | 1-to-1 |
+ - choice | m-to-n |
+ required: false
+ choices: ["1-to-1", "m-to-n"]
+
+ dynamic_mapping_protocol:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | tcp |
+ - choice | udp |
+ - choice | sctp |
+ - choice | icmp |
+ required: false
+ choices: ["tcp", "udp", "sctp", "icmp"]
+
+ dynamic_mapping_server_type:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | http |
+ - choice | https |
+ - choice | ssl |
+ - choice | tcp |
+ - choice | udp |
+ - choice | ip |
+ - choice | imaps |
+ - choice | pop3s |
+ - choice | smtps |
+ required: false
+ choices: ["http", "https", "ssl", "tcp", "udp", "ip", "imaps", "pop3s", "smtps"]
+
+ dynamic_mapping_service:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_src_filter:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_srcintf_filter:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_ssl_algorithm:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | high |
+ - choice | medium |
+ - choice | low |
+ - choice | custom |
+ required: false
+ choices: ["high", "medium", "low", "custom"]
+
+ dynamic_mapping_ssl_certificate:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_ssl_client_fallback:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | disable |
+ - choice | enable |
+ required: false
+ choices: ["disable", "enable"]
+
+ dynamic_mapping_ssl_client_renegotiation:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | deny |
+ - choice | allow |
+ - choice | secure |
+ required: false
+ choices: ["deny", "allow", "secure"]
+
+ dynamic_mapping_ssl_client_session_state_max:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_ssl_client_session_state_timeout:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_ssl_client_session_state_type:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | disable |
+ - choice | time |
+ - choice | count |
+ - choice | both |
+ required: false
+ choices: ["disable", "time", "count", "both"]
+
+ dynamic_mapping_ssl_dh_bits:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | 768 |
+ - choice | 1024 |
+ - choice | 1536 |
+ - choice | 2048 |
+ - choice | 3072 |
+ - choice | 4096 |
+ required: false
+ choices: ["768", "1024", "1536", "2048", "3072", "4096"]
+
+ dynamic_mapping_ssl_hpkp:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | disable |
+ - choice | enable |
+ - choice | report-only |
+ required: false
+ choices: ["disable", "enable", "report-only"]
+
+ dynamic_mapping_ssl_hpkp_age:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_ssl_hpkp_backup:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_ssl_hpkp_include_subdomains:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | disable |
+ - choice | enable |
+ required: false
+ choices: ["disable", "enable"]
+
+ dynamic_mapping_ssl_hpkp_primary:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_ssl_hpkp_report_uri:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_ssl_hsts:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | disable |
+ - choice | enable |
+ required: false
+ choices: ["disable", "enable"]
+
+ dynamic_mapping_ssl_hsts_age:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_ssl_hsts_include_subdomains:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | disable |
+ - choice | enable |
+ required: false
+ choices: ["disable", "enable"]
+
+ dynamic_mapping_ssl_http_location_conversion:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | disable |
+ - choice | enable |
+ required: false
+ choices: ["disable", "enable"]
+
+ dynamic_mapping_ssl_http_match_host:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | disable |
+ - choice | enable |
+ required: false
+ choices: ["disable", "enable"]
+
+ dynamic_mapping_ssl_max_version:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | ssl-3.0 |
+ - choice | tls-1.0 |
+ - choice | tls-1.1 |
+ - choice | tls-1.2 |
+ required: false
+ choices: ["ssl-3.0", "tls-1.0", "tls-1.1", "tls-1.2"]
+
+ dynamic_mapping_ssl_min_version:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | ssl-3.0 |
+ - choice | tls-1.0 |
+ - choice | tls-1.1 |
+ - choice | tls-1.2 |
+ required: false
+ choices: ["ssl-3.0", "tls-1.0", "tls-1.1", "tls-1.2"]
+
+ dynamic_mapping_ssl_mode:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | half |
+ - choice | full |
+ required: false
+ choices: ["half", "full"]
+
+ dynamic_mapping_ssl_pfs:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | require |
+ - choice | deny |
+ - choice | allow |
+ required: false
+ choices: ["require", "deny", "allow"]
+
+ dynamic_mapping_ssl_send_empty_frags:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | disable |
+ - choice | enable |
+ required: false
+ choices: ["disable", "enable"]
+
+ dynamic_mapping_ssl_server_algorithm:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | high |
+ - choice | low |
+ - choice | medium |
+ - choice | custom |
+ - choice | client |
+ required: false
+ choices: ["high", "low", "medium", "custom", "client"]
+
+ dynamic_mapping_ssl_server_max_version:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | ssl-3.0 |
+ - choice | tls-1.0 |
+ - choice | tls-1.1 |
+ - choice | tls-1.2 |
+ - choice | client |
+ required: false
+ choices: ["ssl-3.0", "tls-1.0", "tls-1.1", "tls-1.2", "client"]
+
+ dynamic_mapping_ssl_server_min_version:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | ssl-3.0 |
+ - choice | tls-1.0 |
+ - choice | tls-1.1 |
+ - choice | tls-1.2 |
+ - choice | client |
+ required: false
+ choices: ["ssl-3.0", "tls-1.0", "tls-1.1", "tls-1.2", "client"]
+
+ dynamic_mapping_ssl_server_session_state_max:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_ssl_server_session_state_timeout:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_ssl_server_session_state_type:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | disable |
+ - choice | time |
+ - choice | count |
+ - choice | both |
+ required: false
+ choices: ["disable", "time", "count", "both"]
+
+ dynamic_mapping_type:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | static-nat |
+ - choice | load-balance |
+ - choice | server-load-balance |
+ - choice | dns-translation |
+ - choice | fqdn |
+ required: false
+ choices: ["static-nat", "load-balance", "server-load-balance", "dns-translation", "fqdn"]
+
+ dynamic_mapping_weblogic_server:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | disable |
+ - choice | enable |
+ required: false
+ choices: ["disable", "enable"]
+
+ dynamic_mapping_websphere_server:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | disable |
+ - choice | enable |
+ required: false
+ choices: ["disable", "enable"]
+
+ dynamic_mapping_realservers_client_ip:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_realservers_healthcheck:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | disable |
+ - choice | enable |
+ - choice | vip |
+ required: false
+ choices: ["disable", "enable", "vip"]
+
+ dynamic_mapping_realservers_holddown_interval:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_realservers_http_host:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_realservers_ip:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_realservers_max_connections:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_realservers_monitor:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_realservers_port:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_realservers_seq:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_realservers_status:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | active |
+ - choice | standby |
+ - choice | disable |
+ required: false
+ choices: ["active", "standby", "disable"]
+
+ dynamic_mapping_realservers_weight:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ required: false
+
+ dynamic_mapping_ssl_cipher_suites_cipher:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - choice | TLS-RSA-WITH-RC4-128-MD5 |
+ - choice | TLS-RSA-WITH-RC4-128-SHA |
+ - choice | TLS-RSA-WITH-DES-CBC-SHA |
+ - choice | TLS-RSA-WITH-3DES-EDE-CBC-SHA |
+ - choice | TLS-RSA-WITH-AES-128-CBC-SHA |
+ - choice | TLS-RSA-WITH-AES-256-CBC-SHA |
+ - choice | TLS-RSA-WITH-AES-128-CBC-SHA256 |
+ - choice | TLS-RSA-WITH-AES-256-CBC-SHA256 |
+ - choice | TLS-RSA-WITH-CAMELLIA-128-CBC-SHA |
+ - choice | TLS-RSA-WITH-CAMELLIA-256-CBC-SHA |
+ - choice | TLS-RSA-WITH-CAMELLIA-128-CBC-SHA256 |
+ - choice | TLS-RSA-WITH-CAMELLIA-256-CBC-SHA256 |
+ - choice | TLS-RSA-WITH-SEED-CBC-SHA |
+ - choice | TLS-RSA-WITH-ARIA-128-CBC-SHA256 |
+ - choice | TLS-RSA-WITH-ARIA-256-CBC-SHA384 |
+ - choice | TLS-DHE-RSA-WITH-DES-CBC-SHA |
+ - choice | TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA |
+ - choice | TLS-DHE-RSA-WITH-AES-128-CBC-SHA |
+ - choice | TLS-DHE-RSA-WITH-AES-256-CBC-SHA |
+ - choice | TLS-DHE-RSA-WITH-AES-128-CBC-SHA256 |
+ - choice | TLS-DHE-RSA-WITH-AES-256-CBC-SHA256 |
+ - choice | TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA |
+ - choice | TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA |
+ - choice | TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA256 |
+ - choice | TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA256 |
+ - choice | TLS-DHE-RSA-WITH-SEED-CBC-SHA |
+ - choice | TLS-DHE-RSA-WITH-ARIA-128-CBC-SHA256 |
+ - choice | TLS-DHE-RSA-WITH-ARIA-256-CBC-SHA384 |
+ - choice | TLS-ECDHE-RSA-WITH-RC4-128-SHA |
+ - choice | TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA |
+ - choice | TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA |
+ - choice | TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA |
+ - choice | TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256 |
+ - choice | TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256 |
+ - choice | TLS-DHE-RSA-WITH-CHACHA20-POLY1305-SHA256 |
+ - choice | TLS-DHE-RSA-WITH-AES-128-GCM-SHA256 |
+ - choice | TLS-DHE-RSA-WITH-AES-256-GCM-SHA384 |
+ - choice | TLS-DHE-DSS-WITH-AES-128-CBC-SHA |
+ - choice | TLS-DHE-DSS-WITH-AES-256-CBC-SHA |
+ - choice | TLS-DHE-DSS-WITH-AES-128-CBC-SHA256 |
+ - choice | TLS-DHE-DSS-WITH-AES-128-GCM-SHA256 |
+ - choice | TLS-DHE-DSS-WITH-AES-256-CBC-SHA256 |
+ - choice | TLS-DHE-DSS-WITH-AES-256-GCM-SHA384 |
+ - choice | TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256 |
+ - choice | TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256 |
+ - choice | TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384 |
+ - choice | TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384 |
+ - choice | TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA |
+ - choice | TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256 |
+ - choice | TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 |
+ - choice | TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384 |
+ - choice | TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384 |
+ - choice | TLS-RSA-WITH-AES-128-GCM-SHA256 |
+ - choice | TLS-RSA-WITH-AES-256-GCM-SHA384 |
+ - choice | TLS-DHE-DSS-WITH-CAMELLIA-128-CBC-SHA |
+ - choice | TLS-DHE-DSS-WITH-CAMELLIA-256-CBC-SHA |
+ - choice | TLS-DHE-DSS-WITH-CAMELLIA-128-CBC-SHA256 |
+ - choice | TLS-DHE-DSS-WITH-CAMELLIA-256-CBC-SHA256 |
+ - choice | TLS-DHE-DSS-WITH-SEED-CBC-SHA |
+ - choice | TLS-DHE-DSS-WITH-ARIA-128-CBC-SHA256 |
+ - choice | TLS-DHE-DSS-WITH-ARIA-256-CBC-SHA384 |
+ - choice | TLS-ECDHE-RSA-WITH-ARIA-128-CBC-SHA256 |
+ - choice | TLS-ECDHE-RSA-WITH-ARIA-256-CBC-SHA384 |
+ - choice | TLS-ECDHE-ECDSA-WITH-ARIA-128-CBC-SHA256 |
+ - choice | TLS-ECDHE-ECDSA-WITH-ARIA-256-CBC-SHA384 |
+ - choice | TLS-DHE-DSS-WITH-3DES-EDE-CBC-SHA |
+ - choice | TLS-DHE-DSS-WITH-DES-CBC-SHA |
+ required: false
+ choices: ["TLS-RSA-WITH-RC4-128-MD5",
+ "TLS-RSA-WITH-RC4-128-SHA",
+ "TLS-RSA-WITH-DES-CBC-SHA",
+ "TLS-RSA-WITH-3DES-EDE-CBC-SHA",
+ "TLS-RSA-WITH-AES-128-CBC-SHA",
+ "TLS-RSA-WITH-AES-256-CBC-SHA",
+ "TLS-RSA-WITH-AES-128-CBC-SHA256",
+ "TLS-RSA-WITH-AES-256-CBC-SHA256",
+ "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA",
+ "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA",
+ "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA256",
+ "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA256",
+ "TLS-RSA-WITH-SEED-CBC-SHA",
+ "TLS-RSA-WITH-ARIA-128-CBC-SHA256",
+ "TLS-RSA-WITH-ARIA-256-CBC-SHA384",
+ "TLS-DHE-RSA-WITH-DES-CBC-SHA",
+ "TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA",
+ "TLS-DHE-RSA-WITH-AES-128-CBC-SHA",
+ "TLS-DHE-RSA-WITH-AES-256-CBC-SHA",
+ "TLS-DHE-RSA-WITH-AES-128-CBC-SHA256",
+ "TLS-DHE-RSA-WITH-AES-256-CBC-SHA256",
+ "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA",
+ "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA",
+ "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA256",
+ "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA256",
+ "TLS-DHE-RSA-WITH-SEED-CBC-SHA",
+ "TLS-DHE-RSA-WITH-ARIA-128-CBC-SHA256",
+ "TLS-DHE-RSA-WITH-ARIA-256-CBC-SHA384",
+ "TLS-ECDHE-RSA-WITH-RC4-128-SHA",
+ "TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA",
+ "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA",
+ "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA",
+ "TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256",
+ "TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256",
+ "TLS-DHE-RSA-WITH-CHACHA20-POLY1305-SHA256",
+ "TLS-DHE-RSA-WITH-AES-128-GCM-SHA256",
+ "TLS-DHE-RSA-WITH-AES-256-GCM-SHA384",
+ "TLS-DHE-DSS-WITH-AES-128-CBC-SHA",
+ "TLS-DHE-DSS-WITH-AES-256-CBC-SHA",
+ "TLS-DHE-DSS-WITH-AES-128-CBC-SHA256",
+ "TLS-DHE-DSS-WITH-AES-128-GCM-SHA256",
+ "TLS-DHE-DSS-WITH-AES-256-CBC-SHA256",
+ "TLS-DHE-DSS-WITH-AES-256-GCM-SHA384",
+ "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256",
+ "TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256",
+ "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384",
+ "TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384",
+ "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA",
+ "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256",
+ "TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256",
+ "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384",
+ "TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384",
+ "TLS-RSA-WITH-AES-128-GCM-SHA256",
+ "TLS-RSA-WITH-AES-256-GCM-SHA384",
+ "TLS-DHE-DSS-WITH-CAMELLIA-128-CBC-SHA",
+ "TLS-DHE-DSS-WITH-CAMELLIA-256-CBC-SHA",
+ "TLS-DHE-DSS-WITH-CAMELLIA-128-CBC-SHA256",
+ "TLS-DHE-DSS-WITH-CAMELLIA-256-CBC-SHA256",
+ "TLS-DHE-DSS-WITH-SEED-CBC-SHA",
+ "TLS-DHE-DSS-WITH-ARIA-128-CBC-SHA256",
+ "TLS-DHE-DSS-WITH-ARIA-256-CBC-SHA384",
+ "TLS-ECDHE-RSA-WITH-ARIA-128-CBC-SHA256",
+ "TLS-ECDHE-RSA-WITH-ARIA-256-CBC-SHA384",
+ "TLS-ECDHE-ECDSA-WITH-ARIA-128-CBC-SHA256",
+ "TLS-ECDHE-ECDSA-WITH-ARIA-256-CBC-SHA384",
+ "TLS-DHE-DSS-WITH-3DES-EDE-CBC-SHA",
+ "TLS-DHE-DSS-WITH-DES-CBC-SHA"]
+
+ dynamic_mapping_ssl_cipher_suites_versions:
+ description:
+ - Dynamic Mapping Version of Suffixed Option Name. Sub-Table. Same Descriptions as Parent.
+ - FLAG Based Options. Specify multiple in list form.
+ - flag | ssl-3.0 |
+ - flag | tls-1.0 |
+ - flag | tls-1.1 |
+ - flag | tls-1.2 |
+ required: false
+ choices: ["ssl-3.0", "tls-1.0", "tls-1.1", "tls-1.2"]
+
+ realservers:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ realservers_client_ip:
+ description:
+ - Only clients in this IP range can connect to this real server.
+ required: false
+
+ realservers_healthcheck:
+ description:
+ - Enable to check the responsiveness of the real server before forwarding traffic.
+ - choice | disable | Disable per server health check.
+ - choice | enable | Enable per server health check.
+ - choice | vip | Use health check defined in VIP.
+ required: false
+ choices: ["disable", "enable", "vip"]
+
+ realservers_holddown_interval:
+ description:
+ - Time in seconds that the health check monitor monitors an unresponsive server that should be active.
+ required: false
+
+ realservers_http_host:
+ description:
+ - HTTP server domain name in HTTP header.
+ required: false
+
+ realservers_ip:
+ description:
+ - IP address of the real server.
+ required: false
+
+ realservers_max_connections:
+ description:
+ - Max number of active connections that can be directed to the real server. When reached, sessions are sent to
+ - their real servers.
+ required: false
+
+ realservers_monitor:
+ description:
+ - Name of the health check monitor to use when polling to determine a virtual server's connectivity status.
+ required: false
+
+ realservers_port:
+ description:
+ - Port for communicating with the real server. Required if port forwarding is enabled.
+ required: false
+
+ realservers_seq:
+ description:
+ - Real Server Sequence Number
+ required: false
+
+ realservers_status:
+ description:
+ - Set the status of the real server to active so that it can accept traffic.
+ - Or on standby or disabled so no traffic is sent.
+ - choice | active | Server status active.
+ - choice | standby | Server status standby.
+ - choice | disable | Server status disable.
+ required: false
+ choices: ["active", "standby", "disable"]
+
+ realservers_weight:
+ description:
+ - Weight of the real server. If weighted load balancing is enabled, the server with the highest weight gets more
+ - connections.
+ required: false
+
+ ssl_cipher_suites:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ ssl_cipher_suites_cipher:
+ description:
+ - Cipher suite name.
+ - choice | TLS-RSA-WITH-RC4-128-MD5 | Cipher suite TLS-RSA-WITH-RC4-128-MD5.
+ - choice | TLS-RSA-WITH-RC4-128-SHA | Cipher suite TLS-RSA-WITH-RC4-128-SHA.
+ - choice | TLS-RSA-WITH-DES-CBC-SHA | Cipher suite TLS-RSA-WITH-DES-CBC-SHA.
+ - choice | TLS-RSA-WITH-3DES-EDE-CBC-SHA | Cipher suite TLS-RSA-WITH-3DES-EDE-CBC-SHA.
+ - choice | TLS-RSA-WITH-AES-128-CBC-SHA | Cipher suite TLS-RSA-WITH-AES-128-CBC-SHA.
+ - choice | TLS-RSA-WITH-AES-256-CBC-SHA | Cipher suite TLS-RSA-WITH-AES-256-CBC-SHA.
+ - choice | TLS-RSA-WITH-AES-128-CBC-SHA256 | Cipher suite TLS-RSA-WITH-AES-128-CBC-SHA256.
+ - choice | TLS-RSA-WITH-AES-256-CBC-SHA256 | Cipher suite TLS-RSA-WITH-AES-256-CBC-SHA256.
+ - choice | TLS-RSA-WITH-CAMELLIA-128-CBC-SHA | Cipher suite TLS-RSA-WITH-CAMELLIA-128-CBC-SHA.
+ - choice | TLS-RSA-WITH-CAMELLIA-256-CBC-SHA | Cipher suite TLS-RSA-WITH-CAMELLIA-256-CBC-SHA.
+ - choice | TLS-RSA-WITH-CAMELLIA-128-CBC-SHA256 | Cipher suite TLS-RSA-WITH-CAMELLIA-128-CBC-SHA256.
+ - choice | TLS-RSA-WITH-CAMELLIA-256-CBC-SHA256 | Cipher suite TLS-RSA-WITH-CAMELLIA-256-CBC-SHA256.
+ - choice | TLS-RSA-WITH-SEED-CBC-SHA | Cipher suite TLS-RSA-WITH-SEED-CBC-SHA.
+ - choice | TLS-RSA-WITH-ARIA-128-CBC-SHA256 | Cipher suite TLS-RSA-WITH-ARIA-128-CBC-SHA256.
+ - choice | TLS-RSA-WITH-ARIA-256-CBC-SHA384 | Cipher suite TLS-RSA-WITH-ARIA-256-CBC-SHA384.
+ - choice | TLS-DHE-RSA-WITH-DES-CBC-SHA | Cipher suite TLS-DHE-RSA-WITH-DES-CBC-SHA.
+ - choice | TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA | Cipher suite TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA.
+ - choice | TLS-DHE-RSA-WITH-AES-128-CBC-SHA | Cipher suite TLS-DHE-RSA-WITH-AES-128-CBC-SHA.
+ - choice | TLS-DHE-RSA-WITH-AES-256-CBC-SHA | Cipher suite TLS-DHE-RSA-WITH-AES-256-CBC-SHA.
+ - choice | TLS-DHE-RSA-WITH-AES-128-CBC-SHA256 | Cipher suite TLS-DHE-RSA-WITH-AES-128-CBC-SHA256.
+ - choice | TLS-DHE-RSA-WITH-AES-256-CBC-SHA256 | Cipher suite TLS-DHE-RSA-WITH-AES-256-CBC-SHA256.
+ - choice | TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA | Cipher suite TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA.
+ - choice | TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA | Cipher suite TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA.
+ - choice | TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA256 | Cipher suite TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA256.
+ - choice | TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA256 | Cipher suite TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA256.
+ - choice | TLS-DHE-RSA-WITH-SEED-CBC-SHA | Cipher suite TLS-DHE-RSA-WITH-SEED-CBC-SHA.
+ - choice | TLS-DHE-RSA-WITH-ARIA-128-CBC-SHA256 | Cipher suite TLS-DHE-RSA-WITH-ARIA-128-CBC-SHA256.
+ - choice | TLS-DHE-RSA-WITH-ARIA-256-CBC-SHA384 | Cipher suite TLS-DHE-RSA-WITH-ARIA-256-CBC-SHA384.
+ - choice | TLS-ECDHE-RSA-WITH-RC4-128-SHA | Cipher suite TLS-ECDHE-RSA-WITH-RC4-128-SHA.
+ - choice | TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA | Cipher suite TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA.
+ - choice | TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA | Cipher suite TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA.
+ - choice | TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA | Cipher suite TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA.
+ - choice | TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256 | Cipher suite TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256.
+ - choice | TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256 | Cipher suite TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256.
+ - choice | TLS-DHE-RSA-WITH-CHACHA20-POLY1305-SHA256 | Cipher suite TLS-DHE-RSA-WITH-CHACHA20-POLY1305-SHA256.
+ - choice | TLS-DHE-RSA-WITH-AES-128-GCM-SHA256 | Cipher suite TLS-DHE-RSA-WITH-AES-128-GCM-SHA256.
+ - choice | TLS-DHE-RSA-WITH-AES-256-GCM-SHA384 | Cipher suite TLS-DHE-RSA-WITH-AES-256-GCM-SHA384.
+ - choice | TLS-DHE-DSS-WITH-AES-128-CBC-SHA | Cipher suite TLS-DHE-DSS-WITH-AES-128-CBC-SHA.
+ - choice | TLS-DHE-DSS-WITH-AES-256-CBC-SHA | Cipher suite TLS-DHE-DSS-WITH-AES-256-CBC-SHA.
+ - choice | TLS-DHE-DSS-WITH-AES-128-CBC-SHA256 | Cipher suite TLS-DHE-DSS-WITH-AES-128-CBC-SHA256.
+ - choice | TLS-DHE-DSS-WITH-AES-128-GCM-SHA256 | Cipher suite TLS-DHE-DSS-WITH-AES-128-GCM-SHA256.
+ - choice | TLS-DHE-DSS-WITH-AES-256-CBC-SHA256 | Cipher suite TLS-DHE-DSS-WITH-AES-256-CBC-SHA256.
+ - choice | TLS-DHE-DSS-WITH-AES-256-GCM-SHA384 | Cipher suite TLS-DHE-DSS-WITH-AES-256-GCM-SHA384.
+ - choice | TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256 | Cipher suite TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256.
+ - choice | TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256 | Cipher suite TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256.
+ - choice | TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384 | Cipher suite TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384.
+ - choice | TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384 | Cipher suite TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384.
+ - choice | TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA | Cipher suite TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA.
+ - choice | TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256 | Cipher suite TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256.
+ - choice | TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 | Cipher suite TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256.
+ - choice | TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384 | Cipher suite TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384.
+ - choice | TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384 | Cipher suite TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384.
+ - choice | TLS-RSA-WITH-AES-128-GCM-SHA256 | Cipher suite TLS-RSA-WITH-AES-128-GCM-SHA256.
+ - choice | TLS-RSA-WITH-AES-256-GCM-SHA384 | Cipher suite TLS-RSA-WITH-AES-256-GCM-SHA384.
+ - choice | TLS-DHE-DSS-WITH-CAMELLIA-128-CBC-SHA | Cipher suite TLS-DSS-RSA-WITH-CAMELLIA-128-CBC-SHA.
+ - choice | TLS-DHE-DSS-WITH-CAMELLIA-256-CBC-SHA | Cipher suite TLS-DHE-DSS-WITH-CAMELLIA-256-CBC-SHA.
+ - choice | TLS-DHE-DSS-WITH-CAMELLIA-128-CBC-SHA256 | Cipher suite TLS-DHE-DSS-WITH-CAMELLIA-128-CBC-SHA256.
+ - choice | TLS-DHE-DSS-WITH-CAMELLIA-256-CBC-SHA256 | Cipher suite TLS-DHE-DSS-WITH-CAMELLIA-256-CBC-SHA256.
+ - choice | TLS-DHE-DSS-WITH-SEED-CBC-SHA | Cipher suite TLS-DHE-DSS-WITH-SEED-CBC-SHA.
+ - choice | TLS-DHE-DSS-WITH-ARIA-128-CBC-SHA256 | Cipher suite TLS-DHE-DSS-WITH-ARIA-128-CBC-SHA256.
+ - choice | TLS-DHE-DSS-WITH-ARIA-256-CBC-SHA384 | Cipher suite TLS-DHE-DSS-WITH-ARIA-256-CBC-SHA384.
+ - choice | TLS-ECDHE-RSA-WITH-ARIA-128-CBC-SHA256 | Cipher suite TLS-ECDHE-RSA-WITH-ARIA-128-CBC-SHA256.
+ - choice | TLS-ECDHE-RSA-WITH-ARIA-256-CBC-SHA384 | Cipher suite TLS-ECDHE-RSA-WITH-ARIA-256-CBC-SHA384.
+ - choice | TLS-ECDHE-ECDSA-WITH-ARIA-128-CBC-SHA256 | Cipher suite TLS-ECDHE-ECDSA-WITH-ARIA-128-CBC_SHA256.
+ - choice | TLS-ECDHE-ECDSA-WITH-ARIA-256-CBC-SHA384 | Cipher suite TLS-ECDHE-ECDSA-WITH-ARIA-256-CBC_SHA384.
+ - choice | TLS-DHE-DSS-WITH-3DES-EDE-CBC-SHA | Cipher suite TLS-DHE-DSS-WITH-3DES-EDE-CBC-SHA.
+ - choice | TLS-DHE-DSS-WITH-DES-CBC-SHA | Cipher suite TLS-DHE-DSS-WITH-DES-CBC-SHA.
+ required: false
+ choices: ["TLS-RSA-WITH-RC4-128-MD5",
+ "TLS-RSA-WITH-RC4-128-SHA",
+ "TLS-RSA-WITH-DES-CBC-SHA",
+ "TLS-RSA-WITH-3DES-EDE-CBC-SHA",
+ "TLS-RSA-WITH-AES-128-CBC-SHA",
+ "TLS-RSA-WITH-AES-256-CBC-SHA",
+ "TLS-RSA-WITH-AES-128-CBC-SHA256",
+ "TLS-RSA-WITH-AES-256-CBC-SHA256",
+ "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA",
+ "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA",
+ "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA256",
+ "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA256",
+ "TLS-RSA-WITH-SEED-CBC-SHA",
+ "TLS-RSA-WITH-ARIA-128-CBC-SHA256",
+ "TLS-RSA-WITH-ARIA-256-CBC-SHA384",
+ "TLS-DHE-RSA-WITH-DES-CBC-SHA",
+ "TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA",
+ "TLS-DHE-RSA-WITH-AES-128-CBC-SHA",
+ "TLS-DHE-RSA-WITH-AES-256-CBC-SHA",
+ "TLS-DHE-RSA-WITH-AES-128-CBC-SHA256",
+ "TLS-DHE-RSA-WITH-AES-256-CBC-SHA256",
+ "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA",
+ "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA",
+ "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA256",
+ "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA256",
+ "TLS-DHE-RSA-WITH-SEED-CBC-SHA",
+ "TLS-DHE-RSA-WITH-ARIA-128-CBC-SHA256",
+ "TLS-DHE-RSA-WITH-ARIA-256-CBC-SHA384",
+ "TLS-ECDHE-RSA-WITH-RC4-128-SHA",
+ "TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA",
+ "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA",
+ "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA",
+ "TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256",
+ "TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256",
+ "TLS-DHE-RSA-WITH-CHACHA20-POLY1305-SHA256",
+ "TLS-DHE-RSA-WITH-AES-128-GCM-SHA256",
+ "TLS-DHE-RSA-WITH-AES-256-GCM-SHA384",
+ "TLS-DHE-DSS-WITH-AES-128-CBC-SHA",
+ "TLS-DHE-DSS-WITH-AES-256-CBC-SHA",
+ "TLS-DHE-DSS-WITH-AES-128-CBC-SHA256",
+ "TLS-DHE-DSS-WITH-AES-128-GCM-SHA256",
+ "TLS-DHE-DSS-WITH-AES-256-CBC-SHA256",
+ "TLS-DHE-DSS-WITH-AES-256-GCM-SHA384",
+ "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256",
+ "TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256",
+ "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384",
+ "TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384",
+ "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA",
+ "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256",
+ "TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256",
+ "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384",
+ "TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384",
+ "TLS-RSA-WITH-AES-128-GCM-SHA256",
+ "TLS-RSA-WITH-AES-256-GCM-SHA384",
+ "TLS-DHE-DSS-WITH-CAMELLIA-128-CBC-SHA",
+ "TLS-DHE-DSS-WITH-CAMELLIA-256-CBC-SHA",
+ "TLS-DHE-DSS-WITH-CAMELLIA-128-CBC-SHA256",
+ "TLS-DHE-DSS-WITH-CAMELLIA-256-CBC-SHA256",
+ "TLS-DHE-DSS-WITH-SEED-CBC-SHA",
+ "TLS-DHE-DSS-WITH-ARIA-128-CBC-SHA256",
+ "TLS-DHE-DSS-WITH-ARIA-256-CBC-SHA384",
+ "TLS-ECDHE-RSA-WITH-ARIA-128-CBC-SHA256",
+ "TLS-ECDHE-RSA-WITH-ARIA-256-CBC-SHA384",
+ "TLS-ECDHE-ECDSA-WITH-ARIA-128-CBC-SHA256",
+ "TLS-ECDHE-ECDSA-WITH-ARIA-256-CBC-SHA384",
+ "TLS-DHE-DSS-WITH-3DES-EDE-CBC-SHA",
+ "TLS-DHE-DSS-WITH-DES-CBC-SHA"]
+
+ ssl_cipher_suites_versions:
+ description:
+ - SSL/TLS versions that the cipher suite can be used with.
+ - FLAG Based Options. Specify multiple in list form.
+ - flag | ssl-3.0 | SSL 3.0.
+ - flag | tls-1.0 | TLS 1.0.
+ - flag | tls-1.1 | TLS 1.1.
+ - flag | tls-1.2 | TLS 1.2.
+ required: false
+ choices: ["ssl-3.0", "tls-1.0", "tls-1.1", "tls-1.2"]
+
+ ssl_server_cipher_suites:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ ssl_server_cipher_suites_cipher:
+ description:
+ - Cipher suite name.
+ - choice | TLS-RSA-WITH-RC4-128-MD5 | Cipher suite TLS-RSA-WITH-RC4-128-MD5.
+ - choice | TLS-RSA-WITH-RC4-128-SHA | Cipher suite TLS-RSA-WITH-RC4-128-SHA.
+ - choice | TLS-RSA-WITH-DES-CBC-SHA | Cipher suite TLS-RSA-WITH-DES-CBC-SHA.
+ - choice | TLS-RSA-WITH-3DES-EDE-CBC-SHA | Cipher suite TLS-RSA-WITH-3DES-EDE-CBC-SHA.
+ - choice | TLS-RSA-WITH-AES-128-CBC-SHA | Cipher suite TLS-RSA-WITH-AES-128-CBC-SHA.
+ - choice | TLS-RSA-WITH-AES-256-CBC-SHA | Cipher suite TLS-RSA-WITH-AES-256-CBC-SHA.
+ - choice | TLS-RSA-WITH-AES-128-CBC-SHA256 | Cipher suite TLS-RSA-WITH-AES-128-CBC-SHA256.
+ - choice | TLS-RSA-WITH-AES-256-CBC-SHA256 | Cipher suite TLS-RSA-WITH-AES-256-CBC-SHA256.
+ - choice | TLS-RSA-WITH-CAMELLIA-128-CBC-SHA | Cipher suite TLS-RSA-WITH-CAMELLIA-128-CBC-SHA.
+ - choice | TLS-RSA-WITH-CAMELLIA-256-CBC-SHA | Cipher suite TLS-RSA-WITH-CAMELLIA-256-CBC-SHA.
+ - choice | TLS-RSA-WITH-CAMELLIA-128-CBC-SHA256 | Cipher suite TLS-RSA-WITH-CAMELLIA-128-CBC-SHA256.
+ - choice | TLS-RSA-WITH-CAMELLIA-256-CBC-SHA256 | Cipher suite TLS-RSA-WITH-CAMELLIA-256-CBC-SHA256.
+ - choice | TLS-RSA-WITH-SEED-CBC-SHA | Cipher suite TLS-RSA-WITH-SEED-CBC-SHA.
+ - choice | TLS-RSA-WITH-ARIA-128-CBC-SHA256 | Cipher suite TLS-RSA-WITH-ARIA-128-CBC-SHA256.
+ - choice | TLS-RSA-WITH-ARIA-256-CBC-SHA384 | Cipher suite TLS-RSA-WITH-ARIA-256-CBC-SHA384.
+ - choice | TLS-DHE-RSA-WITH-DES-CBC-SHA | Cipher suite TLS-DHE-RSA-WITH-DES-CBC-SHA.
+ - choice | TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA | Cipher suite TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA.
+ - choice | TLS-DHE-RSA-WITH-AES-128-CBC-SHA | Cipher suite TLS-DHE-RSA-WITH-AES-128-CBC-SHA.
+ - choice | TLS-DHE-RSA-WITH-AES-256-CBC-SHA | Cipher suite TLS-DHE-RSA-WITH-AES-256-CBC-SHA.
+ - choice | TLS-DHE-RSA-WITH-AES-128-CBC-SHA256 | Cipher suite TLS-DHE-RSA-WITH-AES-128-CBC-SHA256.
+ - choice | TLS-DHE-RSA-WITH-AES-256-CBC-SHA256 | Cipher suite TLS-DHE-RSA-WITH-AES-256-CBC-SHA256.
+ - choice | TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA | Cipher suite TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA.
+ - choice | TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA | Cipher suite TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA.
+ - choice | TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA256 | Cipher suite TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA256.
+ - choice | TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA256 | Cipher suite TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA256.
+ - choice | TLS-DHE-RSA-WITH-SEED-CBC-SHA | Cipher suite TLS-DHE-RSA-WITH-SEED-CBC-SHA.
+ - choice | TLS-DHE-RSA-WITH-ARIA-128-CBC-SHA256 | Cipher suite TLS-DHE-RSA-WITH-ARIA-128-CBC-SHA256.
+ - choice | TLS-DHE-RSA-WITH-ARIA-256-CBC-SHA384 | Cipher suite TLS-DHE-RSA-WITH-ARIA-256-CBC-SHA384.
+ - choice | TLS-ECDHE-RSA-WITH-RC4-128-SHA | Cipher suite TLS-ECDHE-RSA-WITH-RC4-128-SHA.
+ - choice | TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA | Cipher suite TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA.
+ - choice | TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA | Cipher suite TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA.
+ - choice | TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA | Cipher suite TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA.
+ - choice | TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256 | Cipher suite TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256.
+ - choice | TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256 | Suite TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256.
+ - choice | TLS-DHE-RSA-WITH-CHACHA20-POLY1305-SHA256 | Cipher suite TLS-DHE-RSA-WITH-CHACHA20-POLY1305-SHA256.
+ - choice | TLS-DHE-RSA-WITH-AES-128-GCM-SHA256 | Cipher suite TLS-DHE-RSA-WITH-AES-128-GCM-SHA256.
+ - choice | TLS-DHE-RSA-WITH-AES-256-GCM-SHA384 | Cipher suite TLS-DHE-RSA-WITH-AES-256-GCM-SHA384.
+ - choice | TLS-DHE-DSS-WITH-AES-128-CBC-SHA | Cipher suite TLS-DHE-DSS-WITH-AES-128-CBC-SHA.
+ - choice | TLS-DHE-DSS-WITH-AES-256-CBC-SHA | Cipher suite TLS-DHE-DSS-WITH-AES-256-CBC-SHA.
+ - choice | TLS-DHE-DSS-WITH-AES-128-CBC-SHA256 | Cipher suite TLS-DHE-DSS-WITH-AES-128-CBC-SHA256.
+ - choice | TLS-DHE-DSS-WITH-AES-128-GCM-SHA256 | Cipher suite TLS-DHE-DSS-WITH-AES-128-GCM-SHA256.
+ - choice | TLS-DHE-DSS-WITH-AES-256-CBC-SHA256 | Cipher suite TLS-DHE-DSS-WITH-AES-256-CBC-SHA256.
+ - choice | TLS-DHE-DSS-WITH-AES-256-GCM-SHA384 | Cipher suite TLS-DHE-DSS-WITH-AES-256-GCM-SHA384.
+ - choice | TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256 | Cipher suite TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256.
+ - choice | TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256 | Cipher suite TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256.
+ - choice | TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384 | Cipher suite TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384.
+ - choice | TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384 | Cipher suite TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384.
+ - choice | TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA | Cipher suite TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA.
+ - choice | TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256 | Cipher suite TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256.
+ - choice | TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256 | Cipher suite TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256.
+ - choice | TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384 | Cipher suite TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384.
+ - choice | TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384 | Cipher suite TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384.
+ - choice | TLS-RSA-WITH-AES-128-GCM-SHA256 | Cipher suite TLS-RSA-WITH-AES-128-GCM-SHA256.
+ - choice | TLS-RSA-WITH-AES-256-GCM-SHA384 | Cipher suite TLS-RSA-WITH-AES-256-GCM-SHA384.
+ - choice | TLS-DHE-DSS-WITH-CAMELLIA-128-CBC-SHA | Cipher suite TLS-DSS-RSA-WITH-CAMELLIA-128-CBC-SHA.
+ - choice | TLS-DHE-DSS-WITH-CAMELLIA-256-CBC-SHA | Cipher suite TLS-DHE-DSS-WITH-CAMELLIA-256-CBC-SHA.
+ - choice | TLS-DHE-DSS-WITH-CAMELLIA-128-CBC-SHA256 | Cipher suite TLS-DHE-DSS-WITH-CAMELLIA-128-CBC-SHA256.
+ - choice | TLS-DHE-DSS-WITH-CAMELLIA-256-CBC-SHA256 | Cipher suite TLS-DHE-DSS-WITH-CAMELLIA-256-CBC-SHA256.
+ - choice | TLS-DHE-DSS-WITH-SEED-CBC-SHA | Cipher suite TLS-DHE-DSS-WITH-SEED-CBC-SHA.
+ - choice | TLS-DHE-DSS-WITH-ARIA-128-CBC-SHA256 | Cipher suite TLS-DHE-DSS-WITH-ARIA-128-CBC-SHA256.
+ - choice | TLS-DHE-DSS-WITH-ARIA-256-CBC-SHA384 | Cipher suite TLS-DHE-DSS-WITH-ARIA-256-CBC-SHA384.
+ - choice | TLS-ECDHE-RSA-WITH-ARIA-128-CBC-SHA256 | Cipher suite TLS-ECDHE-RSA-WITH-ARIA-128-CBC-SHA256.
+ - choice | TLS-ECDHE-RSA-WITH-ARIA-256-CBC-SHA384 | Cipher suite TLS-ECDHE-RSA-WITH-ARIA-256-CBC-SHA384.
+ - choice | TLS-ECDHE-ECDSA-WITH-ARIA-128-CBC-SHA256 | Cipher suite TLS-ECDHE-ECDSA-WITH-ARIA-128-CBC_SHA256.
+ - choice | TLS-ECDHE-ECDSA-WITH-ARIA-256-CBC-SHA384 | Cipher suite TLS-ECDHE-ECDSA-WITH-ARIA-256-CBC_SHA384.
+ - choice | TLS-DHE-DSS-WITH-3DES-EDE-CBC-SHA | Cipher suite TLS-DHE-DSS-WITH-3DES-EDE-CBC-SHA.
+ - choice | TLS-DHE-DSS-WITH-DES-CBC-SHA | Cipher suite TLS-DHE-DSS-WITH-DES-CBC-SHA.
+ required: false
+ choices: ["TLS-RSA-WITH-RC4-128-MD5",
+ "TLS-RSA-WITH-RC4-128-SHA",
+ "TLS-RSA-WITH-DES-CBC-SHA",
+ "TLS-RSA-WITH-3DES-EDE-CBC-SHA",
+ "TLS-RSA-WITH-AES-128-CBC-SHA",
+ "TLS-RSA-WITH-AES-256-CBC-SHA",
+ "TLS-RSA-WITH-AES-128-CBC-SHA256",
+ "TLS-RSA-WITH-AES-256-CBC-SHA256",
+ "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA",
+ "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA",
+ "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA256",
+ "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA256",
+ "TLS-RSA-WITH-SEED-CBC-SHA",
+ "TLS-RSA-WITH-ARIA-128-CBC-SHA256",
+ "TLS-RSA-WITH-ARIA-256-CBC-SHA384",
+ "TLS-DHE-RSA-WITH-DES-CBC-SHA",
+ "TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA",
+ "TLS-DHE-RSA-WITH-AES-128-CBC-SHA",
+ "TLS-DHE-RSA-WITH-AES-256-CBC-SHA",
+ "TLS-DHE-RSA-WITH-AES-128-CBC-SHA256",
+ "TLS-DHE-RSA-WITH-AES-256-CBC-SHA256",
+ "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA",
+ "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA",
+ "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA256",
+ "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA256",
+ "TLS-DHE-RSA-WITH-SEED-CBC-SHA",
+ "TLS-DHE-RSA-WITH-ARIA-128-CBC-SHA256",
+ "TLS-DHE-RSA-WITH-ARIA-256-CBC-SHA384",
+ "TLS-ECDHE-RSA-WITH-RC4-128-SHA",
+ "TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA",
+ "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA",
+ "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA",
+ "TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256",
+ "TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256",
+ "TLS-DHE-RSA-WITH-CHACHA20-POLY1305-SHA256",
+ "TLS-DHE-RSA-WITH-AES-128-GCM-SHA256",
+ "TLS-DHE-RSA-WITH-AES-256-GCM-SHA384",
+ "TLS-DHE-DSS-WITH-AES-128-CBC-SHA",
+ "TLS-DHE-DSS-WITH-AES-256-CBC-SHA",
+ "TLS-DHE-DSS-WITH-AES-128-CBC-SHA256",
+ "TLS-DHE-DSS-WITH-AES-128-GCM-SHA256",
+ "TLS-DHE-DSS-WITH-AES-256-CBC-SHA256",
+ "TLS-DHE-DSS-WITH-AES-256-GCM-SHA384",
+ "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256",
+ "TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256",
+ "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384",
+ "TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384",
+ "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA",
+ "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256",
+ "TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256",
+ "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384",
+ "TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384",
+ "TLS-RSA-WITH-AES-128-GCM-SHA256",
+ "TLS-RSA-WITH-AES-256-GCM-SHA384",
+ "TLS-DHE-DSS-WITH-CAMELLIA-128-CBC-SHA",
+ "TLS-DHE-DSS-WITH-CAMELLIA-256-CBC-SHA",
+ "TLS-DHE-DSS-WITH-CAMELLIA-128-CBC-SHA256",
+ "TLS-DHE-DSS-WITH-CAMELLIA-256-CBC-SHA256",
+ "TLS-DHE-DSS-WITH-SEED-CBC-SHA",
+ "TLS-DHE-DSS-WITH-ARIA-128-CBC-SHA256",
+ "TLS-DHE-DSS-WITH-ARIA-256-CBC-SHA384",
+ "TLS-ECDHE-RSA-WITH-ARIA-128-CBC-SHA256",
+ "TLS-ECDHE-RSA-WITH-ARIA-256-CBC-SHA384",
+ "TLS-ECDHE-ECDSA-WITH-ARIA-128-CBC-SHA256",
+ "TLS-ECDHE-ECDSA-WITH-ARIA-256-CBC-SHA384",
+ "TLS-DHE-DSS-WITH-3DES-EDE-CBC-SHA",
+ "TLS-DHE-DSS-WITH-DES-CBC-SHA"]
+
+ ssl_server_cipher_suites_priority:
+ description:
+ - SSL/TLS cipher suites priority.
+ required: false
+
+ ssl_server_cipher_suites_versions:
+ description:
+ - SSL/TLS versions that the cipher suite can be used with.
+ - FLAG Based Options. Specify multiple in list form.
+ - flag | ssl-3.0 | SSL 3.0.
+ - flag | tls-1.0 | TLS 1.0.
+ - flag | tls-1.1 | TLS 1.1.
+ - flag | tls-1.2 | TLS 1.2.
+ required: false
+ choices: ["ssl-3.0", "tls-1.0", "tls-1.1", "tls-1.2"]
+
+
+'''
+
+EXAMPLES = '''
+# BASIC FULL STATIC NAT MAPPING
+- name: EDIT FMGR_FIREWALL_VIP SNAT
+ community.fortios.fmgr_fwobj_vip:
+ name: "Basic StaticNAT Map"
+ mode: "set"
+ adom: "ansible"
+ type: "static-nat"
+ extip: "82.72.192.185"
+ extintf: "any"
+ mappedip: "10.7.220.25"
+ comment: "Created by Ansible"
+ color: "17"
+
+# BASIC PORT PNAT MAPPING
+- name: EDIT FMGR_FIREWALL_VIP PNAT
+ community.fortios.fmgr_fwobj_vip:
+ name: "Basic PNAT Map Port 10443"
+ mode: "set"
+ adom: "ansible"
+ type: "static-nat"
+ extip: "82.72.192.185"
+ extport: "10443"
+ extintf: "any"
+ portforward: "enable"
+ protocol: "tcp"
+ mappedip: "10.7.220.25"
+ mappedport: "443"
+ comment: "Created by Ansible"
+ color: "17"
+
+# BASIC DNS TRANSLATION NAT
+- name: EDIT FMGR_FIREWALL_DNST
+ community.fortios.fmgr_fwobj_vip:
+ name: "Basic DNS Translation"
+ mode: "set"
+ adom: "ansible"
+ type: "dns-translation"
+ extip: "192.168.0.1-192.168.0.100"
+ extintf: "dmz"
+ mappedip: "3.3.3.0/24, 4.0.0.0/24"
+ comment: "Created by Ansible"
+ color: "12"
+
+# BASIC FQDN NAT
+- name: EDIT FMGR_FIREWALL_FQDN
+ community.fortios.fmgr_fwobj_vip:
+ name: "Basic FQDN Translation"
+ mode: "set"
+ adom: "ansible"
+ type: "fqdn"
+ mapped_addr: "google-play"
+ comment: "Created by Ansible"
+ color: "5"
+
+# DELETE AN ENTRY
+- name: DELETE FMGR_FIREWALL_VIP PNAT
+ community.fortios.fmgr_fwobj_vip:
+ name: "Basic PNAT Map Port 10443"
+ mode: "delete"
+ adom: "ansible"
+'''
+
+RETURN = """
+api_result:
+ description: full API response, includes status code and message
+ returned: always
+ type: str
+"""
+
+from ansible.module_utils.basic import AnsibleModule, env_fallback
+from ansible.module_utils.connection import Connection
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.fortimanager import FortiManagerHandler
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGBaseException
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRCommon
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRMethods
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import DEFAULT_RESULT_OBJ
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FAIL_SOCKET_MSG
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import prepare_dict
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import scrub_dict
+
+
+def fmgr_firewall_vip_modify(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+
+ mode = paramgram["mode"]
+ adom = paramgram["adom"]
+ # INIT A BASIC OBJECTS
+ response = DEFAULT_RESULT_OBJ
+ url = ""
+ datagram = {}
+
+ # EVAL THE MODE PARAMETER FOR SET OR ADD
+ if mode in ['set', 'add', 'update']:
+ url = '/pm/config/adom/{adom}/obj/firewall/vip'.format(adom=adom)
+ datagram = scrub_dict(prepare_dict(paramgram))
+
+ # EVAL THE MODE PARAMETER FOR DELETE
+ elif mode == "delete":
+ # SET THE CORRECT URL FOR DELETE
+ url = '/pm/config/adom/{adom}/obj/firewall/vip/{name}'.format(adom=adom, name=paramgram["name"])
+ datagram = {}
+
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+ return response
+
+
+#############
+# END METHODS
+#############
+
+
+def main():
+ argument_spec = dict(
+ adom=dict(type="str", default="root"),
+ mode=dict(choices=["add", "set", "delete", "update"], type="str", default="add"),
+
+ websphere_server=dict(required=False, type="str", choices=["disable", "enable"]),
+ weblogic_server=dict(required=False, type="str", choices=["disable", "enable"]),
+ type=dict(required=False, type="str",
+ choices=["static-nat", "load-balance", "server-load-balance", "dns-translation", "fqdn"]),
+ ssl_server_session_state_type=dict(required=False, type="str", choices=["disable", "time", "count", "both"]),
+ ssl_server_session_state_timeout=dict(required=False, type="int"),
+ ssl_server_session_state_max=dict(required=False, type="int"),
+ ssl_server_min_version=dict(required=False, type="str",
+ choices=["ssl-3.0", "tls-1.0", "tls-1.1", "tls-1.2", "client"]),
+ ssl_server_max_version=dict(required=False, type="str",
+ choices=["ssl-3.0", "tls-1.0", "tls-1.1", "tls-1.2", "client"]),
+ ssl_server_algorithm=dict(required=False, type="str", choices=["high", "low", "medium", "custom", "client"]),
+ ssl_send_empty_frags=dict(required=False, type="str", choices=["disable", "enable"]),
+ ssl_pfs=dict(required=False, type="str", choices=["require", "deny", "allow"]),
+ ssl_mode=dict(required=False, type="str", choices=["half", "full"]),
+ ssl_min_version=dict(required=False, type="str", choices=["ssl-3.0", "tls-1.0", "tls-1.1", "tls-1.2"]),
+ ssl_max_version=dict(required=False, type="str", choices=["ssl-3.0", "tls-1.0", "tls-1.1", "tls-1.2"]),
+ ssl_http_match_host=dict(required=False, type="str", choices=["disable", "enable"]),
+ ssl_http_location_conversion=dict(required=False, type="str", choices=["disable", "enable"]),
+ ssl_hsts_include_subdomains=dict(required=False, type="str", choices=["disable", "enable"]),
+ ssl_hsts_age=dict(required=False, type="int"),
+ ssl_hsts=dict(required=False, type="str", choices=["disable", "enable"]),
+ ssl_hpkp_report_uri=dict(required=False, type="str"),
+ ssl_hpkp_primary=dict(required=False, type="str"),
+ ssl_hpkp_include_subdomains=dict(required=False, type="str", choices=["disable", "enable"]),
+ ssl_hpkp_backup=dict(required=False, type="str"),
+ ssl_hpkp_age=dict(required=False, type="int"),
+ ssl_hpkp=dict(required=False, type="str", choices=["disable", "enable", "report-only"]),
+ ssl_dh_bits=dict(required=False, type="str", choices=["768", "1024", "1536", "2048", "3072", "4096"]),
+ ssl_client_session_state_type=dict(required=False, type="str", choices=["disable", "time", "count", "both"]),
+ ssl_client_session_state_timeout=dict(required=False, type="int"),
+ ssl_client_session_state_max=dict(required=False, type="int"),
+ ssl_client_renegotiation=dict(required=False, type="str", choices=["deny", "allow", "secure"]),
+ ssl_client_fallback=dict(required=False, type="str", choices=["disable", "enable"]),
+ ssl_certificate=dict(required=False, type="str"),
+ ssl_algorithm=dict(required=False, type="str", choices=["high", "medium", "low", "custom"]),
+ srcintf_filter=dict(required=False, type="str"),
+ src_filter=dict(required=False, type="str"),
+ service=dict(required=False, type="str"),
+ server_type=dict(required=False, type="str",
+ choices=["http", "https", "ssl", "tcp", "udp", "ip", "imaps", "pop3s", "smtps"]),
+ protocol=dict(required=False, type="str", choices=["tcp", "udp", "sctp", "icmp"]),
+ portmapping_type=dict(required=False, type="str", choices=["1-to-1", "m-to-n"]),
+ portforward=dict(required=False, type="str", choices=["disable", "enable"]),
+ persistence=dict(required=False, type="str", choices=["none", "http-cookie", "ssl-session-id"]),
+ outlook_web_access=dict(required=False, type="str", choices=["disable", "enable"]),
+ nat_source_vip=dict(required=False, type="str", choices=["disable", "enable"]),
+ name=dict(required=False, type="str"),
+ monitor=dict(required=False, type="str"),
+ max_embryonic_connections=dict(required=False, type="int"),
+ mappedport=dict(required=False, type="str"),
+ mappedip=dict(required=False, type="str"),
+ mapped_addr=dict(required=False, type="str"),
+ ldb_method=dict(required=False, type="str",
+ choices=["static", "round-robin", "weighted", "least-session", "least-rtt", "first-alive",
+ "http-host"]),
+ https_cookie_secure=dict(required=False, type="str", choices=["disable", "enable"]),
+ http_multiplex=dict(required=False, type="str", choices=["disable", "enable"]),
+ http_ip_header_name=dict(required=False, type="str"),
+ http_ip_header=dict(required=False, type="str", choices=["disable", "enable"]),
+ http_cookie_share=dict(required=False, type="str", choices=["disable", "same-ip"]),
+ http_cookie_path=dict(required=False, type="str"),
+ http_cookie_generation=dict(required=False, type="int"),
+ http_cookie_domain_from_host=dict(required=False, type="str", choices=["disable", "enable"]),
+ http_cookie_domain=dict(required=False, type="str"),
+ http_cookie_age=dict(required=False, type="int"),
+ gratuitous_arp_interval=dict(required=False, type="int"),
+ extport=dict(required=False, type="str"),
+ extip=dict(required=False, type="str"),
+ extintf=dict(required=False, type="str"),
+ extaddr=dict(required=False, type="str"),
+ dns_mapping_ttl=dict(required=False, type="int"),
+ comment=dict(required=False, type="str"),
+ color=dict(required=False, type="int"),
+ arp_reply=dict(required=False, type="str", choices=["disable", "enable"]),
+ dynamic_mapping=dict(required=False, type="list"),
+ dynamic_mapping_arp_reply=dict(required=False, type="str", choices=["disable", "enable"]),
+ dynamic_mapping_color=dict(required=False, type="int"),
+ dynamic_mapping_comment=dict(required=False, type="str"),
+ dynamic_mapping_dns_mapping_ttl=dict(required=False, type="int"),
+ dynamic_mapping_extaddr=dict(required=False, type="str"),
+ dynamic_mapping_extintf=dict(required=False, type="str"),
+ dynamic_mapping_extip=dict(required=False, type="str"),
+ dynamic_mapping_extport=dict(required=False, type="str"),
+ dynamic_mapping_gratuitous_arp_interval=dict(required=False, type="int"),
+ dynamic_mapping_http_cookie_age=dict(required=False, type="int"),
+ dynamic_mapping_http_cookie_domain=dict(required=False, type="str"),
+ dynamic_mapping_http_cookie_domain_from_host=dict(required=False, type="str", choices=["disable", "enable"]),
+ dynamic_mapping_http_cookie_generation=dict(required=False, type="int"),
+ dynamic_mapping_http_cookie_path=dict(required=False, type="str"),
+ dynamic_mapping_http_cookie_share=dict(required=False, type="str", choices=["disable", "same-ip"]),
+ dynamic_mapping_http_ip_header=dict(required=False, type="str", choices=["disable", "enable"]),
+ dynamic_mapping_http_ip_header_name=dict(required=False, type="str"),
+ dynamic_mapping_http_multiplex=dict(required=False, type="str", choices=["disable", "enable"]),
+ dynamic_mapping_https_cookie_secure=dict(required=False, type="str", choices=["disable", "enable"]),
+ dynamic_mapping_ldb_method=dict(required=False, type="str", choices=["static",
+ "round-robin",
+ "weighted",
+ "least-session",
+ "least-rtt",
+ "first-alive",
+ "http-host"]),
+ dynamic_mapping_mapped_addr=dict(required=False, type="str"),
+ dynamic_mapping_mappedip=dict(required=False, type="str"),
+ dynamic_mapping_mappedport=dict(required=False, type="str"),
+ dynamic_mapping_max_embryonic_connections=dict(required=False, type="int"),
+ dynamic_mapping_monitor=dict(required=False, type="str"),
+ dynamic_mapping_nat_source_vip=dict(required=False, type="str", choices=["disable", "enable"]),
+ dynamic_mapping_outlook_web_access=dict(required=False, type="str", choices=["disable", "enable"]),
+ dynamic_mapping_persistence=dict(required=False, type="str", choices=["none", "http-cookie", "ssl-session-id"]),
+ dynamic_mapping_portforward=dict(required=False, type="str", choices=["disable", "enable"]),
+ dynamic_mapping_portmapping_type=dict(required=False, type="str", choices=["1-to-1", "m-to-n"]),
+ dynamic_mapping_protocol=dict(required=False, type="str", choices=["tcp", "udp", "sctp", "icmp"]),
+ dynamic_mapping_server_type=dict(required=False, type="str",
+ choices=["http", "https", "ssl", "tcp", "udp", "ip", "imaps", "pop3s",
+ "smtps"]),
+ dynamic_mapping_service=dict(required=False, type="str"),
+ dynamic_mapping_src_filter=dict(required=False, type="str"),
+ dynamic_mapping_srcintf_filter=dict(required=False, type="str"),
+ dynamic_mapping_ssl_algorithm=dict(required=False, type="str", choices=["high", "medium", "low", "custom"]),
+ dynamic_mapping_ssl_certificate=dict(required=False, type="str"),
+ dynamic_mapping_ssl_client_fallback=dict(required=False, type="str", choices=["disable", "enable"]),
+ dynamic_mapping_ssl_client_renegotiation=dict(required=False, type="str", choices=["deny", "allow", "secure"]),
+ dynamic_mapping_ssl_client_session_state_max=dict(required=False, type="int"),
+ dynamic_mapping_ssl_client_session_state_timeout=dict(required=False, type="int"),
+ dynamic_mapping_ssl_client_session_state_type=dict(required=False, type="str",
+ choices=["disable", "time", "count", "both"]),
+ dynamic_mapping_ssl_dh_bits=dict(required=False, type="str",
+ choices=["768", "1024", "1536", "2048", "3072", "4096"]),
+ dynamic_mapping_ssl_hpkp=dict(required=False, type="str", choices=["disable", "enable", "report-only"]),
+ dynamic_mapping_ssl_hpkp_age=dict(required=False, type="int"),
+ dynamic_mapping_ssl_hpkp_backup=dict(required=False, type="str"),
+ dynamic_mapping_ssl_hpkp_include_subdomains=dict(required=False, type="str", choices=["disable", "enable"]),
+ dynamic_mapping_ssl_hpkp_primary=dict(required=False, type="str"),
+ dynamic_mapping_ssl_hpkp_report_uri=dict(required=False, type="str"),
+ dynamic_mapping_ssl_hsts=dict(required=False, type="str", choices=["disable", "enable"]),
+ dynamic_mapping_ssl_hsts_age=dict(required=False, type="int"),
+ dynamic_mapping_ssl_hsts_include_subdomains=dict(required=False, type="str", choices=["disable", "enable"]),
+ dynamic_mapping_ssl_http_location_conversion=dict(required=False, type="str", choices=["disable", "enable"]),
+ dynamic_mapping_ssl_http_match_host=dict(required=False, type="str", choices=["disable", "enable"]),
+ dynamic_mapping_ssl_max_version=dict(required=False, type="str",
+ choices=["ssl-3.0", "tls-1.0", "tls-1.1", "tls-1.2"]),
+ dynamic_mapping_ssl_min_version=dict(required=False, type="str",
+ choices=["ssl-3.0", "tls-1.0", "tls-1.1", "tls-1.2"]),
+ dynamic_mapping_ssl_mode=dict(required=False, type="str", choices=["half", "full"]),
+ dynamic_mapping_ssl_pfs=dict(required=False, type="str", choices=["require", "deny", "allow"]),
+ dynamic_mapping_ssl_send_empty_frags=dict(required=False, type="str", choices=["disable", "enable"]),
+ dynamic_mapping_ssl_server_algorithm=dict(required=False, type="str",
+ choices=["high", "low", "medium", "custom", "client"]),
+ dynamic_mapping_ssl_server_max_version=dict(required=False, type="str",
+ choices=["ssl-3.0", "tls-1.0", "tls-1.1", "tls-1.2", "client"]),
+ dynamic_mapping_ssl_server_min_version=dict(required=False, type="str",
+ choices=["ssl-3.0", "tls-1.0", "tls-1.1", "tls-1.2", "client"]),
+ dynamic_mapping_ssl_server_session_state_max=dict(required=False, type="int"),
+ dynamic_mapping_ssl_server_session_state_timeout=dict(required=False, type="int"),
+ dynamic_mapping_ssl_server_session_state_type=dict(required=False, type="str",
+ choices=["disable", "time", "count", "both"]),
+ dynamic_mapping_type=dict(required=False, type="str",
+ choices=["static-nat", "load-balance", "server-load-balance", "dns-translation",
+ "fqdn"]),
+ dynamic_mapping_weblogic_server=dict(required=False, type="str", choices=["disable", "enable"]),
+ dynamic_mapping_websphere_server=dict(required=False, type="str", choices=["disable", "enable"]),
+
+ dynamic_mapping_realservers_client_ip=dict(required=False, type="str"),
+ dynamic_mapping_realservers_healthcheck=dict(required=False, type="str", choices=["disable", "enable", "vip"]),
+ dynamic_mapping_realservers_holddown_interval=dict(required=False, type="int"),
+ dynamic_mapping_realservers_http_host=dict(required=False, type="str"),
+ dynamic_mapping_realservers_ip=dict(required=False, type="str"),
+ dynamic_mapping_realservers_max_connections=dict(required=False, type="int"),
+ dynamic_mapping_realservers_monitor=dict(required=False, type="str"),
+ dynamic_mapping_realservers_port=dict(required=False, type="int"),
+ dynamic_mapping_realservers_seq=dict(required=False, type="str"),
+ dynamic_mapping_realservers_status=dict(required=False, type="str", choices=["active", "standby", "disable"]),
+ dynamic_mapping_realservers_weight=dict(required=False, type="int"),
+
+ dynamic_mapping_ssl_cipher_suites_cipher=dict(required=False,
+ type="str",
+ choices=["TLS-RSA-WITH-RC4-128-MD5",
+ "TLS-RSA-WITH-RC4-128-SHA",
+ "TLS-RSA-WITH-DES-CBC-SHA",
+ "TLS-RSA-WITH-3DES-EDE-CBC-SHA",
+ "TLS-RSA-WITH-AES-128-CBC-SHA",
+ "TLS-RSA-WITH-AES-256-CBC-SHA",
+ "TLS-RSA-WITH-AES-128-CBC-SHA256",
+ "TLS-RSA-WITH-AES-256-CBC-SHA256",
+ "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA",
+ "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA",
+ "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA256",
+ "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA256",
+ "TLS-RSA-WITH-SEED-CBC-SHA",
+ "TLS-RSA-WITH-ARIA-128-CBC-SHA256",
+ "TLS-RSA-WITH-ARIA-256-CBC-SHA384",
+ "TLS-DHE-RSA-WITH-DES-CBC-SHA",
+ "TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA",
+ "TLS-DHE-RSA-WITH-AES-128-CBC-SHA",
+ "TLS-DHE-RSA-WITH-AES-256-CBC-SHA",
+ "TLS-DHE-RSA-WITH-AES-128-CBC-SHA256",
+ "TLS-DHE-RSA-WITH-AES-256-CBC-SHA256",
+ "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA",
+ "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA",
+ "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA256",
+ "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA256",
+ "TLS-DHE-RSA-WITH-SEED-CBC-SHA",
+ "TLS-DHE-RSA-WITH-ARIA-128-CBC-SHA256",
+ "TLS-DHE-RSA-WITH-ARIA-256-CBC-SHA384",
+ "TLS-ECDHE-RSA-WITH-RC4-128-SHA",
+ "TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA",
+ "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA",
+ "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA",
+ "TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256",
+ "TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256",
+ "TLS-DHE-RSA-WITH-CHACHA20-POLY1305-SHA256",
+ "TLS-DHE-RSA-WITH-AES-128-GCM-SHA256",
+ "TLS-DHE-RSA-WITH-AES-256-GCM-SHA384",
+ "TLS-DHE-DSS-WITH-AES-128-CBC-SHA",
+ "TLS-DHE-DSS-WITH-AES-256-CBC-SHA",
+ "TLS-DHE-DSS-WITH-AES-128-CBC-SHA256",
+ "TLS-DHE-DSS-WITH-AES-128-GCM-SHA256",
+ "TLS-DHE-DSS-WITH-AES-256-CBC-SHA256",
+ "TLS-DHE-DSS-WITH-AES-256-GCM-SHA384",
+ "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256",
+ "TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256",
+ "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384",
+ "TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384",
+ "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA",
+ "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256",
+ "TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256",
+ "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384",
+ "TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384",
+ "TLS-RSA-WITH-AES-128-GCM-SHA256",
+ "TLS-RSA-WITH-AES-256-GCM-SHA384",
+ "TLS-DHE-DSS-WITH-CAMELLIA-128-CBC-SHA",
+ "TLS-DHE-DSS-WITH-CAMELLIA-256-CBC-SHA",
+ "TLS-DHE-DSS-WITH-CAMELLIA-128-CBC-SHA256",
+ "TLS-DHE-DSS-WITH-CAMELLIA-256-CBC-SHA256",
+ "TLS-DHE-DSS-WITH-SEED-CBC-SHA",
+ "TLS-DHE-DSS-WITH-ARIA-128-CBC-SHA256",
+ "TLS-DHE-DSS-WITH-ARIA-256-CBC-SHA384",
+ "TLS-ECDHE-RSA-WITH-ARIA-128-CBC-SHA256",
+ "TLS-ECDHE-RSA-WITH-ARIA-256-CBC-SHA384",
+ "TLS-ECDHE-ECDSA-WITH-ARIA-128-CBC-SHA256",
+ "TLS-ECDHE-ECDSA-WITH-ARIA-256-CBC-SHA384",
+ "TLS-DHE-DSS-WITH-3DES-EDE-CBC-SHA",
+ "TLS-DHE-DSS-WITH-DES-CBC-SHA"]),
+ dynamic_mapping_ssl_cipher_suites_versions=dict(required=False, type="str",
+ choices=["ssl-3.0", "tls-1.0", "tls-1.1", "tls-1.2"]),
+ realservers=dict(required=False, type="list"),
+ realservers_client_ip=dict(required=False, type="str"),
+ realservers_healthcheck=dict(required=False, type="str", choices=["disable", "enable", "vip"]),
+ realservers_holddown_interval=dict(required=False, type="int"),
+ realservers_http_host=dict(required=False, type="str"),
+ realservers_ip=dict(required=False, type="str"),
+ realservers_max_connections=dict(required=False, type="int"),
+ realservers_monitor=dict(required=False, type="str"),
+ realservers_port=dict(required=False, type="int"),
+ realservers_seq=dict(required=False, type="str"),
+ realservers_status=dict(required=False, type="str", choices=["active", "standby", "disable"]),
+ realservers_weight=dict(required=False, type="int"),
+ ssl_cipher_suites=dict(required=False, type="list"),
+ ssl_cipher_suites_cipher=dict(required=False,
+ type="str",
+ choices=["TLS-RSA-WITH-RC4-128-MD5",
+ "TLS-RSA-WITH-RC4-128-SHA",
+ "TLS-RSA-WITH-DES-CBC-SHA",
+ "TLS-RSA-WITH-3DES-EDE-CBC-SHA",
+ "TLS-RSA-WITH-AES-128-CBC-SHA",
+ "TLS-RSA-WITH-AES-256-CBC-SHA",
+ "TLS-RSA-WITH-AES-128-CBC-SHA256",
+ "TLS-RSA-WITH-AES-256-CBC-SHA256",
+ "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA",
+ "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA",
+ "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA256",
+ "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA256",
+ "TLS-RSA-WITH-SEED-CBC-SHA",
+ "TLS-RSA-WITH-ARIA-128-CBC-SHA256",
+ "TLS-RSA-WITH-ARIA-256-CBC-SHA384",
+ "TLS-DHE-RSA-WITH-DES-CBC-SHA",
+ "TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA",
+ "TLS-DHE-RSA-WITH-AES-128-CBC-SHA",
+ "TLS-DHE-RSA-WITH-AES-256-CBC-SHA",
+ "TLS-DHE-RSA-WITH-AES-128-CBC-SHA256",
+ "TLS-DHE-RSA-WITH-AES-256-CBC-SHA256",
+ "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA",
+ "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA",
+ "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA256",
+ "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA256",
+ "TLS-DHE-RSA-WITH-SEED-CBC-SHA",
+ "TLS-DHE-RSA-WITH-ARIA-128-CBC-SHA256",
+ "TLS-DHE-RSA-WITH-ARIA-256-CBC-SHA384",
+ "TLS-ECDHE-RSA-WITH-RC4-128-SHA",
+ "TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA",
+ "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA",
+ "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA",
+ "TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256",
+ "TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256",
+ "TLS-DHE-RSA-WITH-CHACHA20-POLY1305-SHA256",
+ "TLS-DHE-RSA-WITH-AES-128-GCM-SHA256",
+ "TLS-DHE-RSA-WITH-AES-256-GCM-SHA384",
+ "TLS-DHE-DSS-WITH-AES-128-CBC-SHA",
+ "TLS-DHE-DSS-WITH-AES-256-CBC-SHA",
+ "TLS-DHE-DSS-WITH-AES-128-CBC-SHA256",
+ "TLS-DHE-DSS-WITH-AES-128-GCM-SHA256",
+ "TLS-DHE-DSS-WITH-AES-256-CBC-SHA256",
+ "TLS-DHE-DSS-WITH-AES-256-GCM-SHA384",
+ "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256",
+ "TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256",
+ "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384",
+ "TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384",
+ "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA",
+ "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256",
+ "TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256",
+ "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384",
+ "TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384",
+ "TLS-RSA-WITH-AES-128-GCM-SHA256",
+ "TLS-RSA-WITH-AES-256-GCM-SHA384",
+ "TLS-DHE-DSS-WITH-CAMELLIA-128-CBC-SHA",
+ "TLS-DHE-DSS-WITH-CAMELLIA-256-CBC-SHA",
+ "TLS-DHE-DSS-WITH-CAMELLIA-128-CBC-SHA256",
+ "TLS-DHE-DSS-WITH-CAMELLIA-256-CBC-SHA256",
+ "TLS-DHE-DSS-WITH-SEED-CBC-SHA",
+ "TLS-DHE-DSS-WITH-ARIA-128-CBC-SHA256",
+ "TLS-DHE-DSS-WITH-ARIA-256-CBC-SHA384",
+ "TLS-ECDHE-RSA-WITH-ARIA-128-CBC-SHA256",
+ "TLS-ECDHE-RSA-WITH-ARIA-256-CBC-SHA384",
+ "TLS-ECDHE-ECDSA-WITH-ARIA-128-CBC-SHA256",
+ "TLS-ECDHE-ECDSA-WITH-ARIA-256-CBC-SHA384",
+ "TLS-DHE-DSS-WITH-3DES-EDE-CBC-SHA",
+ "TLS-DHE-DSS-WITH-DES-CBC-SHA"]),
+ ssl_cipher_suites_versions=dict(required=False, type="str",
+ choices=["ssl-3.0", "tls-1.0", "tls-1.1", "tls-1.2"]),
+ ssl_server_cipher_suites=dict(required=False, type="list"),
+ ssl_server_cipher_suites_cipher=dict(required=False,
+ type="str",
+ choices=["TLS-RSA-WITH-RC4-128-MD5",
+ "TLS-RSA-WITH-RC4-128-SHA",
+ "TLS-RSA-WITH-DES-CBC-SHA",
+ "TLS-RSA-WITH-3DES-EDE-CBC-SHA",
+ "TLS-RSA-WITH-AES-128-CBC-SHA",
+ "TLS-RSA-WITH-AES-256-CBC-SHA",
+ "TLS-RSA-WITH-AES-128-CBC-SHA256",
+ "TLS-RSA-WITH-AES-256-CBC-SHA256",
+ "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA",
+ "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA",
+ "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA256",
+ "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA256",
+ "TLS-RSA-WITH-SEED-CBC-SHA",
+ "TLS-RSA-WITH-ARIA-128-CBC-SHA256",
+ "TLS-RSA-WITH-ARIA-256-CBC-SHA384",
+ "TLS-DHE-RSA-WITH-DES-CBC-SHA",
+ "TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA",
+ "TLS-DHE-RSA-WITH-AES-128-CBC-SHA",
+ "TLS-DHE-RSA-WITH-AES-256-CBC-SHA",
+ "TLS-DHE-RSA-WITH-AES-128-CBC-SHA256",
+ "TLS-DHE-RSA-WITH-AES-256-CBC-SHA256",
+ "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA",
+ "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA",
+ "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA256",
+ "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA256",
+ "TLS-DHE-RSA-WITH-SEED-CBC-SHA",
+ "TLS-DHE-RSA-WITH-ARIA-128-CBC-SHA256",
+ "TLS-DHE-RSA-WITH-ARIA-256-CBC-SHA384",
+ "TLS-ECDHE-RSA-WITH-RC4-128-SHA",
+ "TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA",
+ "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA",
+ "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA",
+ "TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256",
+ "TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256",
+ "TLS-DHE-RSA-WITH-CHACHA20-POLY1305-SHA256",
+ "TLS-DHE-RSA-WITH-AES-128-GCM-SHA256",
+ "TLS-DHE-RSA-WITH-AES-256-GCM-SHA384",
+ "TLS-DHE-DSS-WITH-AES-128-CBC-SHA",
+ "TLS-DHE-DSS-WITH-AES-256-CBC-SHA",
+ "TLS-DHE-DSS-WITH-AES-128-CBC-SHA256",
+ "TLS-DHE-DSS-WITH-AES-128-GCM-SHA256",
+ "TLS-DHE-DSS-WITH-AES-256-CBC-SHA256",
+ "TLS-DHE-DSS-WITH-AES-256-GCM-SHA384",
+ "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256",
+ "TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256",
+ "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384",
+ "TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384",
+ "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA",
+ "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256",
+ "TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256",
+ "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384",
+ "TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384",
+ "TLS-RSA-WITH-AES-128-GCM-SHA256",
+ "TLS-RSA-WITH-AES-256-GCM-SHA384",
+ "TLS-DHE-DSS-WITH-CAMELLIA-128-CBC-SHA",
+ "TLS-DHE-DSS-WITH-CAMELLIA-256-CBC-SHA",
+ "TLS-DHE-DSS-WITH-CAMELLIA-128-CBC-SHA256",
+ "TLS-DHE-DSS-WITH-CAMELLIA-256-CBC-SHA256",
+ "TLS-DHE-DSS-WITH-SEED-CBC-SHA",
+ "TLS-DHE-DSS-WITH-ARIA-128-CBC-SHA256",
+ "TLS-DHE-DSS-WITH-ARIA-256-CBC-SHA384",
+ "TLS-ECDHE-RSA-WITH-ARIA-128-CBC-SHA256",
+ "TLS-ECDHE-RSA-WITH-ARIA-256-CBC-SHA384",
+ "TLS-ECDHE-ECDSA-WITH-ARIA-128-CBC-SHA256",
+ "TLS-ECDHE-ECDSA-WITH-ARIA-256-CBC-SHA384",
+ "TLS-DHE-DSS-WITH-3DES-EDE-CBC-SHA",
+ "TLS-DHE-DSS-WITH-DES-CBC-SHA"]),
+ ssl_server_cipher_suites_priority=dict(required=False, type="str"),
+ ssl_server_cipher_suites_versions=dict(required=False, type="str",
+ choices=["ssl-3.0", "tls-1.0", "tls-1.1", "tls-1.2"]),
+
+ )
+
+ module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False, )
+ # MODULE PARAMGRAM
+ paramgram = {
+ "mode": module.params["mode"],
+ "adom": module.params["adom"],
+ "websphere-server": module.params["websphere_server"],
+ "weblogic-server": module.params["weblogic_server"],
+ "type": module.params["type"],
+ "ssl-server-session-state-type": module.params["ssl_server_session_state_type"],
+ "ssl-server-session-state-timeout": module.params["ssl_server_session_state_timeout"],
+ "ssl-server-session-state-max": module.params["ssl_server_session_state_max"],
+ "ssl-server-min-version": module.params["ssl_server_min_version"],
+ "ssl-server-max-version": module.params["ssl_server_max_version"],
+ "ssl-server-algorithm": module.params["ssl_server_algorithm"],
+ "ssl-send-empty-frags": module.params["ssl_send_empty_frags"],
+ "ssl-pfs": module.params["ssl_pfs"],
+ "ssl-mode": module.params["ssl_mode"],
+ "ssl-min-version": module.params["ssl_min_version"],
+ "ssl-max-version": module.params["ssl_max_version"],
+ "ssl-http-match-host": module.params["ssl_http_match_host"],
+ "ssl-http-location-conversion": module.params["ssl_http_location_conversion"],
+ "ssl-hsts-include-subdomains": module.params["ssl_hsts_include_subdomains"],
+ "ssl-hsts-age": module.params["ssl_hsts_age"],
+ "ssl-hsts": module.params["ssl_hsts"],
+ "ssl-hpkp-report-uri": module.params["ssl_hpkp_report_uri"],
+ "ssl-hpkp-primary": module.params["ssl_hpkp_primary"],
+ "ssl-hpkp-include-subdomains": module.params["ssl_hpkp_include_subdomains"],
+ "ssl-hpkp-backup": module.params["ssl_hpkp_backup"],
+ "ssl-hpkp-age": module.params["ssl_hpkp_age"],
+ "ssl-hpkp": module.params["ssl_hpkp"],
+ "ssl-dh-bits": module.params["ssl_dh_bits"],
+ "ssl-client-session-state-type": module.params["ssl_client_session_state_type"],
+ "ssl-client-session-state-timeout": module.params["ssl_client_session_state_timeout"],
+ "ssl-client-session-state-max": module.params["ssl_client_session_state_max"],
+ "ssl-client-renegotiation": module.params["ssl_client_renegotiation"],
+ "ssl-client-fallback": module.params["ssl_client_fallback"],
+ "ssl-certificate": module.params["ssl_certificate"],
+ "ssl-algorithm": module.params["ssl_algorithm"],
+ "srcintf-filter": module.params["srcintf_filter"],
+ "src-filter": module.params["src_filter"],
+ "service": module.params["service"],
+ "server-type": module.params["server_type"],
+ "protocol": module.params["protocol"],
+ "portmapping-type": module.params["portmapping_type"],
+ "portforward": module.params["portforward"],
+ "persistence": module.params["persistence"],
+ "outlook-web-access": module.params["outlook_web_access"],
+ "nat-source-vip": module.params["nat_source_vip"],
+ "name": module.params["name"],
+ "monitor": module.params["monitor"],
+ "max-embryonic-connections": module.params["max_embryonic_connections"],
+ "mappedport": module.params["mappedport"],
+ "mappedip": module.params["mappedip"],
+ "mapped-addr": module.params["mapped_addr"],
+ "ldb-method": module.params["ldb_method"],
+ "https-cookie-secure": module.params["https_cookie_secure"],
+ "http-multiplex": module.params["http_multiplex"],
+ "http-ip-header-name": module.params["http_ip_header_name"],
+ "http-ip-header": module.params["http_ip_header"],
+ "http-cookie-share": module.params["http_cookie_share"],
+ "http-cookie-path": module.params["http_cookie_path"],
+ "http-cookie-generation": module.params["http_cookie_generation"],
+ "http-cookie-domain-from-host": module.params["http_cookie_domain_from_host"],
+ "http-cookie-domain": module.params["http_cookie_domain"],
+ "http-cookie-age": module.params["http_cookie_age"],
+ "gratuitous-arp-interval": module.params["gratuitous_arp_interval"],
+ "extport": module.params["extport"],
+ "extip": module.params["extip"],
+ "extintf": module.params["extintf"],
+ "extaddr": module.params["extaddr"],
+ "dns-mapping-ttl": module.params["dns_mapping_ttl"],
+ "comment": module.params["comment"],
+ "color": module.params["color"],
+ "arp-reply": module.params["arp_reply"],
+ "dynamic_mapping": {
+ "arp-reply": module.params["dynamic_mapping_arp_reply"],
+ "color": module.params["dynamic_mapping_color"],
+ "comment": module.params["dynamic_mapping_comment"],
+ "dns-mapping-ttl": module.params["dynamic_mapping_dns_mapping_ttl"],
+ "extaddr": module.params["dynamic_mapping_extaddr"],
+ "extintf": module.params["dynamic_mapping_extintf"],
+ "extip": module.params["dynamic_mapping_extip"],
+ "extport": module.params["dynamic_mapping_extport"],
+ "gratuitous-arp-interval": module.params["dynamic_mapping_gratuitous_arp_interval"],
+ "http-cookie-age": module.params["dynamic_mapping_http_cookie_age"],
+ "http-cookie-domain": module.params["dynamic_mapping_http_cookie_domain"],
+ "http-cookie-domain-from-host": module.params["dynamic_mapping_http_cookie_domain_from_host"],
+ "http-cookie-generation": module.params["dynamic_mapping_http_cookie_generation"],
+ "http-cookie-path": module.params["dynamic_mapping_http_cookie_path"],
+ "http-cookie-share": module.params["dynamic_mapping_http_cookie_share"],
+ "http-ip-header": module.params["dynamic_mapping_http_ip_header"],
+ "http-ip-header-name": module.params["dynamic_mapping_http_ip_header_name"],
+ "http-multiplex": module.params["dynamic_mapping_http_multiplex"],
+ "https-cookie-secure": module.params["dynamic_mapping_https_cookie_secure"],
+ "ldb-method": module.params["dynamic_mapping_ldb_method"],
+ "mapped-addr": module.params["dynamic_mapping_mapped_addr"],
+ "mappedip": module.params["dynamic_mapping_mappedip"],
+ "mappedport": module.params["dynamic_mapping_mappedport"],
+ "max-embryonic-connections": module.params["dynamic_mapping_max_embryonic_connections"],
+ "monitor": module.params["dynamic_mapping_monitor"],
+ "nat-source-vip": module.params["dynamic_mapping_nat_source_vip"],
+ "outlook-web-access": module.params["dynamic_mapping_outlook_web_access"],
+ "persistence": module.params["dynamic_mapping_persistence"],
+ "portforward": module.params["dynamic_mapping_portforward"],
+ "portmapping-type": module.params["dynamic_mapping_portmapping_type"],
+ "protocol": module.params["dynamic_mapping_protocol"],
+ "server-type": module.params["dynamic_mapping_server_type"],
+ "service": module.params["dynamic_mapping_service"],
+ "src-filter": module.params["dynamic_mapping_src_filter"],
+ "srcintf-filter": module.params["dynamic_mapping_srcintf_filter"],
+ "ssl-algorithm": module.params["dynamic_mapping_ssl_algorithm"],
+ "ssl-certificate": module.params["dynamic_mapping_ssl_certificate"],
+ "ssl-client-fallback": module.params["dynamic_mapping_ssl_client_fallback"],
+ "ssl-client-renegotiation": module.params["dynamic_mapping_ssl_client_renegotiation"],
+ "ssl-client-session-state-max": module.params["dynamic_mapping_ssl_client_session_state_max"],
+ "ssl-client-session-state-timeout": module.params["dynamic_mapping_ssl_client_session_state_timeout"],
+ "ssl-client-session-state-type": module.params["dynamic_mapping_ssl_client_session_state_type"],
+ "ssl-dh-bits": module.params["dynamic_mapping_ssl_dh_bits"],
+ "ssl-hpkp": module.params["dynamic_mapping_ssl_hpkp"],
+ "ssl-hpkp-age": module.params["dynamic_mapping_ssl_hpkp_age"],
+ "ssl-hpkp-backup": module.params["dynamic_mapping_ssl_hpkp_backup"],
+ "ssl-hpkp-include-subdomains": module.params["dynamic_mapping_ssl_hpkp_include_subdomains"],
+ "ssl-hpkp-primary": module.params["dynamic_mapping_ssl_hpkp_primary"],
+ "ssl-hpkp-report-uri": module.params["dynamic_mapping_ssl_hpkp_report_uri"],
+ "ssl-hsts": module.params["dynamic_mapping_ssl_hsts"],
+ "ssl-hsts-age": module.params["dynamic_mapping_ssl_hsts_age"],
+ "ssl-hsts-include-subdomains": module.params["dynamic_mapping_ssl_hsts_include_subdomains"],
+ "ssl-http-location-conversion": module.params["dynamic_mapping_ssl_http_location_conversion"],
+ "ssl-http-match-host": module.params["dynamic_mapping_ssl_http_match_host"],
+ "ssl-max-version": module.params["dynamic_mapping_ssl_max_version"],
+ "ssl-min-version": module.params["dynamic_mapping_ssl_min_version"],
+ "ssl-mode": module.params["dynamic_mapping_ssl_mode"],
+ "ssl-pfs": module.params["dynamic_mapping_ssl_pfs"],
+ "ssl-send-empty-frags": module.params["dynamic_mapping_ssl_send_empty_frags"],
+ "ssl-server-algorithm": module.params["dynamic_mapping_ssl_server_algorithm"],
+ "ssl-server-max-version": module.params["dynamic_mapping_ssl_server_max_version"],
+ "ssl-server-min-version": module.params["dynamic_mapping_ssl_server_min_version"],
+ "ssl-server-session-state-max": module.params["dynamic_mapping_ssl_server_session_state_max"],
+ "ssl-server-session-state-timeout": module.params["dynamic_mapping_ssl_server_session_state_timeout"],
+ "ssl-server-session-state-type": module.params["dynamic_mapping_ssl_server_session_state_type"],
+ "type": module.params["dynamic_mapping_type"],
+ "weblogic-server": module.params["dynamic_mapping_weblogic_server"],
+ "websphere-server": module.params["dynamic_mapping_websphere_server"],
+ "realservers": {
+ "client-ip": module.params["dynamic_mapping_realservers_client_ip"],
+ "healthcheck": module.params["dynamic_mapping_realservers_healthcheck"],
+ "holddown-interval": module.params["dynamic_mapping_realservers_holddown_interval"],
+ "http-host": module.params["dynamic_mapping_realservers_http_host"],
+ "ip": module.params["dynamic_mapping_realservers_ip"],
+ "max-connections": module.params["dynamic_mapping_realservers_max_connections"],
+ "monitor": module.params["dynamic_mapping_realservers_monitor"],
+ "port": module.params["dynamic_mapping_realservers_port"],
+ "seq": module.params["dynamic_mapping_realservers_seq"],
+ "status": module.params["dynamic_mapping_realservers_status"],
+ "weight": module.params["dynamic_mapping_realservers_weight"],
+ },
+ "ssl-cipher-suites": {
+ "cipher": module.params["dynamic_mapping_ssl_cipher_suites_cipher"],
+ "versions": module.params["dynamic_mapping_ssl_cipher_suites_versions"],
+ },
+ },
+ "realservers": {
+ "client-ip": module.params["realservers_client_ip"],
+ "healthcheck": module.params["realservers_healthcheck"],
+ "holddown-interval": module.params["realservers_holddown_interval"],
+ "http-host": module.params["realservers_http_host"],
+ "ip": module.params["realservers_ip"],
+ "max-connections": module.params["realservers_max_connections"],
+ "monitor": module.params["realservers_monitor"],
+ "port": module.params["realservers_port"],
+ "seq": module.params["realservers_seq"],
+ "status": module.params["realservers_status"],
+ "weight": module.params["realservers_weight"],
+ },
+ "ssl-cipher-suites": {
+ "cipher": module.params["ssl_cipher_suites_cipher"],
+ "versions": module.params["ssl_cipher_suites_versions"],
+ },
+ "ssl-server-cipher-suites": {
+ "cipher": module.params["ssl_server_cipher_suites_cipher"],
+ "priority": module.params["ssl_server_cipher_suites_priority"],
+ "versions": module.params["ssl_server_cipher_suites_versions"],
+ }
+ }
+ module.paramgram = paramgram
+ fmgr = None
+ if module._socket_path:
+ connection = Connection(module._socket_path)
+ fmgr = FortiManagerHandler(connection, module)
+ fmgr.tools = FMGRCommon()
+ else:
+ module.fail_json(**FAIL_SOCKET_MSG)
+
+ list_overrides = ['dynamic_mapping', 'realservers', 'ssl-cipher-suites', 'ssl-server-cipher-suites']
+ paramgram = fmgr.tools.paramgram_child_list_override(list_overrides=list_overrides,
+ paramgram=paramgram, module=module)
+
+ results = DEFAULT_RESULT_OBJ
+ try:
+ results = fmgr_firewall_vip_modify(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ return module.exit_json(**results[1])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_fwpol_ipv4.py b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_fwpol_ipv4.py
new file mode 100644
index 00000000..f0b0fd9c
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_fwpol_ipv4.py
@@ -0,0 +1,1355 @@
+#!/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: fmgr_fwpol_ipv4
+notes:
+ - Full Documentation at U(https://ftnt-ansible-docs.readthedocs.io/en/latest/).
+author:
+ - Luke Weighall (@lweighall)
+ - Andrew Welsh (@Ghilli3)
+ - Jim Huber (@p4r4n0y1ng)
+short_description: Allows the add/delete of Firewall Policies on Packages in FortiManager.
+description:
+ - Allows the add/delete of Firewall Policies on Packages in FortiManager.
+
+options:
+ adom:
+ description:
+ - The ADOM the configuration should belong to.
+ required: false
+ default: root
+
+ mode:
+ description:
+ - Sets one of three modes for managing the object.
+ - Allows use of soft-adds instead of overwriting existing values
+ choices: ['add', 'set', 'delete', 'update']
+ required: false
+ default: add
+
+ package_name:
+ description:
+ - The policy package you want to modify
+ required: false
+ default: "default"
+
+ fail_on_missing_dependency:
+ description:
+ - Normal behavior is to "skip" tasks that fail dependency checks, so other tasks can run.
+ - If set to "enabled" if a failed dependency check happeens, Ansible will exit as with failure instead of skip.
+ required: false
+ default: "disable"
+ choices: ["enable", "disable"]
+
+ wsso:
+ description:
+ - Enable/disable WiFi Single Sign On (WSSO).
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ webfilter_profile:
+ description:
+ - Name of an existing Web filter profile.
+ required: false
+
+ webcache_https:
+ description:
+ - Enable/disable web cache for HTTPS.
+ - choice | disable | Disable web cache for HTTPS.
+ - choice | enable | Enable web cache for HTTPS.
+ required: false
+ choices: ["disable", "enable"]
+
+ webcache:
+ description:
+ - Enable/disable web cache.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ wccp:
+ description:
+ - Enable/disable forwarding traffic matching this policy to a configured WCCP server.
+ - choice | disable | Disable WCCP setting.
+ - choice | enable | Enable WCCP setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ wanopt_profile:
+ description:
+ - WAN optimization profile.
+ required: false
+
+ wanopt_peer:
+ description:
+ - WAN optimization peer.
+ required: false
+
+ wanopt_passive_opt:
+ description:
+ - WAN optimization passive mode options. This option decides what IP address will be used to connect server.
+ - choice | default | Allow client side WAN opt peer to decide.
+ - choice | transparent | Use address of client to connect to server.
+ - choice | non-transparent | Use local FortiGate address to connect to server.
+ required: false
+ choices: ["default", "transparent", "non-transparent"]
+
+ wanopt_detection:
+ description:
+ - WAN optimization auto-detection mode.
+ - choice | active | Active WAN optimization peer auto-detection.
+ - choice | passive | Passive WAN optimization peer auto-detection.
+ - choice | off | Turn off WAN optimization peer auto-detection.
+ required: false
+ choices: ["active", "passive", "off"]
+
+ wanopt:
+ description:
+ - Enable/disable WAN optimization.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ waf_profile:
+ description:
+ - Name of an existing Web application firewall profile.
+ required: false
+
+ vpntunnel:
+ description:
+ - Policy-based IPsec VPN | name of the IPsec VPN Phase 1.
+ required: false
+
+ voip_profile:
+ description:
+ - Name of an existing VoIP profile.
+ required: false
+
+ vlan_filter:
+ description:
+ - Set VLAN filters.
+ required: false
+
+ vlan_cos_rev:
+ description:
+ - VLAN reverse direction user priority | 255 passthrough, 0 lowest, 7 highest..
+ required: false
+
+ vlan_cos_fwd:
+ description:
+ - VLAN forward direction user priority | 255 passthrough, 0 lowest, 7 highest.
+ required: false
+
+ utm_status:
+ description:
+ - Enable to add one or more security profiles (AV, IPS, etc.) to the firewall policy.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ users:
+ description:
+ - Names of individual users that can authenticate with this policy.
+ required: false
+
+ url_category:
+ description:
+ - URL category ID list.
+ required: false
+
+ traffic_shaper_reverse:
+ description:
+ - Reverse traffic shaper.
+ required: false
+
+ traffic_shaper:
+ description:
+ - Traffic shaper.
+ required: false
+
+ timeout_send_rst:
+ description:
+ - Enable/disable sending RST packets when TCP sessions expire.
+ - choice | disable | Disable sending of RST packet upon TCP session expiration.
+ - choice | enable | Enable sending of RST packet upon TCP session expiration.
+ required: false
+ choices: ["disable", "enable"]
+
+ tcp_session_without_syn:
+ description:
+ - Enable/disable creation of TCP session without SYN flag.
+ - choice | all | Enable TCP session without SYN.
+ - choice | data-only | Enable TCP session data only.
+ - choice | disable | Disable TCP session without SYN.
+ required: false
+ choices: ["all", "data-only", "disable"]
+
+ tcp_mss_sender:
+ description:
+ - Sender TCP maximum segment size (MSS).
+ required: false
+
+ tcp_mss_receiver:
+ description:
+ - Receiver TCP maximum segment size (MSS).
+ required: false
+
+ status:
+ description:
+ - Enable or disable this policy.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ ssl_ssh_profile:
+ description:
+ - Name of an existing SSL SSH profile.
+ required: false
+
+ ssl_mirror_intf:
+ description:
+ - SSL mirror interface name.
+ required: false
+
+ ssl_mirror:
+ description:
+ - Enable to copy decrypted SSL traffic to a FortiGate interface (called SSL mirroring).
+ - choice | disable | Disable SSL mirror.
+ - choice | enable | Enable SSL mirror.
+ required: false
+ choices: ["disable", "enable"]
+
+ ssh_filter_profile:
+ description:
+ - Name of an existing SSH filter profile.
+ required: false
+
+ srcintf:
+ description:
+ - Incoming (ingress) interface.
+ required: false
+
+ srcaddr_negate:
+ description:
+ - When enabled srcaddr specifies what the source address must NOT be.
+ - choice | disable | Disable source address negate.
+ - choice | enable | Enable source address negate.
+ required: false
+ choices: ["disable", "enable"]
+
+ srcaddr:
+ description:
+ - Source address and address group names.
+ required: false
+
+ spamfilter_profile:
+ description:
+ - Name of an existing Spam filter profile.
+ required: false
+
+ session_ttl:
+ description:
+ - TTL in seconds for sessions accepted by this policy (0 means use the system default session TTL).
+ required: false
+
+ service_negate:
+ description:
+ - When enabled service specifies what the service must NOT be.
+ - choice | disable | Disable negated service match.
+ - choice | enable | Enable negated service match.
+ required: false
+ choices: ["disable", "enable"]
+
+ service:
+ description:
+ - Service and service group names.
+ required: false
+
+ send_deny_packet:
+ description:
+ - Enable to send a reply when a session is denied or blocked by a firewall policy.
+ - choice | disable | Disable deny-packet sending.
+ - choice | enable | Enable deny-packet sending.
+ required: false
+ choices: ["disable", "enable"]
+
+ schedule_timeout:
+ description:
+ - Enable to force current sessions to end when the schedule object times out.
+ - choice | disable | Disable schedule timeout.
+ - choice | enable | Enable schedule timeout.
+ required: false
+ choices: ["disable", "enable"]
+
+ schedule:
+ description:
+ - Schedule name.
+ required: false
+
+ scan_botnet_connections:
+ description:
+ - Block or monitor connections to Botnet servers or disable Botnet scanning.
+ - choice | disable | Do not scan connections to botnet servers.
+ - choice | block | Block connections to botnet servers.
+ - choice | monitor | Log connections to botnet servers.
+ required: false
+ choices: ["disable", "block", "monitor"]
+
+ rtp_nat:
+ description:
+ - Enable Real Time Protocol (RTP) NAT.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ rtp_addr:
+ description:
+ - Address names if this is an RTP NAT policy.
+ required: false
+
+ rsso:
+ description:
+ - Enable/disable RADIUS single sign-on (RSSO).
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ replacemsg_override_group:
+ description:
+ - Override the default replacement message group for this policy.
+ required: false
+
+ redirect_url:
+ description:
+ - URL users are directed to after seeing and accepting the disclaimer or authenticating.
+ required: false
+
+ radius_mac_auth_bypass:
+ description:
+ - Enable MAC authentication bypass. The bypassed MAC address must be received from RADIUS server.
+ - choice | disable | Disable MAC authentication bypass.
+ - choice | enable | Enable MAC authentication bypass.
+ required: false
+ choices: ["disable", "enable"]
+
+ profile_type:
+ description:
+ - Determine whether the firewall policy allows security profile groups or single profiles only.
+ - choice | single | Do not allow security profile groups.
+ - choice | group | Allow security profile groups.
+ required: false
+ choices: ["single", "group"]
+
+ profile_protocol_options:
+ description:
+ - Name of an existing Protocol options profile.
+ required: false
+
+ profile_group:
+ description:
+ - Name of profile group.
+ required: false
+
+ poolname:
+ description:
+ - IP Pool names.
+ required: false
+
+ policyid:
+ description:
+ - Policy ID.
+ required: false
+
+ permit_stun_host:
+ description:
+ - Accept UDP packets from any Session Traversal Utilities for NAT (STUN) host.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ permit_any_host:
+ description:
+ - Accept UDP packets from any host.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ per_ip_shaper:
+ description:
+ - Per-IP traffic shaper.
+ required: false
+
+ outbound:
+ description:
+ - Policy-based IPsec VPN | only traffic from the internal network can initiate a VPN.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ ntlm_guest:
+ description:
+ - Enable/disable NTLM guest user access.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ ntlm_enabled_browsers:
+ description:
+ - HTTP-User-Agent value of supported browsers.
+ required: false
+
+ ntlm:
+ description:
+ - Enable/disable NTLM authentication.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ np_acceleration:
+ description:
+ - Enable/disable UTM Network Processor acceleration.
+ - choice | disable | Disable UTM Network Processor acceleration.
+ - choice | enable | Enable UTM Network Processor acceleration.
+ required: false
+ choices: ["disable", "enable"]
+
+ natoutbound:
+ description:
+ - Policy-based IPsec VPN | apply source NAT to outbound traffic.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ natip:
+ description:
+ - Policy-based IPsec VPN | source NAT IP address for outgoing traffic.
+ required: false
+
+ natinbound:
+ description:
+ - Policy-based IPsec VPN | apply destination NAT to inbound traffic.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ nat:
+ description:
+ - Enable/disable source NAT.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ name:
+ description:
+ - Policy name.
+ required: false
+
+ mms_profile:
+ description:
+ - Name of an existing MMS profile.
+ required: false
+
+ match_vip:
+ description:
+ - Enable to match packets that have had their destination addresses changed by a VIP.
+ - choice | disable | Do not match DNATed packet.
+ - choice | enable | Match DNATed packet.
+ required: false
+ choices: ["disable", "enable"]
+
+ logtraffic_start:
+ description:
+ - Record logs when a session starts and ends.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ logtraffic:
+ description:
+ - Enable or disable logging. Log all sessions or security profile sessions.
+ - choice | disable | Disable all logging for this policy.
+ - choice | all | Log all sessions accepted or denied by this policy.
+ - choice | utm | Log traffic that has a security profile applied to it.
+ required: false
+ choices: ["disable", "all", "utm"]
+
+ learning_mode:
+ description:
+ - Enable to allow everything, but log all of the meaningful data for security information gathering.
+ - choice | disable | Disable learning mode in firewall policy.
+ - choice | enable | Enable learning mode in firewall policy.
+ required: false
+ choices: ["disable", "enable"]
+
+ label:
+ description:
+ - Label for the policy that appears when the GUI is in Section View mode.
+ required: false
+
+ ips_sensor:
+ description:
+ - Name of an existing IPS sensor.
+ required: false
+
+ ippool:
+ description:
+ - Enable to use IP Pools for source NAT.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ internet_service_src_negate:
+ description:
+ - When enabled internet-service-src specifies what the service must NOT be.
+ - choice | disable | Disable negated Internet Service source match.
+ - choice | enable | Enable negated Internet Service source match.
+ required: false
+ choices: ["disable", "enable"]
+
+ internet_service_src_id:
+ description:
+ - Internet Service source ID.
+ required: false
+
+ internet_service_src_custom:
+ description:
+ - Custom Internet Service source name.
+ required: false
+
+ internet_service_src:
+ description:
+ - Enable/disable use of Internet Services in source for this policy. If enabled, source address is not used.
+ - choice | disable | Disable use of Internet Services source in policy.
+ - choice | enable | Enable use of Internet Services source in policy.
+ required: false
+ choices: ["disable", "enable"]
+
+ internet_service_negate:
+ description:
+ - When enabled internet-service specifies what the service must NOT be.
+ - choice | disable | Disable negated Internet Service match.
+ - choice | enable | Enable negated Internet Service match.
+ required: false
+ choices: ["disable", "enable"]
+
+ internet_service_id:
+ description:
+ - Internet Service ID.
+ required: false
+
+ internet_service_custom:
+ description:
+ - Custom Internet Service name.
+ required: false
+
+ internet_service:
+ description:
+ - Enable/disable use of Internet Services for this policy. If enabled, dstaddr and service are not used.
+ - choice | disable | Disable use of Internet Services in policy.
+ - choice | enable | Enable use of Internet Services in policy.
+ required: false
+ choices: ["disable", "enable"]
+
+ inbound:
+ description:
+ - Policy-based IPsec VPN | only traffic from the remote network can initiate a VPN.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ identity_based_route:
+ description:
+ - Name of identity-based routing rule.
+ required: false
+
+ icap_profile:
+ description:
+ - Name of an existing ICAP profile.
+ required: false
+
+ gtp_profile:
+ description:
+ - GTP profile.
+ required: false
+
+ groups:
+ description:
+ - Names of user groups that can authenticate with this policy.
+ required: false
+
+ global_label:
+ description:
+ - Label for the policy that appears when the GUI is in Global View mode.
+ required: false
+
+ fsso_agent_for_ntlm:
+ description:
+ - FSSO agent to use for NTLM authentication.
+ required: false
+
+ fsso:
+ description:
+ - Enable/disable Fortinet Single Sign-On.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ fixedport:
+ description:
+ - Enable to prevent source NAT from changing a session's source port.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ firewall_session_dirty:
+ description:
+ - How to handle sessions if the configuration of this firewall policy changes.
+ - choice | check-all | Flush all current sessions accepted by this policy.
+ - choice | check-new | Continue to allow sessions already accepted by this policy.
+ required: false
+ choices: ["check-all", "check-new"]
+
+ dstintf:
+ description:
+ - Outgoing (egress) interface.
+ required: false
+
+ dstaddr_negate:
+ description:
+ - When enabled dstaddr specifies what the destination address must NOT be.
+ - choice | disable | Disable destination address negate.
+ - choice | enable | Enable destination address negate.
+ required: false
+ choices: ["disable", "enable"]
+
+ dstaddr:
+ description:
+ - Destination address and address group names.
+ required: false
+
+ dsri:
+ description:
+ - Enable DSRI to ignore HTTP server responses.
+ - choice | disable | Disable DSRI.
+ - choice | enable | Enable DSRI.
+ required: false
+ choices: ["disable", "enable"]
+
+ dscp_value:
+ description:
+ - DSCP value.
+ required: false
+
+ dscp_negate:
+ description:
+ - Enable negated DSCP match.
+ - choice | disable | Disable DSCP negate.
+ - choice | enable | Enable DSCP negate.
+ required: false
+ choices: ["disable", "enable"]
+
+ dscp_match:
+ description:
+ - Enable DSCP check.
+ - choice | disable | Disable DSCP check.
+ - choice | enable | Enable DSCP check.
+ required: false
+ choices: ["disable", "enable"]
+
+ dnsfilter_profile:
+ description:
+ - Name of an existing DNS filter profile.
+ required: false
+
+ dlp_sensor:
+ description:
+ - Name of an existing DLP sensor.
+ required: false
+
+ disclaimer:
+ description:
+ - Enable/disable user authentication disclaimer.
+ - choice | disable | Disable user authentication disclaimer.
+ - choice | enable | Enable user authentication disclaimer.
+ required: false
+ choices: ["disable", "enable"]
+
+ diffservcode_rev:
+ description:
+ - Change packet's reverse (reply) DiffServ to this value.
+ required: false
+
+ diffservcode_forward:
+ description:
+ - Change packet's DiffServ to this value.
+ required: false
+
+ diffserv_reverse:
+ description:
+ - Enable to change packet's reverse (reply) DiffServ values to the specified diffservcode-rev value.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ diffserv_forward:
+ description:
+ - Enable to change packet's DiffServ values to the specified diffservcode-forward value.
+ - choice | disable | Disable WAN optimization.
+ - choice | enable | Enable WAN optimization.
+ required: false
+ choices: ["disable", "enable"]
+
+ devices:
+ description:
+ - Names of devices or device groups that can be matched by the policy.
+ required: false
+
+ delay_tcp_npu_session:
+ description:
+ - Enable TCP NPU session delay to guarantee packet order of 3-way handshake.
+ - choice | disable | Disable TCP NPU session delay in order to guarantee packet order of 3-way handshake.
+ - choice | enable | Enable TCP NPU session delay in order to guarantee packet order of 3-way handshake.
+ required: false
+ choices: ["disable", "enable"]
+
+ custom_log_fields:
+ description:
+ - Custom fields to append to log messages for this policy.
+ required: false
+
+ comments:
+ description:
+ - Comment.
+ required: false
+
+ capture_packet:
+ description:
+ - Enable/disable capture packets.
+ - choice | disable | Disable capture packets.
+ - choice | enable | Enable capture packets.
+ required: false
+ choices: ["disable", "enable"]
+
+ captive_portal_exempt:
+ description:
+ - Enable to exempt some users from the captive portal.
+ - choice | disable | Disable exemption of captive portal.
+ - choice | enable | Enable exemption of captive portal.
+ required: false
+ choices: ["disable", "enable"]
+
+ block_notification:
+ description:
+ - Enable/disable block notification.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ av_profile:
+ description:
+ - Name of an existing Antivirus profile.
+ required: false
+
+ auto_asic_offload:
+ description:
+ - Enable/disable offloading security profile processing to CP processors.
+ - choice | disable | Disable ASIC offloading.
+ - choice | enable | Enable auto ASIC offloading.
+ required: false
+ choices: ["disable", "enable"]
+
+ auth_redirect_addr:
+ description:
+ - HTTP-to-HTTPS redirect address for firewall authentication.
+ required: false
+
+ auth_path:
+ description:
+ - Enable/disable authentication-based routing.
+ - choice | disable | Disable authentication-based routing.
+ - choice | enable | Enable authentication-based routing.
+ required: false
+ choices: ["disable", "enable"]
+
+ auth_cert:
+ description:
+ - HTTPS server certificate for policy authentication.
+ required: false
+
+ application_list:
+ description:
+ - Name of an existing Application list.
+ required: false
+
+ application:
+ description:
+ - Application ID list.
+ required: false
+
+ app_group:
+ description:
+ - Application group names.
+ required: false
+
+ app_category:
+ description:
+ - Application category ID list.
+ required: false
+
+ action:
+ description:
+ - Policy action (allow/deny/ipsec).
+ - choice | deny | Blocks sessions that match the firewall policy.
+ - choice | accept | Allows session that match the firewall policy.
+ - choice | ipsec | Firewall policy becomes a policy-based IPsec VPN policy.
+ required: false
+ choices: ["deny", "accept", "ipsec"]
+
+ vpn_dst_node:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED. This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ required: false
+
+ vpn_dst_node_host:
+ description:
+ - VPN Destination Node Host.
+ required: false
+
+ vpn_dst_node_seq:
+ description:
+ - VPN Destination Node Seq.
+ required: false
+
+ vpn_dst_node_subnet:
+ description:
+ - VPN Destination Node Seq.
+ required: false
+
+ vpn_src_node:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED. This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ required: false
+
+ vpn_src_node_host:
+ description:
+ - VPN Source Node Host.
+ required: false
+
+ vpn_src_node_seq:
+ description:
+ - VPN Source Node Seq.
+ required: false
+
+ vpn_src_node_subnet:
+ description:
+ - VPN Source Node.
+ required: false
+
+
+'''
+
+EXAMPLES = '''
+- name: ADD VERY BASIC IPV4 POLICY WITH NO NAT (WIDE OPEN)
+ community.fortios.fmgr_fwpol_ipv4:
+ mode: "set"
+ adom: "ansible"
+ package_name: "default"
+ name: "Basic_IPv4_Policy"
+ comments: "Created by Ansible"
+ action: "accept"
+ dstaddr: "all"
+ srcaddr: "all"
+ dstintf: "any"
+ srcintf: "any"
+ logtraffic: "utm"
+ service: "ALL"
+ schedule: "always"
+
+- name: ADD VERY BASIC IPV4 POLICY WITH NAT AND MULTIPLE ENTRIES
+ community.fortios.fmgr_fwpol_ipv4:
+ mode: "set"
+ adom: "ansible"
+ package_name: "default"
+ name: "Basic_IPv4_Policy_2"
+ comments: "Created by Ansible"
+ action: "accept"
+ dstaddr: "google-play"
+ srcaddr: "all"
+ dstintf: "any"
+ srcintf: "any"
+ logtraffic: "utm"
+ service: "HTTP, HTTPS"
+ schedule: "always"
+ nat: "enable"
+ users: "karen, kevin"
+
+- name: ADD VERY BASIC IPV4 POLICY WITH NAT AND MULTIPLE ENTRIES AND SEC PROFILES
+ community.fortios.fmgr_fwpol_ipv4:
+ mode: "set"
+ adom: "ansible"
+ package_name: "default"
+ name: "Basic_IPv4_Policy_3"
+ comments: "Created by Ansible"
+ action: "accept"
+ dstaddr: "google-play, autoupdate.opera.com"
+ srcaddr: "corp_internal"
+ dstintf: "zone_wan1, zone_wan2"
+ srcintf: "zone_int1"
+ logtraffic: "utm"
+ service: "HTTP, HTTPS"
+ schedule: "always"
+ nat: "enable"
+ users: "karen, kevin"
+ av_profile: "sniffer-profile"
+ ips_sensor: "default"
+
+'''
+
+RETURN = """
+api_result:
+ description: full API response, includes status code and message
+ returned: always
+ type: str
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.connection import Connection
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.fortimanager import FortiManagerHandler
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGBaseException
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRCommon
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRMethods
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import DEFAULT_RESULT_OBJ
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FAIL_SOCKET_MSG
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import prepare_dict
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import scrub_dict
+
+
+def fmgr_firewall_policy_modify(fmgr, paramgram):
+ """
+ fmgr_firewall_policy -- Add/Set/Deletes Firewall Policy Objects defined in the "paramgram"
+
+ :param fmgr: The fmgr object instance from fmgr_utils.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+
+ mode = paramgram["mode"]
+ adom = paramgram["adom"]
+ # INIT A BASIC OBJECTS
+ response = DEFAULT_RESULT_OBJ
+ url = ""
+ datagram = {}
+
+ # EVAL THE MODE PARAMETER FOR SET OR ADD
+ if mode in ['set', 'add', 'update']:
+ url = '/pm/config/adom/{adom}/pkg/{pkg}/firewall/policy'.format(adom=adom, pkg=paramgram["package_name"])
+ datagram = scrub_dict((prepare_dict(paramgram)))
+ del datagram["package_name"]
+ datagram = fmgr._tools.split_comma_strings_into_lists(datagram)
+
+ # EVAL THE MODE PARAMETER FOR DELETE
+ elif mode == "delete":
+ url = '/pm/config/adom/{adom}/pkg/{pkg}/firewall' \
+ '/policy/{policyid}'.format(adom=paramgram["adom"],
+ pkg=paramgram["package_name"],
+ policyid=paramgram["policyid"])
+ datagram = {
+ "policyid": paramgram["policyid"]
+ }
+
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+ return response
+
+
+#############
+# END METHODS
+#############
+
+
+def main():
+ argument_spec = dict(
+ adom=dict(type="str", default="root"),
+ mode=dict(choices=["add", "set", "delete", "update"], type="str", default="add"),
+ package_name=dict(type="str", required=False, default="default"),
+ fail_on_missing_dependency=dict(type="str", required=False, default="disable", choices=["enable",
+ "disable"]),
+ wsso=dict(required=False, type="str", choices=["disable", "enable"]),
+ webfilter_profile=dict(required=False, type="str"),
+ webcache_https=dict(required=False, type="str", choices=["disable", "enable"]),
+ webcache=dict(required=False, type="str", choices=["disable", "enable"]),
+ wccp=dict(required=False, type="str", choices=["disable", "enable"]),
+ wanopt_profile=dict(required=False, type="str"),
+ wanopt_peer=dict(required=False, type="str"),
+ wanopt_passive_opt=dict(required=False, type="str", choices=["default", "transparent", "non-transparent"]),
+ wanopt_detection=dict(required=False, type="str", choices=["active", "passive", "off"]),
+ wanopt=dict(required=False, type="str", choices=["disable", "enable"]),
+ waf_profile=dict(required=False, type="str"),
+ vpntunnel=dict(required=False, type="str"),
+ voip_profile=dict(required=False, type="str"),
+ vlan_filter=dict(required=False, type="str"),
+ vlan_cos_rev=dict(required=False, type="int"),
+ vlan_cos_fwd=dict(required=False, type="int"),
+ utm_status=dict(required=False, type="str", choices=["disable", "enable"]),
+ users=dict(required=False, type="str"),
+ url_category=dict(required=False, type="str"),
+ traffic_shaper_reverse=dict(required=False, type="str"),
+ traffic_shaper=dict(required=False, type="str"),
+ timeout_send_rst=dict(required=False, type="str", choices=["disable", "enable"]),
+ tcp_session_without_syn=dict(required=False, type="str", choices=["all", "data-only", "disable"]),
+ tcp_mss_sender=dict(required=False, type="int"),
+ tcp_mss_receiver=dict(required=False, type="int"),
+ status=dict(required=False, type="str", choices=["disable", "enable"]),
+ ssl_ssh_profile=dict(required=False, type="str"),
+ ssl_mirror_intf=dict(required=False, type="str"),
+ ssl_mirror=dict(required=False, type="str", choices=["disable", "enable"]),
+ ssh_filter_profile=dict(required=False, type="str"),
+ srcintf=dict(required=False, type="str"),
+ srcaddr_negate=dict(required=False, type="str", choices=["disable", "enable"]),
+ srcaddr=dict(required=False, type="str"),
+ spamfilter_profile=dict(required=False, type="str"),
+ session_ttl=dict(required=False, type="int"),
+ service_negate=dict(required=False, type="str", choices=["disable", "enable"]),
+ service=dict(required=False, type="str"),
+ send_deny_packet=dict(required=False, type="str", choices=["disable", "enable"]),
+ schedule_timeout=dict(required=False, type="str", choices=["disable", "enable"]),
+ schedule=dict(required=False, type="str"),
+ scan_botnet_connections=dict(required=False, type="str", choices=["disable", "block", "monitor"]),
+ rtp_nat=dict(required=False, type="str", choices=["disable", "enable"]),
+ rtp_addr=dict(required=False, type="str"),
+ rsso=dict(required=False, type="str", choices=["disable", "enable"]),
+ replacemsg_override_group=dict(required=False, type="str"),
+ redirect_url=dict(required=False, type="str"),
+ radius_mac_auth_bypass=dict(required=False, type="str", choices=["disable", "enable"]),
+ profile_type=dict(required=False, type="str", choices=["single", "group"]),
+ profile_protocol_options=dict(required=False, type="str"),
+ profile_group=dict(required=False, type="str"),
+ poolname=dict(required=False, type="str"),
+ policyid=dict(required=False, type="str"),
+ permit_stun_host=dict(required=False, type="str", choices=["disable", "enable"]),
+ permit_any_host=dict(required=False, type="str", choices=["disable", "enable"]),
+ per_ip_shaper=dict(required=False, type="str"),
+ outbound=dict(required=False, type="str", choices=["disable", "enable"]),
+ ntlm_guest=dict(required=False, type="str", choices=["disable", "enable"]),
+ ntlm_enabled_browsers=dict(required=False, type="str"),
+ ntlm=dict(required=False, type="str", choices=["disable", "enable"]),
+ np_acceleration=dict(required=False, type="str", choices=["disable", "enable"]),
+ natoutbound=dict(required=False, type="str", choices=["disable", "enable"]),
+ natip=dict(required=False, type="str"),
+ natinbound=dict(required=False, type="str", choices=["disable", "enable"]),
+ nat=dict(required=False, type="str", choices=["disable", "enable"]),
+ name=dict(required=False, type="str"),
+ mms_profile=dict(required=False, type="str"),
+ match_vip=dict(required=False, type="str", choices=["disable", "enable"]),
+ logtraffic_start=dict(required=False, type="str", choices=["disable", "enable"]),
+ logtraffic=dict(required=False, type="str", choices=["disable", "all", "utm"]),
+ learning_mode=dict(required=False, type="str", choices=["disable", "enable"]),
+ label=dict(required=False, type="str"),
+ ips_sensor=dict(required=False, type="str"),
+ ippool=dict(required=False, type="str", choices=["disable", "enable"]),
+ internet_service_src_negate=dict(required=False, type="str", choices=["disable", "enable"]),
+ internet_service_src_id=dict(required=False, type="str"),
+ internet_service_src_custom=dict(required=False, type="str"),
+ internet_service_src=dict(required=False, type="str", choices=["disable", "enable"]),
+ internet_service_negate=dict(required=False, type="str", choices=["disable", "enable"]),
+ internet_service_id=dict(required=False, type="str"),
+ internet_service_custom=dict(required=False, type="str"),
+ internet_service=dict(required=False, type="str", choices=["disable", "enable"]),
+ inbound=dict(required=False, type="str", choices=["disable", "enable"]),
+ identity_based_route=dict(required=False, type="str"),
+ icap_profile=dict(required=False, type="str"),
+ gtp_profile=dict(required=False, type="str"),
+ groups=dict(required=False, type="str"),
+ global_label=dict(required=False, type="str"),
+ fsso_agent_for_ntlm=dict(required=False, type="str"),
+ fsso=dict(required=False, type="str", choices=["disable", "enable"]),
+ fixedport=dict(required=False, type="str", choices=["disable", "enable"]),
+ firewall_session_dirty=dict(required=False, type="str", choices=["check-all", "check-new"]),
+ dstintf=dict(required=False, type="str"),
+ dstaddr_negate=dict(required=False, type="str", choices=["disable", "enable"]),
+ dstaddr=dict(required=False, type="str"),
+ dsri=dict(required=False, type="str", choices=["disable", "enable"]),
+ dscp_value=dict(required=False, type="str"),
+ dscp_negate=dict(required=False, type="str", choices=["disable", "enable"]),
+ dscp_match=dict(required=False, type="str", choices=["disable", "enable"]),
+ dnsfilter_profile=dict(required=False, type="str"),
+ dlp_sensor=dict(required=False, type="str"),
+ disclaimer=dict(required=False, type="str", choices=["disable", "enable"]),
+ diffservcode_rev=dict(required=False, type="str"),
+ diffservcode_forward=dict(required=False, type="str"),
+ diffserv_reverse=dict(required=False, type="str", choices=["disable", "enable"]),
+ diffserv_forward=dict(required=False, type="str", choices=["disable", "enable"]),
+ devices=dict(required=False, type="str"),
+ delay_tcp_npu_session=dict(required=False, type="str", choices=["disable", "enable"]),
+ custom_log_fields=dict(required=False, type="str"),
+ comments=dict(required=False, type="str"),
+ capture_packet=dict(required=False, type="str", choices=["disable", "enable"]),
+ captive_portal_exempt=dict(required=False, type="str", choices=["disable", "enable"]),
+ block_notification=dict(required=False, type="str", choices=["disable", "enable"]),
+ av_profile=dict(required=False, type="str"),
+ auto_asic_offload=dict(required=False, type="str", choices=["disable", "enable"]),
+ auth_redirect_addr=dict(required=False, type="str"),
+ auth_path=dict(required=False, type="str", choices=["disable", "enable"]),
+ auth_cert=dict(required=False, type="str"),
+ application_list=dict(required=False, type="str"),
+ application=dict(required=False, type="str"),
+ app_group=dict(required=False, type="str"),
+ app_category=dict(required=False, type="str"),
+ action=dict(required=False, type="str", choices=["deny", "accept", "ipsec"]),
+ vpn_dst_node=dict(required=False, type="list"),
+ vpn_dst_node_host=dict(required=False, type="str"),
+ vpn_dst_node_seq=dict(required=False, type="str"),
+ vpn_dst_node_subnet=dict(required=False, type="str"),
+ vpn_src_node=dict(required=False, type="list"),
+ vpn_src_node_host=dict(required=False, type="str"),
+ vpn_src_node_seq=dict(required=False, type="str"),
+ vpn_src_node_subnet=dict(required=False, type="str"),
+
+ )
+
+ module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False, )
+ # MODULE PARAMGRAM
+ paramgram = {
+ "mode": module.params["mode"],
+ "adom": module.params["adom"],
+ "package_name": module.params["package_name"],
+ "wsso": module.params["wsso"],
+ "webfilter-profile": module.params["webfilter_profile"],
+ "webcache-https": module.params["webcache_https"],
+ "webcache": module.params["webcache"],
+ "wccp": module.params["wccp"],
+ "wanopt-profile": module.params["wanopt_profile"],
+ "wanopt-peer": module.params["wanopt_peer"],
+ "wanopt-passive-opt": module.params["wanopt_passive_opt"],
+ "wanopt-detection": module.params["wanopt_detection"],
+ "wanopt": module.params["wanopt"],
+ "waf-profile": module.params["waf_profile"],
+ "vpntunnel": module.params["vpntunnel"],
+ "voip-profile": module.params["voip_profile"],
+ "vlan-filter": module.params["vlan_filter"],
+ "vlan-cos-rev": module.params["vlan_cos_rev"],
+ "vlan-cos-fwd": module.params["vlan_cos_fwd"],
+ "utm-status": module.params["utm_status"],
+ "users": module.params["users"],
+ "url-category": module.params["url_category"],
+ "traffic-shaper-reverse": module.params["traffic_shaper_reverse"],
+ "traffic-shaper": module.params["traffic_shaper"],
+ "timeout-send-rst": module.params["timeout_send_rst"],
+ "tcp-session-without-syn": module.params["tcp_session_without_syn"],
+ "tcp-mss-sender": module.params["tcp_mss_sender"],
+ "tcp-mss-receiver": module.params["tcp_mss_receiver"],
+ "status": module.params["status"],
+ "ssl-ssh-profile": module.params["ssl_ssh_profile"],
+ "ssl-mirror-intf": module.params["ssl_mirror_intf"],
+ "ssl-mirror": module.params["ssl_mirror"],
+ "ssh-filter-profile": module.params["ssh_filter_profile"],
+ "srcintf": module.params["srcintf"],
+ "srcaddr-negate": module.params["srcaddr_negate"],
+ "srcaddr": module.params["srcaddr"],
+ "spamfilter-profile": module.params["spamfilter_profile"],
+ "session-ttl": module.params["session_ttl"],
+ "service-negate": module.params["service_negate"],
+ "service": module.params["service"],
+ "send-deny-packet": module.params["send_deny_packet"],
+ "schedule-timeout": module.params["schedule_timeout"],
+ "schedule": module.params["schedule"],
+ "scan-botnet-connections": module.params["scan_botnet_connections"],
+ "rtp-nat": module.params["rtp_nat"],
+ "rtp-addr": module.params["rtp_addr"],
+ "rsso": module.params["rsso"],
+ "replacemsg-override-group": module.params["replacemsg_override_group"],
+ "redirect-url": module.params["redirect_url"],
+ "radius-mac-auth-bypass": module.params["radius_mac_auth_bypass"],
+ "profile-type": module.params["profile_type"],
+ "profile-protocol-options": module.params["profile_protocol_options"],
+ "profile-group": module.params["profile_group"],
+ "poolname": module.params["poolname"],
+ "policyid": module.params["policyid"],
+ "permit-stun-host": module.params["permit_stun_host"],
+ "permit-any-host": module.params["permit_any_host"],
+ "per-ip-shaper": module.params["per_ip_shaper"],
+ "outbound": module.params["outbound"],
+ "ntlm-guest": module.params["ntlm_guest"],
+ "ntlm-enabled-browsers": module.params["ntlm_enabled_browsers"],
+ "ntlm": module.params["ntlm"],
+ "np-acceleration": module.params["np_acceleration"],
+ "natoutbound": module.params["natoutbound"],
+ "natip": module.params["natip"],
+ "natinbound": module.params["natinbound"],
+ "nat": module.params["nat"],
+ "name": module.params["name"],
+ "mms-profile": module.params["mms_profile"],
+ "match-vip": module.params["match_vip"],
+ "logtraffic-start": module.params["logtraffic_start"],
+ "logtraffic": module.params["logtraffic"],
+ "learning-mode": module.params["learning_mode"],
+ "label": module.params["label"],
+ "ips-sensor": module.params["ips_sensor"],
+ "ippool": module.params["ippool"],
+ "internet-service-src-negate": module.params["internet_service_src_negate"],
+ "internet-service-src-id": module.params["internet_service_src_id"],
+ "internet-service-src-custom": module.params["internet_service_src_custom"],
+ "internet-service-src": module.params["internet_service_src"],
+ "internet-service-negate": module.params["internet_service_negate"],
+ "internet-service-id": module.params["internet_service_id"],
+ "internet-service-custom": module.params["internet_service_custom"],
+ "internet-service": module.params["internet_service"],
+ "inbound": module.params["inbound"],
+ "identity-based-route": module.params["identity_based_route"],
+ "icap-profile": module.params["icap_profile"],
+ "gtp-profile": module.params["gtp_profile"],
+ "groups": module.params["groups"],
+ "global-label": module.params["global_label"],
+ "fsso-agent-for-ntlm": module.params["fsso_agent_for_ntlm"],
+ "fsso": module.params["fsso"],
+ "fixedport": module.params["fixedport"],
+ "firewall-session-dirty": module.params["firewall_session_dirty"],
+ "dstintf": module.params["dstintf"],
+ "dstaddr-negate": module.params["dstaddr_negate"],
+ "dstaddr": module.params["dstaddr"],
+ "dsri": module.params["dsri"],
+ "dscp-value": module.params["dscp_value"],
+ "dscp-negate": module.params["dscp_negate"],
+ "dscp-match": module.params["dscp_match"],
+ "dnsfilter-profile": module.params["dnsfilter_profile"],
+ "dlp-sensor": module.params["dlp_sensor"],
+ "disclaimer": module.params["disclaimer"],
+ "diffservcode-rev": module.params["diffservcode_rev"],
+ "diffservcode-forward": module.params["diffservcode_forward"],
+ "diffserv-reverse": module.params["diffserv_reverse"],
+ "diffserv-forward": module.params["diffserv_forward"],
+ "devices": module.params["devices"],
+ "delay-tcp-npu-session": module.params["delay_tcp_npu_session"],
+ "custom-log-fields": module.params["custom_log_fields"],
+ "comments": module.params["comments"],
+ "capture-packet": module.params["capture_packet"],
+ "captive-portal-exempt": module.params["captive_portal_exempt"],
+ "block-notification": module.params["block_notification"],
+ "av-profile": module.params["av_profile"],
+ "auto-asic-offload": module.params["auto_asic_offload"],
+ "auth-redirect-addr": module.params["auth_redirect_addr"],
+ "auth-path": module.params["auth_path"],
+ "auth-cert": module.params["auth_cert"],
+ "application-list": module.params["application_list"],
+ "application": module.params["application"],
+ "app-group": module.params["app_group"],
+ "app-category": module.params["app_category"],
+ "action": module.params["action"],
+ "vpn_dst_node": {
+ "host": module.params["vpn_dst_node_host"],
+ "seq": module.params["vpn_dst_node_seq"],
+ "subnet": module.params["vpn_dst_node_subnet"],
+ },
+ "vpn_src_node": {
+ "host": module.params["vpn_src_node_host"],
+ "seq": module.params["vpn_src_node_seq"],
+ "subnet": module.params["vpn_src_node_subnet"],
+ }
+ }
+ module.paramgram = paramgram
+ fmgr = None
+ if module._socket_path:
+ connection = Connection(module._socket_path)
+ fmgr = FortiManagerHandler(connection, module)
+ fmgr.tools = FMGRCommon()
+ else:
+ module.fail_json(**FAIL_SOCKET_MSG)
+
+ list_overrides = ['vpn_dst_node', 'vpn_src_node']
+ paramgram = fmgr.tools.paramgram_child_list_override(list_overrides=list_overrides,
+ paramgram=paramgram, module=module)
+
+ # BEGIN MODULE-SPECIFIC LOGIC -- THINGS NEED TO HAPPEN DEPENDING ON THE ENDPOINT AND OPERATION
+ results = DEFAULT_RESULT_OBJ
+ try:
+ if paramgram["mode"] == "delete":
+ # WE NEED TO GET THE POLICY ID FROM THE NAME OF THE POLICY TO DELETE IT
+ url = '/pm/config/adom/{adom}/pkg/{pkg}/firewall' \
+ '/policy/'.format(adom=paramgram["adom"],
+ pkg=paramgram["package_name"])
+ datagram = {
+ "filter": ["name", "==", paramgram["name"]]
+ }
+ response = fmgr.process_request(url, datagram, FMGRMethods.GET)
+ try:
+ if response[1][0]["policyid"]:
+ policy_id = response[1][0]["policyid"]
+ paramgram["policyid"] = policy_id
+ except BaseException:
+ fmgr.return_response(module=module, results=response, good_codes=[0, ], stop_on_success=True,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram),
+ msg="Couldn't find policy ID number for policy name specified.")
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ try:
+ results = fmgr_firewall_policy_modify(fmgr, paramgram)
+ if module.params["fail_on_missing_dependency"] == "disable":
+ fmgr.govern_response(module=module, results=results, good_codes=[0, -9998],
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+ if module.params["fail_on_missing_dependency"] == "enable" and results[0] == -10131:
+ fmgr.govern_response(module=module, results=results, good_codes=[0, ], failed=True, skipped=False,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ return module.exit_json(**results[1])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_fwpol_package.py b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_fwpol_package.py
new file mode 100644
index 00000000..7b65393f
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_fwpol_package.py
@@ -0,0 +1,479 @@
+#!/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: fmgr_fwpol_package
+notes:
+ - Full Documentation at U(https://ftnt-ansible-docs.readthedocs.io/en/latest/).
+author:
+ - Luke Weighall (@lweighall)
+ - Andrew Welsh (@Ghilli3)
+ - Jim Huber (@p4r4n0y1ng)
+short_description: Manages FortiManager Firewall Policies Packages.
+description:
+ - Manages FortiManager Firewall Policies Packages. Policy Packages contain one or more Firewall Policies/Rules and
+ are distritbuted via FortiManager to Fortigates.
+ - This module controls the creation/edit/delete/assign of these packages.
+
+options:
+ adom:
+ description:
+ - The ADOM the configuration should belong to.
+ required: false
+ default: root
+
+ mode:
+ description:
+ - Sets one of three modes for managing the object.
+ choices: ['add', 'set', 'delete']
+ default: add
+
+ name:
+ description:
+ - Name of the FortiManager package or folder.
+ required: True
+
+ object_type:
+ description:
+ - Are we managing packages or folders, or installing packages?
+ required: True
+ choices: ['pkg','folder','install']
+
+ package_folder:
+ description:
+ - Name of the folder you want to put the package into.
+ required: false
+
+ central_nat:
+ description:
+ - Central NAT setting.
+ required: false
+ choices: ['enable', 'disable']
+ default: disable
+
+ fwpolicy_implicit_log:
+ description:
+ - Implicit Log setting for all IPv4 policies in package.
+ required: false
+ choices: ['enable', 'disable']
+ default: disable
+
+ fwpolicy6_implicit_log:
+ description:
+ - Implicit Log setting for all IPv6 policies in package.
+ required: false
+ choices: ['enable', 'disable']
+ default: disable
+
+ inspection_mode:
+ description:
+ - Inspection mode setting for the policies flow or proxy.
+ required: false
+ choices: ['flow', 'proxy']
+ default: flow
+
+ ngfw_mode:
+ description:
+ - NGFW mode setting for the policies flow or proxy.
+ required: false
+ choices: ['profile-based', 'policy-based']
+ default: profile-based
+
+ ssl_ssh_profile:
+ description:
+ - if policy-based ngfw-mode, refer to firewall ssl-ssh-profile.
+ required: false
+
+ scope_members:
+ description:
+ - The devices or scope that you want to assign this policy package to.
+ required: false
+
+ scope_members_vdom:
+ description:
+ - The members VDOM you want to assign the package to.
+ required: false
+ default: root
+
+ parent_folder:
+ description:
+ - The parent folder name you want to add this object under.
+ required: false
+
+'''
+
+
+EXAMPLES = '''
+- name: CREATE BASIC POLICY PACKAGE
+ community.fortios.fmgr_fwpol_package:
+ adom: "ansible"
+ mode: "add"
+ name: "testPackage"
+ object_type: "pkg"
+
+- name: ADD PACKAGE WITH TARGETS
+ community.fortios.fmgr_fwpol_package:
+ mode: "add"
+ adom: "ansible"
+ name: "ansibleTestPackage1"
+ object_type: "pkg"
+ inspection_mode: "flow"
+ ngfw_mode: "profile-based"
+ scope_members: "seattle-fgt02, seattle-fgt03"
+
+- name: ADD FOLDER
+ community.fortios.fmgr_fwpol_package:
+ mode: "add"
+ adom: "ansible"
+ name: "ansibleTestFolder1"
+ object_type: "folder"
+
+- name: ADD PACKAGE INTO PARENT FOLDER
+ community.fortios.fmgr_fwpol_package:
+ mode: "set"
+ adom: "ansible"
+ name: "ansibleTestPackage2"
+ object_type: "pkg"
+ parent_folder: "ansibleTestFolder1"
+
+- name: ADD FOLDER INTO PARENT FOLDER
+ community.fortios.fmgr_fwpol_package:
+ mode: "set"
+ adom: "ansible"
+ name: "ansibleTestFolder2"
+ object_type: "folder"
+ parent_folder: "ansibleTestFolder1"
+
+- name: INSTALL PACKAGE
+ community.fortios.fmgr_fwpol_package:
+ mode: "set"
+ adom: "ansible"
+ name: "ansibleTestPackage1"
+ object_type: "install"
+ scope_members: "seattle-fgt03, seattle-fgt02"
+
+- name: REMOVE PACKAGE
+ community.fortios.fmgr_fwpol_package:
+ mode: "delete"
+ adom: "ansible"
+ name: "ansibleTestPackage1"
+ object_type: "pkg"
+
+- name: REMOVE NESTED PACKAGE
+ community.fortios.fmgr_fwpol_package:
+ mode: "delete"
+ adom: "ansible"
+ name: "ansibleTestPackage2"
+ object_type: "pkg"
+ parent_folder: "ansibleTestFolder1"
+
+- name: REMOVE NESTED FOLDER
+ community.fortios.fmgr_fwpol_package:
+ mode: "delete"
+ adom: "ansible"
+ name: "ansibleTestFolder2"
+ object_type: "folder"
+ parent_folder: "ansibleTestFolder1"
+
+- name: REMOVE FOLDER
+ community.fortios.fmgr_fwpol_package:
+ mode: "delete"
+ adom: "ansible"
+ name: "ansibleTestFolder1"
+ object_type: "folder"
+'''
+RETURN = """
+api_result:
+ description: full API response, includes status code and message
+ returned: always
+ type: str
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.connection import Connection
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.fortimanager import FortiManagerHandler
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGBaseException
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRCommon
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import DEFAULT_RESULT_OBJ
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FAIL_SOCKET_MSG
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRMethods
+
+
+def fmgr_fwpol_package(fmgr, paramgram):
+ """
+ This function will create FMGR Firewall Policy Packages, or delete them. It is also capable of assigning packages.
+ This function DOES NOT install the package. See the function fmgr_fwpol_package_install()
+
+ :param fmgr: The fmgr object instance from fmgr_utils.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ if paramgram["mode"] in ['set', 'add']:
+ url = '/pm/pkg/adom/{adom}'.format(adom=paramgram["adom"])
+ members_list = []
+
+ # CHECK FOR SCOPE MEMBERS AND CREATE THAT DICT
+ if paramgram["scope_members"] is not None:
+ members = FMGRCommon.split_comma_strings_into_lists(paramgram["scope_members"])
+ for member in members:
+ scope_dict = {
+ "name": member,
+ "vdom": paramgram["scope_members_vdom"],
+ }
+ members_list.append(scope_dict)
+
+ # IF PARENT FOLDER IS NOT DEFINED
+ if paramgram["parent_folder"] is None:
+ datagram = {
+ "type": paramgram["object_type"],
+ "name": paramgram["name"],
+ "scope member": members_list,
+ "package settings": {
+ "central-nat": paramgram["central-nat"],
+ "fwpolicy-implicit-log": paramgram["fwpolicy-implicit-log"],
+ "fwpolicy6-implicit-log": paramgram["fwpolicy6-implicit-log"],
+ "inspection-mode": paramgram["inspection-mode"],
+ "ngfw-mode": paramgram["ngfw-mode"],
+ }
+ }
+
+ if paramgram["ngfw-mode"] == "policy-based" and paramgram["ssl-ssh-profile"] is not None:
+ datagram["package settings"]["ssl-ssh-profile"] = paramgram["ssl-ssh-profile"]
+
+ # IF PARENT FOLDER IS DEFINED
+ if paramgram["parent_folder"] is not None:
+ datagram = {
+ "type": "folder",
+ "name": paramgram["parent_folder"],
+ "subobj": [{
+ "name": paramgram["name"],
+ "scope member": members_list,
+ "type": "pkg",
+ "package settings": {
+ "central-nat": paramgram["central-nat"],
+ "fwpolicy-implicit-log": paramgram["fwpolicy-implicit-log"],
+ "fwpolicy6-implicit-log": paramgram["fwpolicy6-implicit-log"],
+ "inspection-mode": paramgram["inspection-mode"],
+ "ngfw-mode": paramgram["ngfw-mode"],
+ }
+ }]
+ }
+
+ # NORMAL DELETE NO PARENT
+ if paramgram["mode"] == "delete" and paramgram["parent_folder"] is None:
+ datagram = {
+ "name": paramgram["name"]
+ }
+ # SET DELETE URL
+ url = '/pm/pkg/adom/{adom}/{name}'.format(adom=paramgram["adom"], name=paramgram["name"])
+
+ # DELETE WITH PARENT
+ if paramgram["mode"] == "delete" and paramgram["parent_folder"] is not None:
+ datagram = {
+ "name": paramgram["name"]
+ }
+ # SET DELETE URL
+ url = '/pm/pkg/adom/{adom}/{parent_folder}/{name}'.format(adom=paramgram["adom"],
+ name=paramgram["name"],
+ parent_folder=paramgram["parent_folder"])
+
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+ return response
+
+
+def fmgr_fwpol_package_folder(fmgr, paramgram):
+ """
+ This function will create folders for firewall packages. It can create down to two levels deep.
+ We haven't yet tested for any more layers below two levels.
+ parent_folders for multiple levels may need to defined as "level1/level2/level3" for the URL parameters and such.
+
+ :param fmgr: The fmgr object instance from fmgr_utils.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ if paramgram["mode"] in ['set', 'add']:
+ url = '/pm/pkg/adom/{adom}'.format(adom=paramgram["adom"])
+ # IF PARENT FOLDER IS NOT DEFINED
+ if paramgram["parent_folder"] is None:
+ datagram = {
+ "type": paramgram["object_type"],
+ "name": paramgram["name"],
+ }
+
+ # IF PARENT FOLDER IS DEFINED
+ if paramgram["parent_folder"] is not None:
+ datagram = {
+ "type": paramgram["object_type"],
+ "name": paramgram["parent_folder"],
+ "subobj": [{
+ "name": paramgram["name"],
+ "type": paramgram["object_type"],
+
+ }]
+ }
+ # NORMAL DELETE NO PARENT
+ if paramgram["mode"] == "delete" and paramgram["parent_folder"] is None:
+ datagram = {
+ "name": paramgram["name"]
+ }
+ # SET DELETE URL
+ url = '/pm/pkg/adom/{adom}/{name}'.format(adom=paramgram["adom"], name=paramgram["name"])
+
+ # DELETE WITH PARENT
+ if paramgram["mode"] == "delete" and paramgram["parent_folder"] is not None:
+ datagram = {
+ "name": paramgram["name"]
+ }
+ # SET DELETE URL
+ url = '/pm/pkg/adom/{adom}/{parent_folder}/{name}'.format(adom=paramgram["adom"],
+ name=paramgram["name"],
+ parent_folder=paramgram["parent_folder"])
+
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+ return response
+
+
+def fmgr_fwpol_package_install(fmgr, paramgram):
+ """
+ This method/function installs FMGR FW Policy Packages to the scope members defined in the playbook.
+
+ :param fmgr: The fmgr object instance from fmgr_utils.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ # INIT BLANK MEMBERS LIST
+ members_list = []
+ # USE THE PARSE CSV FUNCTION TO GET A LIST FORMAT OF THE MEMBERS
+ members = FMGRCommon.split_comma_strings_into_lists(paramgram["scope_members"])
+ # USE THAT LIST TO BUILD THE DICTIONARIES NEEDED, AND ADD TO THE BLANK MEMBERS LIST
+ for member in members:
+ scope_dict = {
+ "name": member,
+ "vdom": paramgram["scope_members_vdom"],
+ }
+ members_list.append(scope_dict)
+ # THEN FOR THE DATAGRAM, USING THE MEMBERS LIST CREATED ABOVE
+ datagram = {
+ "adom": paramgram["adom"],
+ "pkg": paramgram["name"],
+ "scope": members_list
+ }
+ # EXECUTE THE INSTALL REQUEST
+ url = '/securityconsole/install/package'
+ response = fmgr.process_request(url, datagram, FMGRMethods.EXEC)
+ return response
+
+
+def main():
+ argument_spec = dict(
+ adom=dict(required=False, type="str", default="root"),
+ mode=dict(choices=["add", "set", "delete"], type="str", default="add"),
+
+ name=dict(required=False, type="str"),
+ object_type=dict(required=True, type="str", choices=['pkg', 'folder', 'install']),
+ package_folder=dict(required=False, type="str"),
+ central_nat=dict(required=False, type="str", default="disable", choices=['enable', 'disable']),
+ fwpolicy_implicit_log=dict(required=False, type="str", default="disable", choices=['enable', 'disable']),
+ fwpolicy6_implicit_log=dict(required=False, type="str", default="disable", choices=['enable', 'disable']),
+ inspection_mode=dict(required=False, type="str", default="flow", choices=['flow', 'proxy']),
+ ngfw_mode=dict(required=False, type="str", default="profile-based", choices=['profile-based', 'policy-based']),
+ ssl_ssh_profile=dict(required=False, type="str"),
+ scope_members=dict(required=False, type="str"),
+ scope_members_vdom=dict(required=False, type="str", default="root"),
+ parent_folder=dict(required=False, type="str"),
+
+ )
+
+ module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False, )
+ # MODULE DATAGRAM
+ paramgram = {
+ "adom": module.params["adom"],
+ "name": module.params["name"],
+ "mode": module.params["mode"],
+ "object_type": module.params["object_type"],
+ "package-folder": module.params["package_folder"],
+ "central-nat": module.params["central_nat"],
+ "fwpolicy-implicit-log": module.params["fwpolicy_implicit_log"],
+ "fwpolicy6-implicit-log": module.params["fwpolicy6_implicit_log"],
+ "inspection-mode": module.params["inspection_mode"],
+ "ngfw-mode": module.params["ngfw_mode"],
+ "ssl-ssh-profile": module.params["ssl_ssh_profile"],
+ "scope_members": module.params["scope_members"],
+ "scope_members_vdom": module.params["scope_members_vdom"],
+ "parent_folder": module.params["parent_folder"],
+ }
+ module.paramgram = paramgram
+ fmgr = None
+ if module._socket_path:
+ connection = Connection(module._socket_path)
+ fmgr = FortiManagerHandler(connection, module)
+ fmgr.tools = FMGRCommon()
+ else:
+ module.fail_json(**FAIL_SOCKET_MSG)
+
+ # BEGIN MODULE-SPECIFIC LOGIC -- THINGS NEED TO HAPPEN DEPENDING ON THE ENDPOINT AND OPERATION
+ results = DEFAULT_RESULT_OBJ
+
+ try:
+ if paramgram["object_type"] == "pkg":
+ results = fmgr_fwpol_package(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ try:
+ # IF THE object_type IS FOLDER LETS RUN THAT METHOD
+ if paramgram["object_type"] == "folder":
+ results = fmgr_fwpol_package_folder(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ try:
+ # IF THE object_type IS INSTALL AND NEEDED PARAMETERS ARE DEFINED INSTALL THE PACKAGE
+ if paramgram["scope_members"] is not None and paramgram["name"] is not None and\
+ paramgram["object_type"] == "install":
+ results = fmgr_fwpol_package_install(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ return module.exit_json(**results[1])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_ha.py b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_ha.py
new file mode 100644
index 00000000..e24f1146
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_ha.py
@@ -0,0 +1,349 @@
+#!/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: fmgr_ha
+notes:
+ - Full Documentation at U(https://ftnt-ansible-docs.readthedocs.io/en/latest/).
+author:
+ - Luke Weighall (@lweighall)
+ - Andrew Welsh (@Ghilli3)
+ - Jim Huber (@p4r4n0y1ng)
+short_description: Manages the High-Availability State of FortiManager Clusters and Nodes.
+description: Change HA state or settings of FortiManager nodes (Standalone/Master/Slave).
+
+options:
+ fmgr_ha_mode:
+ description:
+ - Sets the role of the FortiManager host for HA.
+ required: false
+ choices: ["standalone", "master", "slave"]
+
+ fmgr_ha_peer_ipv4:
+ description:
+ - Sets the IPv4 address of a HA peer.
+ required: false
+
+ fmgr_ha_peer_ipv6:
+ description:
+ - Sets the IPv6 address of a HA peer.
+ required: false
+
+ fmgr_ha_peer_sn:
+ description:
+ - Sets the HA Peer Serial Number.
+ required: false
+
+ fmgr_ha_peer_status:
+ description:
+ - Sets the peer status to enable or disable.
+ required: false
+ choices: ["enable", "disable"]
+
+ fmgr_ha_cluster_pw:
+ description:
+ - Sets the password for the HA cluster. Only required once. System remembers between HA mode switches.
+ required: false
+
+ fmgr_ha_cluster_id:
+ description:
+ - Sets the ID number of the HA cluster. Defaults to 1.
+ required: false
+ default: 1
+
+ fmgr_ha_hb_threshold:
+ description:
+ - Sets heartbeat lost threshold (1-255).
+ required: false
+ default: 3
+
+ fmgr_ha_hb_interval:
+ description:
+ - Sets the heartbeat interval (1-255).
+ required: false
+ default: 5
+
+ fmgr_ha_file_quota:
+ description:
+ - Sets the File quota in MB (2048-20480).
+ required: false
+ default: 4096
+'''
+
+
+EXAMPLES = '''
+- name: SET FORTIMANAGER HA NODE TO MASTER
+ community.fortios.fmgr_ha:
+ fmgr_ha_mode: "master"
+ fmgr_ha_cluster_pw: "fortinet"
+ fmgr_ha_cluster_id: "1"
+
+- name: SET FORTIMANAGER HA NODE TO SLAVE
+ community.fortios.fmgr_ha:
+ fmgr_ha_mode: "slave"
+ fmgr_ha_cluster_pw: "fortinet"
+ fmgr_ha_cluster_id: "1"
+
+- name: SET FORTIMANAGER HA NODE TO STANDALONE
+ community.fortios.fmgr_ha:
+ fmgr_ha_mode: "standalone"
+
+- name: ADD FORTIMANAGER HA PEER
+ community.fortios.fmgr_ha:
+ fmgr_ha_peer_ipv4: "192.168.1.254"
+ fmgr_ha_peer_sn: "FMG-VM1234567890"
+ fmgr_ha_peer_status: "enable"
+
+- name: CREATE CLUSTER ON MASTER
+ community.fortios.fmgr_ha:
+ fmgr_ha_mode: "master"
+ fmgr_ha_cluster_pw: "fortinet"
+ fmgr_ha_cluster_id: "1"
+ fmgr_ha_hb_threshold: "10"
+ fmgr_ha_hb_interval: "15"
+ fmgr_ha_file_quota: "2048"
+'''
+RETURN = """
+api_result:
+ description: full API response, includes status code and message
+ returned: always
+ type: str
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.connection import Connection
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.fortimanager import FortiManagerHandler
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGBaseException
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRCommon
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRMethods
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import DEFAULT_RESULT_OBJ
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FAIL_SOCKET_MSG
+
+
+def fmgr_set_ha_mode(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ # INIT A BASIC OBJECTS
+ response = DEFAULT_RESULT_OBJ
+ url = ""
+ datagram = {}
+
+ if paramgram["fmgr_ha_cluster_pw"] is not None and str(paramgram["fmgr_ha_mode"].lower()) != "standalone":
+ datagram = {
+ "mode": paramgram["fmgr_ha_mode"],
+ "file-quota": paramgram["fmgr_ha_file_quota"],
+ "hb-interval": paramgram["fmgr_ha_hb_interval"],
+ "hb-lost-threshold": paramgram["fmgr_ha_hb_threshold"],
+ "password": paramgram["fmgr_ha_cluster_pw"],
+ "clusterid": paramgram["fmgr_ha_cluster_id"]
+ }
+ elif str(paramgram["fmgr_ha_mode"].lower()) == "standalone":
+ datagram = {
+ "mode": paramgram["fmgr_ha_mode"],
+ "file-quota": paramgram["fmgr_ha_file_quota"],
+ "hb-interval": paramgram["fmgr_ha_hb_interval"],
+ "hb-lost-threshold": paramgram["fmgr_ha_hb_threshold"],
+ "clusterid": paramgram["fmgr_ha_cluster_id"]
+ }
+
+ url = '/cli/global/system/ha'
+ response = fmgr.process_request(url, datagram, FMGRMethods.SET)
+ return response
+
+
+def fmgr_get_ha_peer_list(fmgr):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ # INIT A BASIC OBJECTS
+ response = DEFAULT_RESULT_OBJ
+
+ datagram = {}
+ paramgram = {}
+
+ url = '/cli/global/system/ha/peer/'
+ response = fmgr.process_request(url, datagram, FMGRMethods.GET)
+ return response
+
+
+def fmgr_set_ha_peer(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+
+ datagram = {
+ "ip": paramgram["fmgr_ha_peer_ipv4"],
+ "ip6": paramgram["fmgr_ha_peer_ipv6"],
+ "serial-number": paramgram["fmgr_ha_peer_sn"],
+ "status": paramgram["fmgr_ha_peer_status"],
+ "id": paramgram["peer_id"]
+ }
+
+ url = '/cli/global/system/ha/peer/'
+ response = fmgr.process_request(url, datagram, FMGRMethods.SET)
+ return response
+
+
+def main():
+ argument_spec = dict(
+ fmgr_ha_mode=dict(required=False, type="str", choices=["standalone", "master", "slave"]),
+ fmgr_ha_cluster_pw=dict(required=False, type="str", no_log=True),
+ fmgr_ha_peer_status=dict(required=False, type="str", choices=["enable", "disable"]),
+ fmgr_ha_peer_sn=dict(required=False, type="str"),
+ fmgr_ha_peer_ipv4=dict(required=False, type="str"),
+ fmgr_ha_peer_ipv6=dict(required=False, type="str"),
+ fmgr_ha_hb_threshold=dict(required=False, type="int", default=3),
+ fmgr_ha_hb_interval=dict(required=False, type="int", default=5),
+ fmgr_ha_file_quota=dict(required=False, type="int", default=4096),
+ fmgr_ha_cluster_id=dict(required=False, type="int", default=1)
+ )
+
+ required_if = [
+ ['fmgr_ha_peer_ipv4', 'present', ['fmgr_ha_peer_sn', 'fmgr_ha_peer_status']],
+ ['fmgr_ha_peer_ipv6', 'present', ['fmgr_ha_peer_sn', 'fmgr_ha_peer_status']],
+ ['fmgr_ha_mode', 'master', ['fmgr_ha_cluster_pw', 'fmgr_ha_cluster_id']],
+ ['fmgr_ha_mode', 'slave', ['fmgr_ha_cluster_pw', 'fmgr_ha_cluster_id']],
+ ]
+
+ module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False, required_if=required_if)
+ paramgram = {
+ "fmgr_ha_mode": module.params["fmgr_ha_mode"],
+ "fmgr_ha_cluster_pw": module.params["fmgr_ha_cluster_pw"],
+ "fmgr_ha_peer_status": module.params["fmgr_ha_peer_status"],
+ "fmgr_ha_peer_sn": module.params["fmgr_ha_peer_sn"],
+ "fmgr_ha_peer_ipv4": module.params["fmgr_ha_peer_ipv4"],
+ "fmgr_ha_peer_ipv6": module.params["fmgr_ha_peer_ipv6"],
+ "fmgr_ha_hb_threshold": module.params["fmgr_ha_hb_threshold"],
+ "fmgr_ha_hb_interval": module.params["fmgr_ha_hb_interval"],
+ "fmgr_ha_file_quota": module.params["fmgr_ha_file_quota"],
+ "fmgr_ha_cluster_id": module.params["fmgr_ha_cluster_id"],
+ }
+ module.paramgram = paramgram
+ fmgr = None
+ if module._socket_path:
+ connection = Connection(module._socket_path)
+ fmgr = FortiManagerHandler(connection, module)
+ fmgr.tools = FMGRCommon()
+ else:
+ module.fail_json(**FAIL_SOCKET_MSG)
+
+ # INIT FLAGS AND COUNTERS
+ get_ha_peers = 0
+ results = DEFAULT_RESULT_OBJ
+ try:
+ if any(v is not None for v in (paramgram["fmgr_ha_peer_sn"], paramgram["fmgr_ha_peer_ipv4"],
+ paramgram["fmgr_ha_peer_ipv6"], paramgram["fmgr_ha_peer_status"])):
+ get_ha_peers = 1
+ except Exception as err:
+ raise FMGBaseException(err)
+ try:
+ # IF HA MODE IS NOT NULL, SWITCH THAT
+ if paramgram["fmgr_ha_mode"] is not None:
+ if (str.lower(paramgram["fmgr_ha_mode"]) != "standalone" and paramgram["fmgr_ha_cluster_pw"] is not None)\
+ or str.lower(paramgram["fmgr_ha_mode"]) == "standalone":
+ results = fmgr_set_ha_mode(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results, stop_on_success=False,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+
+ elif str.lower(paramgram["fmgr_ha_mode"]) != "standalone" and\
+ paramgram["fmgr_ha_mode"] is not None and\
+ paramgram["fmgr_ha_cluster_pw"] is None:
+ module.exit_json(msg="If setting HA Mode of MASTER or SLAVE, you must specify a cluster password")
+
+ except Exception as err:
+ raise FMGBaseException(err)
+ # IF GET_HA_PEERS IS ENABLED, LETS PROCESS THE PEERS
+ try:
+ if get_ha_peers == 1:
+ # GET THE CURRENT LIST OF PEERS FROM THE NODE
+ peers = fmgr_get_ha_peer_list(fmgr)
+ # GET LENGTH OF RETURNED PEERS LIST AND ADD ONE FOR THE NEXT ID
+ paramgram["next_peer_id"] = len(peers[1]) + 1
+ # SET THE ACTUAL NUMBER OF PEERS
+ num_of_peers = len(peers[1])
+ # SET THE PEER ID FOR DISABLE METHOD
+ paramgram["peer_id"] = len(peers) - 1
+ # SET THE PEER LOOPCOUNT TO 1 TO START THE LOOP
+ peer_loopcount = 1
+
+ # LOOP THROUGH PEERS TO FIND THE SERIAL NUMBER MATCH TO GET THE RIGHT PEER ID
+ # IDEA BEING WE DON'T WANT TO SUBMIT A BAD peer_id THAT DOESN'T JIVE WITH CURRENT DB ON FMG
+ # SO LETS SEARCH FOR IT, AND IF WE FIND IT, WE WILL CHANGE THE PEER ID VARIABLES TO MATCH
+ # IF NOT FOUND, LIFE GOES ON AND WE ASSUME THAT WE'RE ADDING A PEER
+ # AT WHICH POINT THE next_peer_id VARIABLE WILL HAVE THE RIGHT PRIMARY KEY
+
+ if paramgram["fmgr_ha_peer_sn"] is not None:
+ while peer_loopcount <= num_of_peers:
+ # GET THE SERIAL NUMBER FOR CURRENT PEER IN LOOP TO COMPARE TO SN IN PLAYBOOK
+ try:
+ sn_compare = peers[1][peer_loopcount - 1]["serial-number"]
+ # IF THE SN IN THE PEERS MATCHES THE PLAYBOOK SN, SET THE IDS
+ if sn_compare == paramgram["fmgr_ha_peer_sn"]:
+ paramgram["peer_id"] = peer_loopcount
+ paramgram["next_peer_id"] = paramgram["peer_id"]
+ except Exception as err:
+ raise FMGBaseException(err)
+ # ADVANCE THE LOOP AND REPEAT UNTIL DONE
+ peer_loopcount += 1
+
+ # IF THE PEER STATUS ISN'T IN THE PLAYBOOK, ASSUME ITS ENABLE
+ if paramgram["fmgr_ha_peer_status"] is None:
+ paramgram["fmgr_ha_peer_status"] = "enable"
+
+ # IF THE PEER STATUS IS ENABLE, USE THE next_peer_id IN THE API CALL FOR THE ID
+ if paramgram["fmgr_ha_peer_status"] == "enable":
+ results = fmgr_set_ha_peer(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results, stop_on_success=True,
+ ansible_facts=fmgr.construct_ansible_facts(results,
+ module.params, paramgram))
+
+ # IF THE PEER STATUS IS DISABLE, WE HAVE TO HANDLE THAT A BIT DIFFERENTLY
+ # JUST USING TWO DIFFERENT peer_id 's HERE
+ if paramgram["fmgr_ha_peer_status"] == "disable":
+ results = fmgr_set_ha_peer(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results, stop_on_success=True,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ return module.exit_json(**results[1])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_provisioning.py b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_provisioning.py
new file mode 100644
index 00000000..da499cbe
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_provisioning.py
@@ -0,0 +1,360 @@
+#!/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: fmgr_provisioning
+author: Andrew Welsh (@Ghilli3)
+short_description: Provision devices via FortiMananger
+description:
+ - Add model devices on the FortiManager using jsonrpc API and have them pre-configured,
+ so when central management is configured, the configuration is pushed down to the
+ registering devices
+
+options:
+ adom:
+ description:
+ - The administrative domain (admon) the configuration belongs to
+ required: true
+ vdom:
+ description:
+ - The virtual domain (vdom) the configuration belongs to
+ host:
+ description:
+ - The FortiManager's Address.
+ required: true
+ username:
+ description:
+ - The username to log into the FortiManager
+ required: true
+ password:
+ description:
+ - The password associated with the username account.
+ required: false
+
+ policy_package:
+ description:
+ - The name of the policy package to be assigned to the device.
+ required: True
+ name:
+ description:
+ - The name of the device to be provisioned.
+ required: True
+ group:
+ description:
+ - The name of the device group the provisioned device can belong to.
+ required: False
+ serial:
+ description:
+ - The serial number of the device that will be provisioned.
+ required: True
+ platform:
+ description:
+ - The platform of the device, such as model number or VM.
+ required: True
+ description:
+ description:
+ - Description of the device to be provisioned.
+ required: False
+ os_version:
+ description:
+ - The Fortinet OS version to be used for the device, such as 5.0 or 6.0.
+ required: True
+ minor_release:
+ description:
+ - The minor release number such as 6.X.1, as X being the minor release.
+ required: False
+ patch_release:
+ description:
+ - The patch release number such as 6.0.X, as X being the patch release.
+ required: False
+ os_type:
+ description:
+ - The Fortinet OS type to be pushed to the device, such as 'FOS' for FortiOS.
+ required: True
+'''
+
+EXAMPLES = '''
+- name: Create FGT1 Model Device
+ community.fortios.fmgr_provisioning:
+ host: "{{ inventory_hostname }}"
+ username: "{{ username }}"
+ password: "{{ password }}"
+ adom: "root"
+ vdom: "root"
+ policy_package: "default"
+ name: "FGT1"
+ group: "Ansible"
+ serial: "FGVM000000117994"
+ platform: "FortiGate-VM64"
+ description: "Provisioned by Ansible"
+ os_version: '6.0'
+ minor_release: 0
+ patch_release: 0
+ os_type: 'fos'
+
+
+- name: Create FGT2 Model Device
+ community.fortios.fmgr_provisioning:
+ host: "{{ inventory_hostname }}"
+ username: "{{ username }}"
+ password: "{{ password }}"
+ adom: "root"
+ vdom: "root"
+ policy_package: "test_pp"
+ name: "FGT2"
+ group: "Ansible"
+ serial: "FGVM000000117992"
+ platform: "FortiGate-VM64"
+ description: "Provisioned by Ansible"
+ os_version: '5.0'
+ minor_release: 6
+ patch_release: 0
+ os_type: 'fos'
+
+'''
+
+RETURN = """
+api_result:
+ description: full API response, includes status code and message
+ returned: always
+ type: str
+"""
+
+from ansible.module_utils.basic import AnsibleModule, env_fallback
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.fortimanager import AnsibleFortiManager
+
+# check for pyFMG lib
+try:
+ from pyFMG.fortimgr import FortiManager
+ HAS_PYFMGR = True
+except ImportError:
+ HAS_PYFMGR = False
+
+
+def dev_group_exists(fmg, dev_grp_name, adom):
+ datagram = {
+ 'adom': adom,
+ 'name': dev_grp_name,
+ }
+
+ url = '/dvmdb/adom/{adom}/group/{dev_grp_name}'.format(adom=adom, dev_grp_name=dev_grp_name)
+ response = fmg.get(url, datagram)
+ return response
+
+
+def prov_template_exists(fmg, prov_template, adom, vdom):
+ datagram = {
+ 'name': prov_template,
+ 'adom': adom,
+ }
+
+ url = '/pm/devprof/adom/{adom}/devprof/{name}'.format(adom=adom, name=prov_template)
+ response = fmg.get(url, datagram)
+ return response
+
+
+def create_model_device(fmg, name, serial, group, platform, os_version,
+ os_type, minor_release, patch_release=0, adom='root'):
+ datagram = {
+ 'adom': adom,
+ 'flags': ['create_task', 'nonblocking'],
+ 'groups': [{'name': group, 'vdom': 'root'}],
+ 'device': {
+ 'mr': minor_release,
+ 'name': name,
+ 'sn': serial,
+ 'mgmt_mode': 'fmg',
+ 'device action': 'add_model',
+ 'platform_str': platform,
+ 'os_ver': os_version,
+ 'os_type': os_type,
+ 'patch': patch_release,
+ 'desc': 'Provisioned by Ansible',
+ }
+ }
+
+ url = '/dvm/cmd/add/device'
+ response = fmg.execute(url, datagram)
+ return response
+
+
+def update_flags(fmg, name):
+ datagram = {
+ 'flags': ['is_model', 'linked_to_model']
+ }
+ url = 'dvmdb/device/{name}'.format(name=name)
+ response = fmg.update(url, datagram)
+ return response
+
+
+def assign_provision_template(fmg, template, adom, target):
+ datagram = {
+ 'name': template,
+ 'type': 'devprof',
+ 'description': 'Provisioned by Ansible',
+ 'scope member': [{'name': target}]
+ }
+ url = "/pm/devprof/adom/{adom}".format(adom=adom)
+ response = fmg.update(url, datagram)
+ return response
+
+
+def set_devprof_scope(self, provisioning_template, adom, provision_targets):
+ """
+ GET the DevProf (check to see if exists)
+ """
+ fields = dict()
+ targets = []
+ fields["name"] = provisioning_template
+ fields["type"] = "devprof"
+ fields["description"] = "CreatedByAnsible"
+
+ for target in provision_targets.strip().split(","):
+ # split the host on the space to get the mask out
+ new_target = {"name": target}
+ targets.append(new_target)
+
+ fields["scope member"] = targets
+
+ body = {"method": "set", "params": [{"url": "/pm/devprof/adom/{adom}".format(adom=adom),
+ "data": fields, "session": self.session}]}
+ response = self.make_request(body).json()
+ return response
+
+
+def assign_dev_grp(fmg, grp_name, device_name, vdom, adom):
+ datagram = {
+ 'name': device_name,
+ 'vdom': vdom,
+ }
+ url = "/dvmdb/adom/{adom}/group/{grp_name}/object member".format(adom=adom, grp_name=grp_name)
+ response = fmg.set(url, datagram)
+ return response
+
+
+def update_install_target(fmg, device, pp='default', vdom='root', adom='root'):
+ datagram = {
+ 'scope member': [{'name': device, 'vdom': vdom}],
+ 'type': 'pkg'
+ }
+ url = '/pm/pkg/adom/{adom}/{pkg_name}'.format(adom=adom, pkg_name=pp)
+ response = fmg.update(url, datagram)
+ return response
+
+
+def install_pp(fmg, device, pp='default', vdom='root', adom='root'):
+ datagram = {
+ 'adom': adom,
+ 'flags': 'nonblocking',
+ 'pkg': pp,
+ 'scope': [{'name': device, 'vdom': vdom}],
+ }
+ url = 'securityconsole/install/package'
+ response = fmg.execute(url, datagram)
+ return response
+
+
+def main():
+
+ argument_spec = dict(
+ adom=dict(required=False, type="str"),
+ vdom=dict(required=False, type="str"),
+ host=dict(required=True, type="str"),
+ password=dict(fallback=(env_fallback, ["ANSIBLE_NET_PASSWORD"]), no_log=True),
+ username=dict(fallback=(env_fallback, ["ANSIBLE_NET_USERNAME"]), no_log=True),
+
+ policy_package=dict(required=False, type="str"),
+ name=dict(required=False, type="str"),
+ group=dict(required=False, type="str"),
+ serial=dict(required=True, type="str"),
+ platform=dict(required=True, type="str"),
+ description=dict(required=False, type="str"),
+ os_version=dict(required=True, type="str"),
+ minor_release=dict(required=False, type="str"),
+ patch_release=dict(required=False, type="str"),
+ os_type=dict(required=False, type="str"),
+
+ )
+
+ module = AnsibleModule(argument_spec, supports_check_mode=True, )
+
+ # check if params are set
+ if module.params["host"] is None or module.params["username"] is None:
+ module.fail_json(msg="Host and username are required for connection")
+
+ # check if login failed
+ fmg = AnsibleFortiManager(module, module.params["host"], module.params["username"], module.params["password"])
+ response = fmg.login()
+
+ if "FortiManager instance connnected" not in str(response):
+ module.fail_json(msg="Connection to FortiManager Failed")
+ else:
+
+ if module.params["policy_package"] is None:
+ module.params["policy_package"] = 'default'
+ if module.params["adom"] is None:
+ module.params["adom"] = 'root'
+ if module.params["vdom"] is None:
+ module.params["vdom"] = 'root'
+ if module.params["platform"] is None:
+ module.params["platform"] = 'FortiGate-VM64'
+ if module.params["os_type"] is None:
+ module.params["os_type"] = 'fos'
+
+ results = create_model_device(fmg,
+ module.params["name"],
+ module.params["serial"],
+ module.params["group"],
+ module.params["platform"],
+ module.params["os_ver"],
+ module.params["os_type"],
+ module.params["minor_release"],
+ module.params["patch_release"],
+ module.params["adom"])
+ if results[0] != 0:
+ module.fail_json(msg="Create model failed", **results)
+
+ results = update_flags(fmg, module.params["name"])
+ if results[0] != 0:
+ module.fail_json(msg="Update device flags failed", **results)
+
+ # results = assign_dev_grp(fmg, 'Ansible', 'FGVM000000117992', 'root', 'root')
+ # if not results[0] == 0:
+ # module.fail_json(msg="Setting device group failed", **results)
+
+ results = update_install_target(fmg, module.params["name"], module.params["policy_package"])
+ if results[0] != 0:
+ module.fail_json(msg="Adding device target to package failed", **results)
+
+ results = install_pp(fmg, module.params["name"], module.params["policy_package"])
+ if results[0] != 0:
+ module.fail_json(msg="Installing policy package failed", **results)
+
+ fmg.logout()
+
+ # results is returned as a tuple
+ return module.exit_json(**results[1])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_query.py b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_query.py
new file mode 100644
index 00000000..1ceb7dbb
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_query.py
@@ -0,0 +1,424 @@
+#!/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: fmgr_query
+notes:
+ - Full Documentation at U(https://ftnt-ansible-docs.readthedocs.io/en/latest/).
+author: Luke Weighall (@lweighall)
+short_description: Query FortiManager data objects for use in Ansible workflows.
+description:
+ - Provides information on data objects within FortiManager so that playbooks can perform conditionals.
+
+options:
+ adom:
+ description:
+ - The ADOM the configuration should belong to.
+ required: false
+ default: root
+
+ object:
+ description:
+ - The data object we wish to query (device, package, rule, etc). Will expand choices as improves.
+ required: true
+ choices:
+ - device
+ - cluster_nodes
+ - task
+ - custom
+
+ custom_endpoint:
+ description:
+ - ADVANCED USERS ONLY! REQUIRES KNOWLEDGE OF FMGR JSON API!
+ - The HTTP Endpoint on FortiManager you wish to GET from.
+ required: false
+
+ custom_dict:
+ description:
+ - ADVANCED USERS ONLY! REQUIRES KNOWLEDGE OF FMGR JSON API!
+ - DICTIONARY JSON FORMAT ONLY -- Custom dictionary/datagram to send to the endpoint.
+ required: false
+
+ device_ip:
+ description:
+ - The IP of the device you want to query.
+ required: false
+
+ device_unique_name:
+ description:
+ - The desired "friendly" name of the device you want to query.
+ required: false
+
+ device_serial:
+ description:
+ - The serial number of the device you want to query.
+ required: false
+
+ task_id:
+ description:
+ - The ID of the task you wish to query status on. If left blank and object = 'task' a list of tasks are returned.
+ required: false
+
+ nodes:
+ description:
+ - A LIST of firewalls in the cluster you want to verify i.e. ["firewall_A","firewall_B"].
+ required: false
+'''
+
+
+EXAMPLES = '''
+- name: QUERY FORTIGATE DEVICE BY IP
+ community.fortios.fmgr_query:
+ object: "device"
+ adom: "ansible"
+ device_ip: "10.7.220.41"
+
+- name: QUERY FORTIGATE DEVICE BY SERIAL
+ community.fortios.fmgr_query:
+ adom: "ansible"
+ object: "device"
+ device_serial: "FGVM000000117992"
+
+- name: QUERY FORTIGATE DEVICE BY FRIENDLY NAME
+ community.fortios.fmgr_query:
+ adom: "ansible"
+ object: "device"
+ device_unique_name: "ansible-fgt01"
+
+- name: VERIFY CLUSTER MEMBERS AND STATUS
+ community.fortios.fmgr_query:
+ adom: "ansible"
+ object: "cluster_nodes"
+ device_unique_name: "fgt-cluster01"
+ nodes: ["ansible-fgt01", "ansible-fgt02", "ansible-fgt03"]
+
+- name: GET STATUS OF TASK ID
+ community.fortios.fmgr_query:
+ adom: "ansible"
+ object: "task"
+ task_id: "3"
+
+- name: USE CUSTOM TYPE TO QUERY AVAILABLE SCRIPTS
+ community.fortios.fmgr_query:
+ adom: "ansible"
+ object: "custom"
+ custom_endpoint: "/dvmdb/adom/ansible/script"
+ custom_dict: { "type": "cli" }
+'''
+
+RETURN = """
+api_result:
+ description: full API response, includes status code and message
+ returned: always
+ type: str
+"""
+
+from ansible.module_utils.basic import AnsibleModule, env_fallback
+from ansible.module_utils.connection import Connection
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.fortimanager import FortiManagerHandler
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGBaseException
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRCommon
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRMethods
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import DEFAULT_RESULT_OBJ
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FAIL_SOCKET_MSG
+
+
+def fmgr_get_custom(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ # IF THE CUSTOM DICTIONARY (OFTEN CONTAINING FILTERS) IS DEFINED CREATED THAT
+ if paramgram["custom_dict"] is not None:
+ datagram = paramgram["custom_dict"]
+ else:
+ datagram = dict()
+
+ # SET THE CUSTOM ENDPOINT PROVIDED
+ url = paramgram["custom_endpoint"]
+ # MAKE THE CALL AND RETURN RESULTS
+ response = fmgr.process_request(url, datagram, FMGRMethods.GET)
+ return response
+
+
+def fmgr_get_task_status(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ # IF THE TASK_ID IS DEFINED, THEN GET THAT SPECIFIC TASK
+ # OTHERWISE, GET ALL RECENT TASKS IN A LIST
+ if paramgram["task_id"] is not None:
+
+ datagram = {
+ "adom": paramgram["adom"]
+ }
+ url = '/task/task/{task_id}'.format(task_id=paramgram["task_id"])
+ response = fmgr.process_request(url, datagram, FMGRMethods.GET)
+ else:
+ datagram = {
+ "adom": paramgram["adom"]
+ }
+ url = '/task/task'
+ response = fmgr.process_request(url, datagram, FMGRMethods.GET)
+ return response
+
+
+def fmgr_get_device(fmgr, paramgram):
+ """
+ This method is used to get information on devices. This will not work on HA_SLAVE nodes, only top level devices.
+ Such as cluster objects and standalone devices.
+
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ # FIRST TRY TO RUN AN UPDATE ON THE DEVICE
+ # RUN A QUICK CLUSTER REFRESH/UPDATE ATTEMPT TO ENSURE WE'RE GETTING THE LATEST INFORMOATION
+ response = DEFAULT_RESULT_OBJ
+ url = ""
+ datagram = {}
+
+ update_url = '/dvm/cmd/update/device'
+ update_dict = {
+ "adom": paramgram['adom'],
+ "device": paramgram['device_unique_name'],
+ "flags": "create_task"
+ }
+ # DO THE UPDATE CALL
+ fmgr.process_request(update_url, update_dict, FMGRMethods.EXEC)
+
+ # SET THE URL
+ url = '/dvmdb/adom/{adom}/device'.format(adom=paramgram["adom"])
+ device_found = 0
+ response = []
+
+ # TRY TO FIND IT FIRST BY SERIAL NUMBER
+ if paramgram["device_serial"] is not None:
+ datagram = {
+ "filter": ["sn", "==", paramgram["device_serial"]]
+ }
+ response = fmgr.process_request(url, datagram, FMGRMethods.GET)
+ if len(response[1]) >= 0:
+ device_found = 1
+
+ # CHECK IF ANYTHING WAS RETURNED, IF NOT TRY DEVICE NAME PARAMETER
+ if device_found == 0 and paramgram["device_unique_name"] is not None:
+ datagram = {
+ "filter": ["name", "==", paramgram["device_unique_name"]]
+ }
+ response = fmgr.process_request(url, datagram, FMGRMethods.GET)
+ if len(response[1]) >= 0:
+ device_found = 1
+
+ # CHECK IF ANYTHING WAS RETURNED, IF NOT TRY DEVICE IP ADDRESS
+ if device_found == 0 and paramgram["device_ip"] is not None:
+ datagram = {
+ "filter": ["ip", "==", paramgram["device_ip"]]
+ }
+ response = fmgr.process_request(url, datagram, FMGRMethods.GET)
+ if len(response[1]) >= 0:
+ device_found = 1
+
+ return response
+
+
+def fmgr_get_cluster_nodes(fmgr, paramgram):
+ """
+ This method is used to get information on devices. This WILL work on HA_SLAVE nodes, but NOT top level standalone
+ devices.
+ Such as cluster objects and standalone devices.
+
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ response = DEFAULT_RESULT_OBJ
+ url = ""
+ datagram = {}
+ # USE THE DEVICE METHOD TO GET THE CLUSTER INFORMATION SO WE CAN SEE THE HA_SLAVE NODES
+ response = fmgr_get_device(fmgr, paramgram)
+ # CHECK FOR HA_SLAVE NODES, IF CLUSTER IS MISSING COMPLETELY THEN QUIT
+ try:
+ returned_nodes = response[1][0]["ha_slave"]
+ num_of_nodes = len(returned_nodes)
+ except Exception:
+ error_msg = {"cluster_status": "MISSING"}
+ return error_msg
+
+ # INIT LOOP RESOURCES
+ loop_count = 0
+ good_nodes = []
+ expected_nodes = list(paramgram["nodes"])
+ missing_nodes = list(paramgram["nodes"])
+ bad_status_nodes = []
+
+ # LOOP THROUGH THE NODES AND GET THEIR STATUS TO BUILD THE RETURN JSON OBJECT
+ # WE'RE ALSO CHECKING THE NODES IF THEY ARE BAD STATUS, OR PLAIN MISSING
+ while loop_count < num_of_nodes:
+ node_append = {
+ "node_name": returned_nodes[loop_count]["name"],
+ "node_serial": returned_nodes[loop_count]["sn"],
+ "node_parent": returned_nodes[loop_count]["did"],
+ "node_status": returned_nodes[loop_count]["status"],
+ }
+ # IF THE NODE IS IN THE EXPECTED NODES LIST AND WORKING THEN ADD IT TO GOOD NODES LIST
+ if node_append["node_name"] in expected_nodes and node_append["node_status"] == 1:
+ good_nodes.append(node_append["node_name"])
+ # IF THE NODE IS IN THE EXPECTED NODES LIST BUT NOT WORKING THEN ADDED IT TO BAD_STATUS_NODES
+ # IF THE NODE STATUS IS NOT 1 THEN ITS BAD
+ if node_append["node_name"] in expected_nodes and node_append["node_status"] != 1:
+ bad_status_nodes.append(node_append["node_name"])
+ # REMOVE THE NODE FROM MISSING NODES LIST IF NOTHING IS WRONG WITH NODE -- LEAVING US A LIST OF
+ # NOT WORKING NODES
+ missing_nodes.remove(node_append["node_name"])
+ loop_count += 1
+
+ # BUILD RETURN OBJECT FROM NODE LISTS
+ nodes = {
+ "good_nodes": good_nodes,
+ "expected_nodes": expected_nodes,
+ "missing_nodes": missing_nodes,
+ "bad_nodes": bad_status_nodes,
+ "query_status": "good",
+ }
+ if len(nodes["good_nodes"]) == len(nodes["expected_nodes"]):
+ nodes["cluster_status"] = "OK"
+ else:
+ nodes["cluster_status"] = "NOT-COMPLIANT"
+ return nodes
+
+
+def main():
+ argument_spec = dict(
+ adom=dict(required=False, type="str", default="root"),
+ object=dict(required=True, type="str", choices=["device", "cluster_nodes", "task", "custom"]),
+ custom_endpoint=dict(required=False, type="str"),
+ custom_dict=dict(required=False, type="dict"),
+ device_ip=dict(required=False, type="str"),
+ device_unique_name=dict(required=False, type="str"),
+ device_serial=dict(required=False, type="str"),
+ nodes=dict(required=False, type="list"),
+ task_id=dict(required=False, type="str")
+ )
+
+ module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False, )
+ paramgram = {
+ "adom": module.params["adom"],
+ "object": module.params["object"],
+ "device_ip": module.params["device_ip"],
+ "device_unique_name": module.params["device_unique_name"],
+ "device_serial": module.params["device_serial"],
+ "nodes": module.params["nodes"],
+ "task_id": module.params["task_id"],
+ "custom_endpoint": module.params["custom_endpoint"],
+ "custom_dict": module.params["custom_dict"]
+ }
+ module.paramgram = paramgram
+ fmgr = None
+ if module._socket_path:
+ connection = Connection(module._socket_path)
+ fmgr = FortiManagerHandler(connection, module)
+ fmgr.tools = FMGRCommon()
+ else:
+ module.fail_json(**FAIL_SOCKET_MSG)
+
+ results = DEFAULT_RESULT_OBJ
+
+ try:
+ # IF OBJECT IS DEVICE
+ if paramgram["object"] == "device" and any(v is not None for v in [paramgram["device_unique_name"],
+ paramgram["device_serial"],
+ paramgram["device_ip"]]):
+ results = fmgr_get_device(fmgr, paramgram)
+ if results[0] not in [0]:
+ module.fail_json(msg="Device query failed!")
+ elif len(results[1]) == 0:
+ module.exit_json(msg="Device NOT FOUND!")
+ else:
+ module.exit_json(msg="Device Found", **results[1][0])
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ try:
+ # IF OBJECT IS CLUSTER_NODES
+ if paramgram["object"] == "cluster_nodes" and paramgram["nodes"] is not None:
+ results = fmgr_get_cluster_nodes(fmgr, paramgram)
+ if results["cluster_status"] == "MISSING":
+ module.exit_json(msg="No cluster device found!", **results)
+ elif results["query_status"] == "good":
+ module.exit_json(msg="Cluster Found - Showing Nodes", **results)
+ elif results is None:
+ module.fail_json(msg="Query FAILED -- Check module or playbook syntax")
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ try:
+ # IF OBJECT IS TASK
+ if paramgram["object"] == "task":
+ results = fmgr_get_task_status(fmgr, paramgram)
+ if results[0] != 0:
+ module.fail_json(**results[1])
+ if results[0] == 0:
+ module.exit_json(**results[1])
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ try:
+ # IF OBJECT IS CUSTOM
+ if paramgram["object"] == "custom":
+ results = fmgr_get_custom(fmgr, paramgram)
+ if results[0] != 0:
+ module.fail_json(msg="QUERY FAILED -- Please check syntax check JSON guide if needed.")
+ if results[0] == 0:
+ results_len = len(results[1])
+ if results_len > 0:
+ results_combine = dict()
+ if isinstance(results[1], dict):
+ results_combine["results"] = results[1]
+ if isinstance(results[1], list):
+ results_combine["results"] = results[1][0:results_len]
+ module.exit_json(msg="Custom Query Success", **results_combine)
+ else:
+ module.exit_json(msg="NO RESULTS")
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ return module.exit_json(**results[1])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_script.py b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_script.py
new file mode 100644
index 00000000..d84606cc
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_script.py
@@ -0,0 +1,262 @@
+#!/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: fmgr_script
+notes:
+ - Full Documentation at U(https://ftnt-ansible-docs.readthedocs.io/en/latest/).
+author: Andrew Welsh (@Ghilli3)
+short_description: Add/Edit/Delete and execute scripts
+description: Create/edit/delete scripts and execute the scripts on the FortiManager using jsonrpc API
+
+options:
+ adom:
+ description:
+ - The administrative domain (admon) the configuration belongs to
+ required: true
+
+ vdom:
+ description:
+ - The virtual domain (vdom) the configuration belongs to
+
+ mode:
+ description:
+ - The desired mode of the specified object. Execute will run the script.
+ required: false
+ default: "add"
+ choices: ["add", "delete", "execute", "set"]
+
+ script_name:
+ description:
+ - The name of the script.
+ required: True
+
+ script_type:
+ description:
+ - The type of script (CLI or TCL).
+ required: false
+
+ script_target:
+ description:
+ - The target of the script to be run.
+ required: false
+
+ script_description:
+ description:
+ - The description of the script.
+ required: false
+
+ script_content:
+ description:
+ - The script content that will be executed.
+ required: false
+
+ script_scope:
+ description:
+ - (datasource) The devices that the script will run on, can have both device member and device group member.
+ required: false
+
+ script_package:
+ description:
+ - (datasource) Policy package object to run the script against
+ required: false
+'''
+
+EXAMPLES = '''
+- name: CREATE SCRIPT
+ community.fortios.fmgr_script:
+ adom: "root"
+ script_name: "TestScript"
+ script_type: "cli"
+ script_target: "remote_device"
+ script_description: "Create by Ansible"
+ script_content: "get system status"
+
+- name: EXECUTE SCRIPT
+ community.fortios.fmgr_script:
+ adom: "root"
+ script_name: "TestScript"
+ mode: "execute"
+ script_scope: "FGT1,FGT2"
+
+- name: DELETE SCRIPT
+ community.fortios.fmgr_script:
+ adom: "root"
+ script_name: "TestScript"
+ mode: "delete"
+'''
+
+RETURN = """
+api_result:
+ description: full API response, includes status code and message
+ returned: always
+ type: str
+"""
+
+from ansible.module_utils.basic import AnsibleModule, env_fallback
+from ansible.module_utils.connection import Connection
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.fortimanager import FortiManagerHandler
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGBaseException
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRCommon
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRMethods
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import DEFAULT_RESULT_OBJ
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FAIL_SOCKET_MSG
+
+
+def set_script(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+
+ datagram = {
+ 'content': paramgram["script_content"],
+ 'desc': paramgram["script_description"],
+ 'name': paramgram["script_name"],
+ 'target': paramgram["script_target"],
+ 'type': paramgram["script_type"],
+ }
+
+ url = '/dvmdb/adom/{adom}/script/'.format(adom=paramgram["adom"])
+ response = fmgr.process_request(url, datagram, FMGRMethods.SET)
+ return response
+
+
+def delete_script(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+
+ datagram = {
+ 'name': paramgram["script_name"],
+ }
+
+ url = '/dvmdb/adom/{adom}/script/{script_name}'.format(adom=paramgram["adom"], script_name=paramgram["script_name"])
+ response = fmgr.process_request(url, datagram, FMGRMethods.DELETE)
+ return response
+
+
+def execute_script(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+
+ scope_list = list()
+ scope = paramgram["script_scope"].replace(' ', '')
+ scope = scope.split(',')
+ for dev_name in scope:
+ scope_list.append({'name': dev_name, 'vdom': paramgram["vdom"]})
+
+ datagram = {
+ 'adom': paramgram["adom"],
+ 'script': paramgram["script_name"],
+ 'package': paramgram["script_package"],
+ 'scope': scope_list,
+ }
+
+ url = '/dvmdb/adom/{adom}/script/execute'.format(adom=paramgram["adom"])
+ response = fmgr.process_request(url, datagram, FMGRMethods.EXEC)
+ return response
+
+
+def main():
+ argument_spec = dict(
+ adom=dict(required=False, type="str", default="root"),
+ vdom=dict(required=False, type="str", default="root"),
+ mode=dict(choices=["add", "execute", "set", "delete"], type="str", default="add"),
+ script_name=dict(required=True, type="str"),
+ script_type=dict(required=False, type="str"),
+ script_target=dict(required=False, type="str"),
+ script_description=dict(required=False, type="str"),
+ script_content=dict(required=False, type="str"),
+ script_scope=dict(required=False, type="str"),
+ script_package=dict(required=False, type="str"),
+ )
+
+ module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False, )
+ paramgram = {
+ "script_name": module.params["script_name"],
+ "script_type": module.params["script_type"],
+ "script_target": module.params["script_target"],
+ "script_description": module.params["script_description"],
+ "script_content": module.params["script_content"],
+ "script_scope": module.params["script_scope"],
+ "script_package": module.params["script_package"],
+ "adom": module.params["adom"],
+ "vdom": module.params["vdom"],
+ "mode": module.params["mode"],
+ }
+ module.paramgram = paramgram
+ fmgr = None
+ if module._socket_path:
+ connection = Connection(module._socket_path)
+ fmgr = FortiManagerHandler(connection, module)
+ fmgr.tools = FMGRCommon()
+ else:
+ module.fail_json(**FAIL_SOCKET_MSG)
+
+ results = DEFAULT_RESULT_OBJ
+
+ try:
+ if paramgram["mode"] in ['add', 'set']:
+ results = set_script(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results, msg="Operation Finished",
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, module.params))
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ try:
+ if paramgram["mode"] == "execute":
+ results = execute_script(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results, msg="Operation Finished",
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, module.params))
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ try:
+ if paramgram["mode"] == "delete":
+ results = delete_script(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results, msg="Operation Finished",
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, module.params))
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ return module.exit_json(**results[1])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_appctrl.py b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_appctrl.py
new file mode 100644
index 00000000..aabd2985
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_appctrl.py
@@ -0,0 +1,516 @@
+#!/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: fmgr_secprof_appctrl
+notes:
+ - Full Documentation at U(https://ftnt-ansible-docs.readthedocs.io/en/latest/).
+author:
+ - Luke Weighall (@lweighall)
+ - Andrew Welsh (@Ghilli3)
+ - Jim Huber (@p4r4n0y1ng)
+short_description: Manage application control security profiles
+description:
+ - Manage application control security profiles within FortiManager
+
+options:
+ adom:
+ description:
+ - The ADOM the configuration should belong to.
+ required: false
+ default: root
+
+ mode:
+ description:
+ - Sets one of three modes for managing the object.
+ - Allows use of soft-adds instead of overwriting existing values
+ choices: ['add', 'set', 'delete', 'update']
+ required: false
+ default: add
+
+ unknown_application_log:
+ description:
+ - Enable/disable logging for unknown applications.
+ - choice | disable | Disable logging for unknown applications.
+ - choice | enable | Enable logging for unknown applications.
+ required: false
+ choices: ["disable", "enable"]
+
+ unknown_application_action:
+ description:
+ - Pass or block traffic from unknown applications.
+ - choice | pass | Pass or allow unknown applications.
+ - choice | block | Drop or block unknown applications.
+ required: false
+ choices: ["pass", "block"]
+
+ replacemsg_group:
+ description:
+ - Replacement message group.
+ required: false
+
+ p2p_black_list:
+ description:
+ - NO DESCRIPTION PARSED ENTER MANUALLY
+ - FLAG Based Options. Specify multiple in list form.
+ - flag | skype | Skype.
+ - flag | edonkey | Edonkey.
+ - flag | bittorrent | Bit torrent.
+ required: false
+ choices: ["skype", "edonkey", "bittorrent"]
+
+ other_application_log:
+ description:
+ - Enable/disable logging for other applications.
+ - choice | disable | Disable logging for other applications.
+ - choice | enable | Enable logging for other applications.
+ required: false
+ choices: ["disable", "enable"]
+
+ other_application_action:
+ description:
+ - Action for other applications.
+ - choice | pass | Allow sessions matching an application in this application list.
+ - choice | block | Block sessions matching an application in this application list.
+ required: false
+ choices: ["pass", "block"]
+
+ options:
+ description:
+ - NO DESCRIPTION PARSED ENTER MANUALLY
+ - FLAG Based Options. Specify multiple in list form.
+ - flag | allow-dns | Allow DNS.
+ - flag | allow-icmp | Allow ICMP.
+ - flag | allow-http | Allow generic HTTP web browsing.
+ - flag | allow-ssl | Allow generic SSL communication.
+ - flag | allow-quic | Allow QUIC.
+ required: false
+ choices: ["allow-dns", "allow-icmp", "allow-http", "allow-ssl", "allow-quic"]
+
+ name:
+ description:
+ - List name.
+ required: false
+
+ extended_log:
+ description:
+ - Enable/disable extended logging.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ deep_app_inspection:
+ description:
+ - Enable/disable deep application inspection.
+ - choice | disable | Disable deep application inspection.
+ - choice | enable | Enable deep application inspection.
+ required: false
+ choices: ["disable", "enable"]
+
+ comment:
+ description:
+ - comments
+ required: false
+
+ app_replacemsg:
+ description:
+ - Enable/disable replacement messages for blocked applications.
+ - choice | disable | Disable replacement messages for blocked applications.
+ - choice | enable | Enable replacement messages for blocked applications.
+ required: false
+ choices: ["disable", "enable"]
+
+ entries:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED. This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, OMIT THE USE OF THIS PARAMETER
+ - AND USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ entries_action:
+ description:
+ - Pass or block traffic, or reset connection for traffic from this application.
+ - choice | pass | Pass or allow matching traffic.
+ - choice | block | Block or drop matching traffic.
+ - choice | reset | Reset sessions for matching traffic.
+ required: false
+ choices: ["pass", "block", "reset"]
+
+ entries_application:
+ description:
+ - ID of allowed applications.
+ required: false
+
+ entries_behavior:
+ description:
+ - Application behavior filter.
+ required: false
+
+ entries_category:
+ description:
+ - Category ID list.
+ required: false
+
+ entries_log:
+ description:
+ - Enable/disable logging for this application list.
+ - choice | disable | Disable logging.
+ - choice | enable | Enable logging.
+ required: false
+ choices: ["disable", "enable"]
+
+ entries_log_packet:
+ description:
+ - Enable/disable packet logging.
+ - choice | disable | Disable packet logging.
+ - choice | enable | Enable packet logging.
+ required: false
+ choices: ["disable", "enable"]
+
+ entries_per_ip_shaper:
+ description:
+ - Per-IP traffic shaper.
+ required: false
+
+ entries_popularity:
+ description:
+ - Application popularity filter (1 - 5, from least to most popular).
+ - FLAG Based Options. Specify multiple in list form.
+ - flag | 1 | Popularity level 1.
+ - flag | 2 | Popularity level 2.
+ - flag | 3 | Popularity level 3.
+ - flag | 4 | Popularity level 4.
+ - flag | 5 | Popularity level 5.
+ required: false
+ choices: ["1", "2", "3", "4", "5"]
+
+ entries_protocols:
+ description:
+ - Application protocol filter.
+ required: false
+
+ entries_quarantine:
+ description:
+ - Quarantine method.
+ - choice | none | Quarantine is disabled.
+ - choice | attacker | Block all traffic sent from attacker's IP address.
+ - The attacker's IP address is also added to the banned user list. The target's address is not affected.
+ required: false
+ choices: ["none", "attacker"]
+
+ entries_quarantine_expiry:
+ description:
+ - Duration of quarantine. (Format ###d##h##m, minimum 1m, maximum 364d23h59m, default = 5m).
+ - Requires quarantine set to attacker.
+ required: false
+
+ entries_quarantine_log:
+ description:
+ - Enable/disable quarantine logging.
+ - choice | disable | Disable quarantine logging.
+ - choice | enable | Enable quarantine logging.
+ required: false
+ choices: ["disable", "enable"]
+
+ entries_rate_count:
+ description:
+ - Count of the rate.
+ required: false
+
+ entries_rate_duration:
+ description:
+ - Duration (sec) of the rate.
+ required: false
+
+ entries_rate_mode:
+ description:
+ - Rate limit mode.
+ - choice | periodical | Allow configured number of packets every rate-duration.
+ - choice | continuous | Block packets once the rate is reached.
+ required: false
+ choices: ["periodical", "continuous"]
+
+ entries_rate_track:
+ description:
+ - Track the packet protocol field.
+ - choice | none |
+ - choice | src-ip | Source IP.
+ - choice | dest-ip | Destination IP.
+ - choice | dhcp-client-mac | DHCP client.
+ - choice | dns-domain | DNS domain.
+ required: false
+ choices: ["none", "src-ip", "dest-ip", "dhcp-client-mac", "dns-domain"]
+
+ entries_risk:
+ description:
+ - Risk, or impact, of allowing traffic from this application to occur 1 - 5;
+ - (Low, Elevated, Medium, High, and Critical).
+ required: false
+
+ entries_session_ttl:
+ description:
+ - Session TTL (0 = default).
+ required: false
+
+ entries_shaper:
+ description:
+ - Traffic shaper.
+ required: false
+
+ entries_shaper_reverse:
+ description:
+ - Reverse traffic shaper.
+ required: false
+
+ entries_sub_category:
+ description:
+ - Application Sub-category ID list.
+ required: false
+
+ entries_technology:
+ description:
+ - Application technology filter.
+ required: false
+
+ entries_vendor:
+ description:
+ - Application vendor filter.
+ required: false
+
+ entries_parameters_value:
+ description:
+ - Parameter value.
+ required: false
+
+
+'''
+
+EXAMPLES = '''
+ - name: DELETE Profile
+ community.fortios.fmgr_secprof_appctrl:
+ name: "Ansible_Application_Control_Profile"
+ comment: "Created by Ansible Module TEST"
+ mode: "delete"
+
+ - name: CREATE Profile
+ community.fortios.fmgr_secprof_appctrl:
+ name: "Ansible_Application_Control_Profile"
+ comment: "Created by Ansible Module TEST"
+ mode: "set"
+ entries: [{
+ action: "block",
+ log: "enable",
+ log-packet: "enable",
+ protocols: ["1"],
+ quarantine: "attacker",
+ quarantine-log: "enable",
+ },
+ {action: "pass",
+ category: ["2","3","4"]},
+ ]
+'''
+
+RETURN = """
+api_result:
+ description: full API response, includes status code and message
+ returned: always
+ type: str
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.connection import Connection
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.fortimanager import FortiManagerHandler
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGBaseException
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRCommon
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import DEFAULT_RESULT_OBJ
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FAIL_SOCKET_MSG
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import prepare_dict
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import scrub_dict
+
+###############
+# START METHODS
+###############
+
+
+def fmgr_application_list_modify(fmgr, paramgram):
+ """
+ fmgr_application_list -- Modifies Application Control Profiles on FortiManager
+
+ :param fmgr: The fmgr object instance from fmgr_utils.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ # INIT A BASIC OBJECTS
+ response = DEFAULT_RESULT_OBJ
+ url = ""
+ datagram = {}
+
+ # EVAL THE MODE PARAMETER FOR SET OR ADD
+ if paramgram["mode"] in ['set', 'add', 'update']:
+ url = '/pm/config/adom/{adom}/obj/application/list'.format(adom=paramgram["adom"])
+ datagram = scrub_dict(prepare_dict(paramgram))
+
+ # EVAL THE MODE PARAMETER FOR DELETE
+ elif paramgram["mode"] == "delete":
+ # SET THE CORRECT URL FOR DELETE
+ url = '/pm/config/adom/{adom}/obj/application/list/{name}'.format(adom=paramgram["adom"],
+ name=paramgram["name"])
+ datagram = {}
+
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+ return response
+
+
+#############
+# END METHODS
+#############
+
+
+def main():
+ argument_spec = dict(
+ adom=dict(type="str", default="root"),
+ mode=dict(choices=["add", "set", "delete", "update"], type="str", default="add"),
+
+ unknown_application_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ unknown_application_action=dict(required=False, type="str", choices=["pass", "block"]),
+ replacemsg_group=dict(required=False, type="str"),
+ p2p_black_list=dict(required=False, type="str", choices=["skype", "edonkey", "bittorrent"]),
+ other_application_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ other_application_action=dict(required=False, type="str", choices=["pass", "block"]),
+ options=dict(required=False, type="str",
+ choices=["allow-dns", "allow-icmp", "allow-http", "allow-ssl", "allow-quic"]),
+ name=dict(required=False, type="str"),
+ extended_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ deep_app_inspection=dict(required=False, type="str", choices=["disable", "enable"]),
+ comment=dict(required=False, type="str"),
+ app_replacemsg=dict(required=False, type="str", choices=["disable", "enable"]),
+ entries=dict(required=False, type="list"),
+ entries_action=dict(required=False, type="str", choices=["pass", "block", "reset"]),
+ entries_application=dict(required=False, type="str"),
+ entries_behavior=dict(required=False, type="str"),
+ entries_category=dict(required=False, type="str"),
+ entries_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ entries_log_packet=dict(required=False, type="str", choices=["disable", "enable"]),
+ entries_per_ip_shaper=dict(required=False, type="str"),
+ entries_popularity=dict(required=False, type="str", choices=["1", "2", "3", "4", "5"]),
+ entries_protocols=dict(required=False, type="str"),
+ entries_quarantine=dict(required=False, type="str", choices=["none", "attacker"]),
+ entries_quarantine_expiry=dict(required=False, type="str"),
+ entries_quarantine_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ entries_rate_count=dict(required=False, type="int"),
+ entries_rate_duration=dict(required=False, type="int"),
+ entries_rate_mode=dict(required=False, type="str", choices=["periodical", "continuous"]),
+ entries_rate_track=dict(required=False, type="str",
+ choices=["none", "src-ip", "dest-ip", "dhcp-client-mac", "dns-domain"]),
+ entries_risk=dict(required=False, type="str"),
+ entries_session_ttl=dict(required=False, type="int"),
+ entries_shaper=dict(required=False, type="str"),
+ entries_shaper_reverse=dict(required=False, type="str"),
+ entries_sub_category=dict(required=False, type="str"),
+ entries_technology=dict(required=False, type="str"),
+ entries_vendor=dict(required=False, type="str"),
+
+ entries_parameters_value=dict(required=False, type="str"),
+
+ )
+ module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False, )
+ # MODULE PARAMGRAM
+ paramgram = {
+ "mode": module.params["mode"],
+ "adom": module.params["adom"],
+ "unknown-application-log": module.params["unknown_application_log"],
+ "unknown-application-action": module.params["unknown_application_action"],
+ "replacemsg-group": module.params["replacemsg_group"],
+ "p2p-black-list": module.params["p2p_black_list"],
+ "other-application-log": module.params["other_application_log"],
+ "other-application-action": module.params["other_application_action"],
+ "options": module.params["options"],
+ "name": module.params["name"],
+ "extended-log": module.params["extended_log"],
+ "deep-app-inspection": module.params["deep_app_inspection"],
+ "comment": module.params["comment"],
+ "app-replacemsg": module.params["app_replacemsg"],
+ "entries": {
+ "action": module.params["entries_action"],
+ "application": module.params["entries_application"],
+ "behavior": module.params["entries_behavior"],
+ "category": module.params["entries_category"],
+ "log": module.params["entries_log"],
+ "log-packet": module.params["entries_log_packet"],
+ "per-ip-shaper": module.params["entries_per_ip_shaper"],
+ "popularity": module.params["entries_popularity"],
+ "protocols": module.params["entries_protocols"],
+ "quarantine": module.params["entries_quarantine"],
+ "quarantine-expiry": module.params["entries_quarantine_expiry"],
+ "quarantine-log": module.params["entries_quarantine_log"],
+ "rate-count": module.params["entries_rate_count"],
+ "rate-duration": module.params["entries_rate_duration"],
+ "rate-mode": module.params["entries_rate_mode"],
+ "rate-track": module.params["entries_rate_track"],
+ "risk": module.params["entries_risk"],
+ "session-ttl": module.params["entries_session_ttl"],
+ "shaper": module.params["entries_shaper"],
+ "shaper-reverse": module.params["entries_shaper_reverse"],
+ "sub-category": module.params["entries_sub_category"],
+ "technology": module.params["entries_technology"],
+ "vendor": module.params["entries_vendor"],
+ "parameters": {
+ "value": module.params["entries_parameters_value"],
+ }
+ }
+ }
+ module.paramgram = paramgram
+ fmgr = None
+ if module._socket_path:
+ connection = Connection(module._socket_path)
+ fmgr = FortiManagerHandler(connection, module)
+ fmgr.tools = FMGRCommon()
+ else:
+ module.fail_json(**FAIL_SOCKET_MSG)
+
+ list_overrides = ['entries']
+ paramgram = fmgr.tools.paramgram_child_list_override(list_overrides=list_overrides,
+ paramgram=paramgram, module=module)
+
+ results = DEFAULT_RESULT_OBJ
+ try:
+ results = fmgr_application_list_modify(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ return module.exit_json(**results[1])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_av.py b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_av.py
new file mode 100644
index 00000000..88375cf1
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_av.py
@@ -0,0 +1,1386 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# 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: fmgr_secprof_av
+notes:
+ - Full Documentation at U(https://ftnt-ansible-docs.readthedocs.io/en/latest/).
+author:
+ - Luke Weighall (@lweighall)
+ - Andrew Welsh (@Ghilli3)
+ - Jim Huber (@p4r4n0y1ng)
+short_description: Manage security profile
+description:
+ - Manage security profile groups for FortiManager objects
+
+options:
+ adom:
+ description:
+ - The ADOM the configuration should belong to.
+ required: false
+ default: root
+
+ mode:
+ description:
+ - Sets one of three modes for managing the object.
+ - Allows use of soft-adds instead of overwriting existing values
+ choices: ['add', 'set', 'delete', 'update']
+ required: false
+ default: add
+
+ scan_mode:
+ description:
+ - Choose between full scan mode and quick scan mode.
+ required: false
+ choices:
+ - quick
+ - full
+
+ replacemsg_group:
+ description:
+ - Replacement message group customized for this profile.
+ required: false
+
+ name:
+ description:
+ - Profile name.
+ required: false
+
+ mobile_malware_db:
+ description:
+ - Enable/disable using the mobile malware signature database.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ inspection_mode:
+ description:
+ - Inspection mode.
+ required: false
+ choices:
+ - proxy
+ - flow-based
+
+ ftgd_analytics:
+ description:
+ - Settings to control which files are uploaded to FortiSandbox.
+ required: false
+ choices:
+ - disable
+ - suspicious
+ - everything
+
+ extended_log:
+ description:
+ - Enable/disable extended logging for antivirus.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ comment:
+ description:
+ - Comment.
+ required: false
+
+ av_virus_log:
+ description:
+ - Enable/disable AntiVirus logging.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ av_block_log:
+ description:
+ - Enable/disable logging for AntiVirus file blocking.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ analytics_wl_filetype:
+ description:
+ - Do not submit files matching this DLP file-pattern to FortiSandbox.
+ required: false
+
+ analytics_max_upload:
+ description:
+ - Maximum size of files that can be uploaded to FortiSandbox (1 - 395 MBytes, default = 10).
+ required: false
+
+ analytics_db:
+ description:
+ - Enable/disable using the FortiSandbox signature database to supplement the AV signature databases.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ analytics_bl_filetype:
+ description:
+ - Only submit files matching this DLP file-pattern to FortiSandbox.
+ required: false
+
+ content_disarm:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ content_disarm_cover_page:
+ description:
+ - Enable/disable inserting a cover page into the disarmed document.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ content_disarm_detect_only:
+ description:
+ - Enable/disable only detect disarmable files, do not alter content.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ content_disarm_office_embed:
+ description:
+ - Enable/disable stripping of embedded objects in Microsoft Office documents.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ content_disarm_office_hylink:
+ description:
+ - Enable/disable stripping of hyperlinks in Microsoft Office documents.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ content_disarm_office_linked:
+ description:
+ - Enable/disable stripping of linked objects in Microsoft Office documents.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ content_disarm_office_macro:
+ description:
+ - Enable/disable stripping of macros in Microsoft Office documents.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ content_disarm_original_file_destination:
+ description:
+ - Destination to send original file if active content is removed.
+ required: false
+ choices:
+ - fortisandbox
+ - quarantine
+ - discard
+
+ content_disarm_pdf_act_form:
+ description:
+ - Enable/disable stripping of actions that submit data to other targets in PDF documents.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ content_disarm_pdf_act_gotor:
+ description:
+ - Enable/disable stripping of links to other PDFs in PDF documents.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ content_disarm_pdf_act_java:
+ description:
+ - Enable/disable stripping of actions that execute JavaScript code in PDF documents.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ content_disarm_pdf_act_launch:
+ description:
+ - Enable/disable stripping of links to external applications in PDF documents.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ content_disarm_pdf_act_movie:
+ description:
+ - Enable/disable stripping of embedded movies in PDF documents.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ content_disarm_pdf_act_sound:
+ description:
+ - Enable/disable stripping of embedded sound files in PDF documents.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ content_disarm_pdf_embedfile:
+ description:
+ - Enable/disable stripping of embedded files in PDF documents.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ content_disarm_pdf_hyperlink:
+ description:
+ - Enable/disable stripping of hyperlinks from PDF documents.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ content_disarm_pdf_javacode:
+ description:
+ - Enable/disable stripping of JavaScript code in PDF documents.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ ftp:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ ftp_archive_block:
+ description:
+ - Select the archive types to block.
+ - FLAG Based Options. Specify multiple in list form.
+ required: false
+ choices:
+ - encrypted
+ - corrupted
+ - multipart
+ - nested
+ - mailbomb
+ - unhandled
+ - partiallycorrupted
+ - fileslimit
+ - timeout
+
+ ftp_archive_log:
+ description:
+ - Select the archive types to log.
+ - FLAG Based Options. Specify multiple in list form.
+ required: false
+ choices:
+ - encrypted
+ - corrupted
+ - multipart
+ - nested
+ - mailbomb
+ - unhandled
+ - partiallycorrupted
+ - fileslimit
+ - timeout
+
+ ftp_emulator:
+ description:
+ - Enable/disable the virus emulator.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ ftp_options:
+ description:
+ - Enable/disable FTP AntiVirus scanning, monitoring, and quarantine.
+ - FLAG Based Options. Specify multiple in list form.
+ required: false
+ choices:
+ - scan
+ - quarantine
+ - avmonitor
+
+ ftp_outbreak_prevention:
+ description:
+ - Enable FortiGuard Virus Outbreak Prevention service.
+ required: false
+ choices:
+ - disabled
+ - files
+ - full-archive
+
+ http:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ http_archive_block:
+ description:
+ - Select the archive types to block.
+ - FLAG Based Options. Specify multiple in list form.
+ required: false
+ choices:
+ - encrypted
+ - corrupted
+ - multipart
+ - nested
+ - mailbomb
+ - unhandled
+ - partiallycorrupted
+ - fileslimit
+ - timeout
+
+ http_archive_log:
+ description:
+ - Select the archive types to log.
+ - FLAG Based Options. Specify multiple in list form.
+ required: false
+ choices:
+ - encrypted
+ - corrupted
+ - multipart
+ - nested
+ - mailbomb
+ - unhandled
+ - partiallycorrupted
+ - fileslimit
+ - timeout
+
+ http_content_disarm:
+ description:
+ - Enable Content Disarm and Reconstruction for this protocol.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ http_emulator:
+ description:
+ - Enable/disable the virus emulator.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ http_options:
+ description:
+ - Enable/disable HTTP AntiVirus scanning, monitoring, and quarantine.
+ - FLAG Based Options. Specify multiple in list form.
+ required: false
+ choices:
+ - scan
+ - quarantine
+ - avmonitor
+
+ http_outbreak_prevention:
+ description:
+ - Enable FortiGuard Virus Outbreak Prevention service.
+ required: false
+ choices:
+ - disabled
+ - files
+ - full-archive
+
+ imap:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ imap_archive_block:
+ description:
+ - Select the archive types to block.
+ - FLAG Based Options. Specify multiple in list form.
+ required: false
+ choices:
+ - encrypted
+ - corrupted
+ - multipart
+ - nested
+ - mailbomb
+ - unhandled
+ - partiallycorrupted
+ - fileslimit
+ - timeout
+
+ imap_archive_log:
+ description:
+ - Select the archive types to log.
+ - FLAG Based Options. Specify multiple in list form.
+ required: false
+ choices:
+ - encrypted
+ - corrupted
+ - multipart
+ - nested
+ - mailbomb
+ - unhandled
+ - partiallycorrupted
+ - fileslimit
+ - timeout
+
+ imap_content_disarm:
+ description:
+ - Enable Content Disarm and Reconstruction for this protocol.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ imap_emulator:
+ description:
+ - Enable/disable the virus emulator.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ imap_executables:
+ description:
+ - Treat Windows executable files as viruses for the purpose of blocking or monitoring.
+ required: false
+ choices:
+ - default
+ - virus
+
+ imap_options:
+ description:
+ - Enable/disable IMAP AntiVirus scanning, monitoring, and quarantine.
+ - FLAG Based Options. Specify multiple in list form.
+ required: false
+ choices:
+ - scan
+ - quarantine
+ - avmonitor
+
+ imap_outbreak_prevention:
+ description:
+ - Enable FortiGuard Virus Outbreak Prevention service.
+ required: false
+ choices:
+ - disabled
+ - files
+ - full-archive
+
+ mapi:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ mapi_archive_block:
+ description:
+ - Select the archive types to block.
+ - FLAG Based Options. Specify multiple in list form.
+ required: false
+ choices:
+ - encrypted
+ - corrupted
+ - multipart
+ - nested
+ - mailbomb
+ - unhandled
+ - partiallycorrupted
+ - fileslimit
+ - timeout
+
+ mapi_archive_log:
+ description:
+ - Select the archive types to log.
+ - FLAG Based Options. Specify multiple in list form.
+ required: false
+ choices:
+ - encrypted
+ - corrupted
+ - multipart
+ - nested
+ - mailbomb
+ - unhandled
+ - partiallycorrupted
+ - fileslimit
+ - timeout
+
+ mapi_emulator:
+ description:
+ - Enable/disable the virus emulator.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ mapi_executables:
+ description:
+ - Treat Windows executable files as viruses for the purpose of blocking or monitoring.
+ required: false
+ choices:
+ - default
+ - virus
+
+ mapi_options:
+ description:
+ - Enable/disable MAPI AntiVirus scanning, monitoring, and quarantine.
+ - FLAG Based Options. Specify multiple in list form.
+ required: false
+ choices:
+ - scan
+ - quarantine
+ - avmonitor
+
+ mapi_outbreak_prevention:
+ description:
+ - Enable FortiGuard Virus Outbreak Prevention service.
+ required: false
+ choices:
+ - disabled
+ - files
+ - full-archive
+
+ nac_quar:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ nac_quar_expiry:
+ description:
+ - Duration of quarantine.
+ required: false
+
+ nac_quar_infected:
+ description:
+ - Enable/Disable quarantining infected hosts to the banned user list.
+ required: false
+ choices:
+ - none
+ - quar-src-ip
+
+ nac_quar_log:
+ description:
+ - Enable/disable AntiVirus quarantine logging.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ nntp:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ nntp_archive_block:
+ description:
+ - Select the archive types to block.
+ - FLAG Based Options. Specify multiple in list form.
+ required: false
+ choices:
+ - encrypted
+ - corrupted
+ - multipart
+ - nested
+ - mailbomb
+ - unhandled
+ - partiallycorrupted
+ - fileslimit
+ - timeout
+
+ nntp_archive_log:
+ description:
+ - Select the archive types to log.
+ - FLAG Based Options. Specify multiple in list form.
+ required: false
+ choices:
+ - encrypted
+ - corrupted
+ - multipart
+ - nested
+ - mailbomb
+ - unhandled
+ - partiallycorrupted
+ - fileslimit
+ - timeout
+
+ nntp_emulator:
+ description:
+ - Enable/disable the virus emulator.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ nntp_options:
+ description:
+ - Enable/disable NNTP AntiVirus scanning, monitoring, and quarantine.
+ - FLAG Based Options. Specify multiple in list form.
+ required: false
+ choices:
+ - scan
+ - quarantine
+ - avmonitor
+
+ nntp_outbreak_prevention:
+ description:
+ - Enable FortiGuard Virus Outbreak Prevention service.
+ required: false
+ choices:
+ - disabled
+ - files
+ - full-archive
+
+ pop3:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ pop3_archive_block:
+ description:
+ - Select the archive types to block.
+ - FLAG Based Options. Specify multiple in list form.
+ required: false
+ choices:
+ - encrypted
+ - corrupted
+ - multipart
+ - nested
+ - mailbomb
+ - unhandled
+ - partiallycorrupted
+ - fileslimit
+ - timeout
+
+ pop3_archive_log:
+ description:
+ - Select the archive types to log.
+ - FLAG Based Options. Specify multiple in list form.
+ required: false
+ choices:
+ - encrypted
+ - corrupted
+ - multipart
+ - nested
+ - mailbomb
+ - unhandled
+ - partiallycorrupted
+ - fileslimit
+ - timeout
+
+ pop3_content_disarm:
+ description:
+ - Enable Content Disarm and Reconstruction for this protocol.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ pop3_emulator:
+ description:
+ - Enable/disable the virus emulator.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ pop3_executables:
+ description:
+ - Treat Windows executable files as viruses for the purpose of blocking or monitoring.
+ required: false
+ choices:
+ - default
+ - virus
+
+ pop3_options:
+ description:
+ - Enable/disable POP3 AntiVirus scanning, monitoring, and quarantine.
+ - FLAG Based Options. Specify multiple in list form.
+ required: false
+ choices:
+ - scan
+ - quarantine
+ - avmonitor
+
+ pop3_outbreak_prevention:
+ description:
+ - Enable FortiGuard Virus Outbreak Prevention service.
+ required: false
+ choices:
+ - disabled
+ - files
+ - full-archive
+
+ smb:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ smb_archive_block:
+ description:
+ - Select the archive types to block.
+ - FLAG Based Options. Specify multiple in list form.
+ required: false
+ choices:
+ - encrypted
+ - corrupted
+ - multipart
+ - nested
+ - mailbomb
+ - unhandled
+ - partiallycorrupted
+ - fileslimit
+ - timeout
+
+ smb_archive_log:
+ description:
+ - Select the archive types to log.
+ - FLAG Based Options. Specify multiple in list form.
+ required: false
+ choices:
+ - encrypted
+ - corrupted
+ - multipart
+ - nested
+ - mailbomb
+ - unhandled
+ - partiallycorrupted
+ - fileslimit
+ - timeout
+
+ smb_emulator:
+ description:
+ - Enable/disable the virus emulator.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ smb_options:
+ description:
+ - Enable/disable SMB AntiVirus scanning, monitoring, and quarantine.
+ - FLAG Based Options. Specify multiple in list form.
+ required: false
+ choices:
+ - scan
+ - quarantine
+ - avmonitor
+
+ smb_outbreak_prevention:
+ description:
+ - Enable FortiGuard Virus Outbreak Prevention service.
+ required: false
+ choices:
+ - disabled
+ - files
+ - full-archive
+
+ smtp:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ smtp_archive_block:
+ description:
+ - Select the archive types to block.
+ - FLAG Based Options. Specify multiple in list form.
+ required: false
+ choices:
+ - encrypted
+ - corrupted
+ - multipart
+ - nested
+ - mailbomb
+ - unhandled
+ - partiallycorrupted
+ - fileslimit
+ - timeout
+
+ smtp_archive_log:
+ description:
+ - Select the archive types to log.
+ - FLAG Based Options. Specify multiple in list form.
+ required: false
+ choices:
+ - encrypted
+ - corrupted
+ - multipart
+ - nested
+ - mailbomb
+ - unhandled
+ - partiallycorrupted
+ - fileslimit
+ - timeout
+
+ smtp_content_disarm:
+ description:
+ - Enable Content Disarm and Reconstruction for this protocol.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ smtp_emulator:
+ description:
+ - Enable/disable the virus emulator.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ smtp_executables:
+ description:
+ - Treat Windows executable files as viruses for the purpose of blocking or monitoring.
+ required: false
+ choices:
+ - default
+ - virus
+
+ smtp_options:
+ description:
+ - Enable/disable SMTP AntiVirus scanning, monitoring, and quarantine.
+ - FLAG Based Options. Specify multiple in list form.
+ required: false
+ choices:
+ - scan
+ - quarantine
+ - avmonitor
+
+ smtp_outbreak_prevention:
+ description:
+ - Enable FortiGuard Virus Outbreak Prevention service.
+ required: false
+ choices:
+ - disabled
+ - files
+ - full-archive
+'''
+
+EXAMPLES = '''
+ - name: DELETE Profile
+ community.fortios.fmgr_secprof_av:
+ name: "Ansible_AV_Profile"
+ mode: "delete"
+
+ - name: CREATE Profile
+ community.fortios.fmgr_secprof_av:
+ name: "Ansible_AV_Profile"
+ comment: "Created by Ansible Module TEST"
+ mode: "set"
+ inspection_mode: "proxy"
+ ftgd_analytics: "everything"
+ av_block_log: "enable"
+ av_virus_log: "enable"
+ scan_mode: "full"
+ mobile_malware_db: "enable"
+ ftp_archive_block: "encrypted"
+ ftp_outbreak_prevention: "files"
+ ftp_archive_log: "timeout"
+ ftp_emulator: "disable"
+ ftp_options: "scan"
+'''
+
+RETURN = """
+api_result:
+ description: full API response, includes status code and message
+ returned: always
+ type: str
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.connection import Connection
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.fortimanager import FortiManagerHandler
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGBaseException
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRCommon
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import DEFAULT_RESULT_OBJ
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FAIL_SOCKET_MSG
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import prepare_dict
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import scrub_dict
+
+###############
+# START METHODS
+###############
+
+
+def fmgr_antivirus_profile_modify(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+
+ mode = paramgram["mode"]
+ adom = paramgram["adom"]
+
+ response = DEFAULT_RESULT_OBJ
+ # EVAL THE MODE PARAMETER FOR SET OR ADD
+ if mode in ['set', 'add', 'update']:
+ url = '/pm/config/adom/{adom}/obj/antivirus/profile'.format(adom=adom)
+ datagram = scrub_dict(prepare_dict(paramgram))
+
+ # EVAL THE MODE PARAMETER FOR DELETE
+ else:
+ # SET THE CORRECT URL FOR DELETE
+ url = '/pm/config/adom/{adom}/obj/antivirus/profile/{name}'.format(adom=adom, name=paramgram["name"])
+ datagram = {}
+
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+ return response
+
+#############
+# END METHODS
+#############
+
+
+def main():
+ argument_spec = dict(
+ adom=dict(required=False, type="str", default="root"),
+ mode=dict(choices=["add", "set", "delete", "update"], type="str", default="add"),
+
+ scan_mode=dict(required=False, type="str", choices=["quick", "full"]),
+ replacemsg_group=dict(required=False, type="dict"),
+ name=dict(required=False, type="str"),
+ mobile_malware_db=dict(required=False, type="str", choices=["disable", "enable"]),
+ inspection_mode=dict(required=False, type="str", choices=["proxy", "flow-based"]),
+ ftgd_analytics=dict(required=False, type="str", choices=["disable", "suspicious", "everything"]),
+ extended_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ comment=dict(required=False, type="str"),
+ av_virus_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ av_block_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ analytics_wl_filetype=dict(required=False, type="dict"),
+ analytics_max_upload=dict(required=False, type="int"),
+ analytics_db=dict(required=False, type="str", choices=["disable", "enable"]),
+ analytics_bl_filetype=dict(required=False, type="dict"),
+ content_disarm=dict(required=False, type="list"),
+ content_disarm_cover_page=dict(required=False, type="str", choices=["disable", "enable"]),
+ content_disarm_detect_only=dict(required=False, type="str", choices=["disable", "enable"]),
+ content_disarm_office_embed=dict(required=False, type="str", choices=["disable", "enable"]),
+ content_disarm_office_hylink=dict(required=False, type="str", choices=["disable", "enable"]),
+ content_disarm_office_linked=dict(required=False, type="str", choices=["disable", "enable"]),
+ content_disarm_office_macro=dict(required=False, type="str", choices=["disable", "enable"]),
+ content_disarm_original_file_destination=dict(required=False, type="str", choices=["fortisandbox",
+ "quarantine",
+ "discard"]),
+ content_disarm_pdf_act_form=dict(required=False, type="str", choices=["disable", "enable"]),
+ content_disarm_pdf_act_gotor=dict(required=False, type="str", choices=["disable", "enable"]),
+ content_disarm_pdf_act_java=dict(required=False, type="str", choices=["disable", "enable"]),
+ content_disarm_pdf_act_launch=dict(required=False, type="str", choices=["disable", "enable"]),
+ content_disarm_pdf_act_movie=dict(required=False, type="str", choices=["disable", "enable"]),
+ content_disarm_pdf_act_sound=dict(required=False, type="str", choices=["disable", "enable"]),
+ content_disarm_pdf_embedfile=dict(required=False, type="str", choices=["disable", "enable"]),
+ content_disarm_pdf_hyperlink=dict(required=False, type="str", choices=["disable", "enable"]),
+ content_disarm_pdf_javacode=dict(required=False, type="str", choices=["disable", "enable"]),
+ ftp=dict(required=False, type="list"),
+ ftp_archive_block=dict(required=False, type="str", choices=["encrypted",
+ "corrupted",
+ "multipart",
+ "nested",
+ "mailbomb",
+ "unhandled",
+ "partiallycorrupted",
+ "fileslimit",
+ "timeout"]),
+ ftp_archive_log=dict(required=False, type="str", choices=["encrypted",
+ "corrupted",
+ "multipart",
+ "nested",
+ "mailbomb",
+ "unhandled",
+ "partiallycorrupted",
+ "fileslimit",
+ "timeout"]),
+ ftp_emulator=dict(required=False, type="str", choices=["disable", "enable"]),
+ ftp_options=dict(required=False, type="str", choices=["scan", "quarantine", "avmonitor"]),
+ ftp_outbreak_prevention=dict(required=False, type="str", choices=["disabled", "files", "full-archive"]),
+ http=dict(required=False, type="list"),
+ http_archive_block=dict(required=False, type="str", choices=["encrypted",
+ "corrupted",
+ "multipart",
+ "nested",
+ "mailbomb",
+ "unhandled",
+ "partiallycorrupted",
+ "fileslimit",
+ "timeout"]),
+ http_archive_log=dict(required=False, type="str", choices=["encrypted",
+ "corrupted",
+ "multipart",
+ "nested",
+ "mailbomb",
+ "unhandled",
+ "partiallycorrupted",
+ "fileslimit",
+ "timeout"]),
+ http_content_disarm=dict(required=False, type="str", choices=["disable", "enable"]),
+ http_emulator=dict(required=False, type="str", choices=["disable", "enable"]),
+ http_options=dict(required=False, type="str", choices=["scan", "quarantine", "avmonitor"]),
+ http_outbreak_prevention=dict(required=False, type="str", choices=["disabled", "files", "full-archive"]),
+ imap=dict(required=False, type="list"),
+ imap_archive_block=dict(required=False, type="str", choices=["encrypted",
+ "corrupted",
+ "multipart",
+ "nested",
+ "mailbomb",
+ "unhandled",
+ "partiallycorrupted",
+ "fileslimit",
+ "timeout"]),
+ imap_archive_log=dict(required=False, type="str", choices=["encrypted",
+ "corrupted",
+ "multipart",
+ "nested",
+ "mailbomb",
+ "unhandled",
+ "partiallycorrupted",
+ "fileslimit",
+ "timeout"]),
+ imap_content_disarm=dict(required=False, type="str", choices=["disable", "enable"]),
+ imap_emulator=dict(required=False, type="str", choices=["disable", "enable"]),
+ imap_executables=dict(required=False, type="str", choices=["default", "virus"]),
+ imap_options=dict(required=False, type="str", choices=["scan", "quarantine", "avmonitor"]),
+ imap_outbreak_prevention=dict(required=False, type="str", choices=["disabled", "files", "full-archive"]),
+ mapi=dict(required=False, type="list"),
+ mapi_archive_block=dict(required=False, type="str", choices=["encrypted",
+ "corrupted",
+ "multipart",
+ "nested",
+ "mailbomb",
+ "unhandled",
+ "partiallycorrupted",
+ "fileslimit",
+ "timeout"]),
+ mapi_archive_log=dict(required=False, type="str", choices=["encrypted",
+ "corrupted",
+ "multipart",
+ "nested",
+ "mailbomb",
+ "unhandled",
+ "partiallycorrupted",
+ "fileslimit",
+ "timeout"]),
+ mapi_emulator=dict(required=False, type="str", choices=["disable", "enable"]),
+ mapi_executables=dict(required=False, type="str", choices=["default", "virus"]),
+ mapi_options=dict(required=False, type="str", choices=["scan", "quarantine", "avmonitor"]),
+ mapi_outbreak_prevention=dict(required=False, type="str", choices=["disabled", "files", "full-archive"]),
+ nac_quar=dict(required=False, type="list"),
+ nac_quar_expiry=dict(required=False, type="str"),
+ nac_quar_infected=dict(required=False, type="str", choices=["none", "quar-src-ip"]),
+ nac_quar_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ nntp=dict(required=False, type="list"),
+ nntp_archive_block=dict(required=False, type="str", choices=["encrypted",
+ "corrupted",
+ "multipart",
+ "nested",
+ "mailbomb",
+ "unhandled",
+ "partiallycorrupted",
+ "fileslimit",
+ "timeout"]),
+ nntp_archive_log=dict(required=False, type="str", choices=["encrypted",
+ "corrupted",
+ "multipart",
+ "nested",
+ "mailbomb",
+ "unhandled",
+ "partiallycorrupted",
+ "fileslimit",
+ "timeout"]),
+ nntp_emulator=dict(required=False, type="str", choices=["disable", "enable"]),
+ nntp_options=dict(required=False, type="str", choices=["scan", "quarantine", "avmonitor"]),
+ nntp_outbreak_prevention=dict(required=False, type="str", choices=["disabled", "files", "full-archive"]),
+ pop3=dict(required=False, type="list"),
+ pop3_archive_block=dict(required=False, type="str", choices=["encrypted",
+ "corrupted",
+ "multipart",
+ "nested",
+ "mailbomb",
+ "unhandled",
+ "partiallycorrupted",
+ "fileslimit",
+ "timeout"]),
+ pop3_archive_log=dict(required=False, type="str", choices=["encrypted",
+ "corrupted",
+ "multipart",
+ "nested",
+ "mailbomb",
+ "unhandled",
+ "partiallycorrupted",
+ "fileslimit",
+ "timeout"]),
+ pop3_content_disarm=dict(required=False, type="str", choices=["disable", "enable"]),
+ pop3_emulator=dict(required=False, type="str", choices=["disable", "enable"]),
+ pop3_executables=dict(required=False, type="str", choices=["default", "virus"]),
+ pop3_options=dict(required=False, type="str", choices=["scan", "quarantine", "avmonitor"]),
+ pop3_outbreak_prevention=dict(required=False, type="str", choices=["disabled", "files", "full-archive"]),
+ smb=dict(required=False, type="list"),
+ smb_archive_block=dict(required=False, type="str", choices=["encrypted",
+ "corrupted",
+ "multipart",
+ "nested",
+ "mailbomb",
+ "unhandled",
+ "partiallycorrupted",
+ "fileslimit",
+ "timeout"]),
+ smb_archive_log=dict(required=False, type="str", choices=["encrypted",
+ "corrupted",
+ "multipart",
+ "nested",
+ "mailbomb",
+ "unhandled",
+ "partiallycorrupted",
+ "fileslimit",
+ "timeout"]),
+ smb_emulator=dict(required=False, type="str", choices=["disable", "enable"]),
+ smb_options=dict(required=False, type="str", choices=["scan", "quarantine", "avmonitor"]),
+ smb_outbreak_prevention=dict(required=False, type="str", choices=["disabled", "files", "full-archive"]),
+ smtp=dict(required=False, type="list"),
+ smtp_archive_block=dict(required=False, type="str", choices=["encrypted",
+ "corrupted",
+ "multipart",
+ "nested",
+ "mailbomb",
+ "unhandled",
+ "partiallycorrupted",
+ "fileslimit",
+ "timeout"]),
+ smtp_archive_log=dict(required=False, type="str", choices=["encrypted",
+ "corrupted",
+ "multipart",
+ "nested",
+ "mailbomb",
+ "unhandled",
+ "partiallycorrupted",
+ "fileslimit",
+ "timeout"]),
+ smtp_content_disarm=dict(required=False, type="str", choices=["disable", "enable"]),
+ smtp_emulator=dict(required=False, type="str", choices=["disable", "enable"]),
+ smtp_executables=dict(required=False, type="str", choices=["default", "virus"]),
+ smtp_options=dict(required=False, type="str", choices=["scan", "quarantine", "avmonitor"]),
+ smtp_outbreak_prevention=dict(required=False, type="str", choices=["disabled", "files", "full-archive"]),
+
+ )
+
+ module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False, )
+ # MODULE PARAMGRAM
+ paramgram = {
+ "mode": module.params["mode"],
+ "adom": module.params["adom"],
+ "scan-mode": module.params["scan_mode"],
+ "replacemsg-group": module.params["replacemsg_group"],
+ "name": module.params["name"],
+ "mobile-malware-db": module.params["mobile_malware_db"],
+ "inspection-mode": module.params["inspection_mode"],
+ "ftgd-analytics": module.params["ftgd_analytics"],
+ "extended-log": module.params["extended_log"],
+ "comment": module.params["comment"],
+ "av-virus-log": module.params["av_virus_log"],
+ "av-block-log": module.params["av_block_log"],
+ "analytics-wl-filetype": module.params["analytics_wl_filetype"],
+ "analytics-max-upload": module.params["analytics_max_upload"],
+ "analytics-db": module.params["analytics_db"],
+ "analytics-bl-filetype": module.params["analytics_bl_filetype"],
+ "content-disarm": {
+ "cover-page": module.params["content_disarm_cover_page"],
+ "detect-only": module.params["content_disarm_detect_only"],
+ "office-embed": module.params["content_disarm_office_embed"],
+ "office-hylink": module.params["content_disarm_office_hylink"],
+ "office-linked": module.params["content_disarm_office_linked"],
+ "office-macro": module.params["content_disarm_office_macro"],
+ "original-file-destination": module.params["content_disarm_original_file_destination"],
+ "pdf-act-form": module.params["content_disarm_pdf_act_form"],
+ "pdf-act-gotor": module.params["content_disarm_pdf_act_gotor"],
+ "pdf-act-java": module.params["content_disarm_pdf_act_java"],
+ "pdf-act-launch": module.params["content_disarm_pdf_act_launch"],
+ "pdf-act-movie": module.params["content_disarm_pdf_act_movie"],
+ "pdf-act-sound": module.params["content_disarm_pdf_act_sound"],
+ "pdf-embedfile": module.params["content_disarm_pdf_embedfile"],
+ "pdf-hyperlink": module.params["content_disarm_pdf_hyperlink"],
+ "pdf-javacode": module.params["content_disarm_pdf_javacode"],
+ },
+ "ftp": {
+ "archive-block": module.params["ftp_archive_block"],
+ "archive-log": module.params["ftp_archive_log"],
+ "emulator": module.params["ftp_emulator"],
+ "options": module.params["ftp_options"],
+ "outbreak-prevention": module.params["ftp_outbreak_prevention"],
+ },
+ "http": {
+ "archive-block": module.params["http_archive_block"],
+ "archive-log": module.params["http_archive_log"],
+ "content-disarm": module.params["http_content_disarm"],
+ "emulator": module.params["http_emulator"],
+ "options": module.params["http_options"],
+ "outbreak-prevention": module.params["http_outbreak_prevention"],
+ },
+ "imap": {
+ "archive-block": module.params["imap_archive_block"],
+ "archive-log": module.params["imap_archive_log"],
+ "content-disarm": module.params["imap_content_disarm"],
+ "emulator": module.params["imap_emulator"],
+ "executables": module.params["imap_executables"],
+ "options": module.params["imap_options"],
+ "outbreak-prevention": module.params["imap_outbreak_prevention"],
+ },
+ "mapi": {
+ "archive-block": module.params["mapi_archive_block"],
+ "archive-log": module.params["mapi_archive_log"],
+ "emulator": module.params["mapi_emulator"],
+ "executables": module.params["mapi_executables"],
+ "options": module.params["mapi_options"],
+ "outbreak-prevention": module.params["mapi_outbreak_prevention"],
+ },
+ "nac-quar": {
+ "expiry": module.params["nac_quar_expiry"],
+ "infected": module.params["nac_quar_infected"],
+ "log": module.params["nac_quar_log"],
+ },
+ "nntp": {
+ "archive-block": module.params["nntp_archive_block"],
+ "archive-log": module.params["nntp_archive_log"],
+ "emulator": module.params["nntp_emulator"],
+ "options": module.params["nntp_options"],
+ "outbreak-prevention": module.params["nntp_outbreak_prevention"],
+ },
+ "pop3": {
+ "archive-block": module.params["pop3_archive_block"],
+ "archive-log": module.params["pop3_archive_log"],
+ "content-disarm": module.params["pop3_content_disarm"],
+ "emulator": module.params["pop3_emulator"],
+ "executables": module.params["pop3_executables"],
+ "options": module.params["pop3_options"],
+ "outbreak-prevention": module.params["pop3_outbreak_prevention"],
+ },
+ "smb": {
+ "archive-block": module.params["smb_archive_block"],
+ "archive-log": module.params["smb_archive_log"],
+ "emulator": module.params["smb_emulator"],
+ "options": module.params["smb_options"],
+ "outbreak-prevention": module.params["smb_outbreak_prevention"],
+ },
+ "smtp": {
+ "archive-block": module.params["smtp_archive_block"],
+ "archive-log": module.params["smtp_archive_log"],
+ "content-disarm": module.params["smtp_content_disarm"],
+ "emulator": module.params["smtp_emulator"],
+ "executables": module.params["smtp_executables"],
+ "options": module.params["smtp_options"],
+ "outbreak-prevention": module.params["smtp_outbreak_prevention"],
+ }
+ }
+
+ module.paramgram = paramgram
+ fmgr = None
+ if module._socket_path:
+ connection = Connection(module._socket_path)
+ fmgr = FortiManagerHandler(connection, module)
+ fmgr.tools = FMGRCommon()
+ else:
+ module.fail_json(**FAIL_SOCKET_MSG)
+
+ list_overrides = ["content-disarm", "ftp", "http", "imap", "mapi", "nac-quar", "nntp", "pop3", "smb", "smtp"]
+ paramgram = fmgr.tools.paramgram_child_list_override(list_overrides=list_overrides,
+ paramgram=paramgram, module=module)
+ module.paramgram = paramgram
+
+ results = DEFAULT_RESULT_OBJ
+
+ try:
+ results = fmgr_antivirus_profile_modify(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ return module.exit_json(**results[1])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_dns.py b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_dns.py
new file mode 100644
index 00000000..e6157ff4
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_dns.py
@@ -0,0 +1,339 @@
+#!/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: fmgr_secprof_dns
+notes:
+ - Full Documentation at U(https://ftnt-ansible-docs.readthedocs.io/en/latest/).
+author:
+ - Luke Weighall (@lweighall)
+ - Andrew Welsh (@Ghilli3)
+ - Jim Huber (@p4r4n0y1ng)
+short_description: Manage DNS security profiles in FortiManager
+description:
+ - Manage DNS security profiles in FortiManager
+
+options:
+ adom:
+ description:
+ - The ADOM the configuration should belong to.
+ required: false
+ default: root
+
+ mode:
+ description:
+ - Sets one of three modes for managing the object.
+ - Allows use of soft-adds instead of overwriting existing values.
+ choices: ['add', 'set', 'delete', 'update']
+ required: false
+ default: add
+
+ youtube_restrict:
+ type: str
+ description:
+ - Set safe search for YouTube restriction level.
+ - choice | strict | Enable strict safe seach for YouTube.
+ - choice | moderate | Enable moderate safe search for YouTube.
+ required: false
+ choices: ["strict", "moderate"]
+
+ sdns_ftgd_err_log:
+ type: str
+ description:
+ - Enable/disable FortiGuard SDNS rating error logging.
+ - choice | disable | Disable FortiGuard SDNS rating error logging.
+ - choice | enable | Enable FortiGuard SDNS rating error logging.
+ required: false
+ choices: ["disable", "enable"]
+
+ sdns_domain_log:
+ type: str
+ description:
+ - Enable/disable domain filtering and botnet domain logging.
+ - choice | disable | Disable domain filtering and botnet domain logging.
+ - choice | enable | Enable domain filtering and botnet domain logging.
+ required: false
+ choices: ["disable", "enable"]
+
+ safe_search:
+ type: str
+ description:
+ - Enable/disable Google, Bing, and YouTube safe search.
+ - choice | disable | Disable Google, Bing, and YouTube safe search.
+ - choice | enable | Enable Google, Bing, and YouTube safe search.
+ required: false
+ choices: ["disable", "enable"]
+
+ redirect_portal:
+ type: str
+ description:
+ - IP address of the SDNS redirect portal.
+ required: false
+
+ name:
+ type: str
+ description:
+ - Profile name.
+ required: false
+
+ log_all_domain:
+ type: str
+ description:
+ - Enable/disable logging of all domains visited (detailed DNS logging).
+ - choice | disable | Disable logging of all domains visited.
+ - choice | enable | Enable logging of all domains visited.
+ required: false
+ choices: ["disable", "enable"]
+
+ external_ip_blocklist:
+ type: str
+ description:
+ - One or more external IP block lists.
+ required: false
+
+ comment:
+ type: str
+ description:
+ - Comment for the security profile to show in the FortiManager GUI.
+ required: false
+
+ block_botnet:
+ type: str
+ description:
+ - Enable/disable blocking botnet C&C; DNS lookups.
+ - choice | disable | Disable blocking botnet C&C; DNS lookups.
+ - choice | enable | Enable blocking botnet C&C; DNS lookups.
+ required: false
+ choices: ["disable", "enable"]
+
+ block_action:
+ type: str
+ description:
+ - Action to take for blocked domains.
+ - choice | block | Return NXDOMAIN for blocked domains.
+ - choice | redirect | Redirect blocked domains to SDNS portal.
+ required: false
+ choices: ["block", "redirect"]
+
+ domain_filter_domain_filter_table:
+ type: str
+ description:
+ - DNS domain filter table ID.
+ required: false
+
+ ftgd_dns_options:
+ type: str
+ description:
+ - FortiGuard DNS filter options.
+ - FLAG Based Options. Specify multiple in list form.
+ - flag | error-allow | Allow all domains when FortiGuard DNS servers fail.
+ - flag | ftgd-disable | Disable FortiGuard DNS domain rating.
+ required: false
+ choices: ["error-allow", "ftgd-disable"]
+
+ ftgd_dns_filters_action:
+ type: str
+ description:
+ - Action to take for DNS requests matching the category.
+ - choice | monitor | Allow DNS requests matching the category and log the result.
+ - choice | block | Block DNS requests matching the category.
+ required: false
+ choices: ["monitor", "block"]
+
+ ftgd_dns_filters_category:
+ type: str
+ description:
+ - Category number.
+ required: false
+
+ ftgd_dns_filters_log:
+ type: str
+ description:
+ - Enable/disable DNS filter logging for this DNS profile.
+ - choice | disable | Disable DNS filter logging.
+ - choice | enable | Enable DNS filter logging.
+ required: false
+ choices: ["disable", "enable"]
+
+
+'''
+
+EXAMPLES = '''
+ - name: DELETE Profile
+ community.fortios.fmgr_secprof_dns:
+ name: "Ansible_DNS_Profile"
+ comment: "Created by Ansible Module TEST"
+ mode: "delete"
+
+ - name: CREATE Profile
+ community.fortios.fmgr_secprof_dns:
+ name: "Ansible_DNS_Profile"
+ comment: "Created by Ansible Module TEST"
+ mode: "set"
+ block_action: "block"
+
+
+'''
+
+RETURN = """
+api_result:
+ description: full API response, includes status code and message
+ returned: always
+ type: str
+"""
+
+from ansible.module_utils.basic import AnsibleModule, env_fallback
+from ansible.module_utils.connection import Connection
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.fortimanager import FortiManagerHandler
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGBaseException
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRCommon
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRMethods
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import DEFAULT_RESULT_OBJ
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FAIL_SOCKET_MSG
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import prepare_dict
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import scrub_dict
+
+
+###############
+# START METHODS
+###############
+
+
+def fmgr_dnsfilter_profile_modify(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+
+ mode = paramgram["mode"]
+ adom = paramgram["adom"]
+ url = ""
+ datagram = {}
+
+ response = DEFAULT_RESULT_OBJ
+
+ # EVAL THE MODE PARAMETER FOR SET OR ADD
+ if mode in ['set', 'add', 'update']:
+ url = '/pm/config/adom/{adom}/obj/dnsfilter/profile'.format(adom=adom)
+ datagram = scrub_dict(prepare_dict(paramgram))
+
+ # EVAL THE MODE PARAMETER FOR DELETE
+ elif mode == "delete":
+ # SET THE CORRECT URL FOR DELETE
+ url = '/pm/config/adom/{adom}/obj/dnsfilter/profile/{name}'.format(adom=adom, name=paramgram["name"])
+ datagram = {}
+
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+
+ return response
+
+
+#############
+# END METHODS
+#############
+
+
+def main():
+ argument_spec = dict(
+ adom=dict(type="str", default="root"),
+ mode=dict(choices=["add", "set", "delete", "update"], type="str", default="add"),
+
+ youtube_restrict=dict(required=False, type="str", choices=["strict", "moderate"]),
+ sdns_ftgd_err_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ sdns_domain_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ safe_search=dict(required=False, type="str", choices=["disable", "enable"]),
+ redirect_portal=dict(required=False, type="str"),
+ name=dict(required=False, type="str"),
+ log_all_domain=dict(required=False, type="str", choices=["disable", "enable"]),
+ external_ip_blocklist=dict(required=False, type="str"),
+ comment=dict(required=False, type="str"),
+ block_botnet=dict(required=False, type="str", choices=["disable", "enable"]),
+ block_action=dict(required=False, type="str", choices=["block", "redirect"]),
+
+ domain_filter_domain_filter_table=dict(required=False, type="str"),
+
+ ftgd_dns_options=dict(required=False, type="str", choices=["error-allow", "ftgd-disable"]),
+
+ ftgd_dns_filters_action=dict(required=False, type="str", choices=["monitor", "block"]),
+ ftgd_dns_filters_category=dict(required=False, type="str"),
+ ftgd_dns_filters_log=dict(required=False, type="str", choices=["disable", "enable"]),
+
+ )
+
+ module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False, )
+ # MODULE PARAMGRAM
+ paramgram = {
+ "mode": module.params["mode"],
+ "adom": module.params["adom"],
+ "youtube-restrict": module.params["youtube_restrict"],
+ "sdns-ftgd-err-log": module.params["sdns_ftgd_err_log"],
+ "sdns-domain-log": module.params["sdns_domain_log"],
+ "safe-search": module.params["safe_search"],
+ "redirect-portal": module.params["redirect_portal"],
+ "name": module.params["name"],
+ "log-all-domain": module.params["log_all_domain"],
+ "external-ip-blocklist": module.params["external_ip_blocklist"],
+ "comment": module.params["comment"],
+ "block-botnet": module.params["block_botnet"],
+ "block-action": module.params["block_action"],
+ "domain-filter": {
+ "domain-filter-table": module.params["domain_filter_domain_filter_table"],
+ },
+ "ftgd-dns": {
+ "options": module.params["ftgd_dns_options"],
+ "filters": {
+ "action": module.params["ftgd_dns_filters_action"],
+ "category": module.params["ftgd_dns_filters_category"],
+ "log": module.params["ftgd_dns_filters_log"],
+ }
+ }
+ }
+
+ module.paramgram = paramgram
+ fmgr = None
+ if module._socket_path:
+ connection = Connection(module._socket_path)
+ fmgr = FortiManagerHandler(connection, module)
+ fmgr.tools = FMGRCommon()
+ else:
+ module.fail_json(**FAIL_SOCKET_MSG)
+
+ results = DEFAULT_RESULT_OBJ
+
+ try:
+ results = fmgr_dnsfilter_profile_modify(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ return module.exit_json(**results[1])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_ips.py b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_ips.py
new file mode 100644
index 00000000..4b5f8996
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_ips.py
@@ -0,0 +1,664 @@
+#!/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: fmgr_secprof_ips
+notes:
+ - Full Documentation at U(https://ftnt-ansible-docs.readthedocs.io/en/latest/).
+author:
+ - Luke Weighall (@lweighall)
+ - Andrew Welsh (@Ghilli3)
+ - Jim Huber (@p4r4n0y1ng)
+short_description: Managing IPS security profiles in FortiManager
+description:
+ - Managing IPS security profiles in FortiManager
+
+options:
+ adom:
+ description:
+ - The ADOM the configuration should belong to.
+ required: false
+ default: root
+
+ mode:
+ description:
+ - Sets one of three modes for managing the object.
+ - Allows use of soft-adds instead of overwriting existing values
+ choices: ['add', 'set', 'delete', 'update']
+ required: false
+ default: add
+
+ replacemsg_group:
+ description:
+ - Replacement message group.
+ required: false
+
+ name:
+ description:
+ - Sensor name.
+ required: false
+
+ extended_log:
+ description:
+ - Enable/disable extended logging.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ comment:
+ description:
+ - Comment.
+ required: false
+
+ block_malicious_url:
+ description:
+ - Enable/disable malicious URL blocking.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ entries:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ entries_action:
+ description:
+ - Action taken with traffic in which signatures are detected.
+ required: false
+ choices:
+ - pass
+ - block
+ - reset
+ - default
+
+ entries_application:
+ description:
+ - Applications to be protected. set application ? lists available applications. all includes
+ all applications. other includes all unlisted applications.
+ required: false
+
+ entries_location:
+ description:
+ - Protect client or server traffic.
+ required: false
+
+ entries_log:
+ description:
+ - Enable/disable logging of signatures included in filter.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ entries_log_attack_context:
+ description:
+ - Enable/disable logging of attack context| URL buffer, header buffer, body buffer, packet buffer.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ entries_log_packet:
+ description:
+ - Enable/disable packet logging. Enable to save the packet that triggers the filter. You can
+ download the packets in pcap format for diagnostic use.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ entries_os:
+ description:
+ - Operating systems to be protected. all includes all operating systems. other includes all
+ unlisted operating systems.
+ required: false
+
+ entries_protocol:
+ description:
+ - Protocols to be examined. set protocol ? lists available protocols. all includes all protocols.
+ other includes all unlisted protocols.
+ required: false
+
+ entries_quarantine:
+ description:
+ - Quarantine method.
+ required: false
+ choices:
+ - none
+ - attacker
+
+ entries_quarantine_expiry:
+ description:
+ - Duration of quarantine.
+ required: false
+
+ entries_quarantine_log:
+ description:
+ - Enable/disable quarantine logging.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ entries_rate_count:
+ description:
+ - Count of the rate.
+ required: false
+
+ entries_rate_duration:
+ description:
+ - Duration (sec) of the rate.
+ required: false
+
+ entries_rate_mode:
+ description:
+ - Rate limit mode.
+ required: false
+ choices:
+ - periodical
+ - continuous
+
+ entries_rate_track:
+ description:
+ - Track the packet protocol field.
+ required: false
+ choices:
+ - none
+ - src-ip
+ - dest-ip
+ - dhcp-client-mac
+ - dns-domain
+
+ entries_rule:
+ description:
+ - Identifies the predefined or custom IPS signatures to add to the sensor.
+ required: false
+
+ entries_severity:
+ description:
+ - Relative severity of the signature, from info to critical. Log messages generated by the signature
+ include the severity.
+ required: false
+
+ entries_status:
+ description:
+ - Status of the signatures included in filter. default enables the filter and only use filters
+ with default status of enable. Filters with default status of disable will not be used.
+ required: false
+ choices:
+ - disable
+ - enable
+ - default
+
+ entries_exempt_ip_dst_ip:
+ description:
+ - Destination IP address and netmask.
+ required: false
+
+ entries_exempt_ip_src_ip:
+ description:
+ - Source IP address and netmask.
+ required: false
+
+ filter:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ filter_action:
+ description:
+ - Action of selected rules.
+ required: false
+ choices:
+ - pass
+ - block
+ - default
+ - reset
+
+ filter_application:
+ description:
+ - Vulnerable application filter.
+ required: false
+
+ filter_location:
+ description:
+ - Vulnerability location filter.
+ required: false
+
+ filter_log:
+ description:
+ - Enable/disable logging of selected rules.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ filter_log_packet:
+ description:
+ - Enable/disable packet logging of selected rules.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ filter_name:
+ description:
+ - Filter name.
+ required: false
+
+ filter_os:
+ description:
+ - Vulnerable OS filter.
+ required: false
+
+ filter_protocol:
+ description:
+ - Vulnerable protocol filter.
+ required: false
+
+ filter_quarantine:
+ description:
+ - Quarantine IP or interface.
+ required: false
+ choices:
+ - none
+ - attacker
+
+ filter_quarantine_expiry:
+ description:
+ - Duration of quarantine in minute.
+ required: false
+
+ filter_quarantine_log:
+ description:
+ - Enable/disable logging of selected quarantine.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ filter_severity:
+ description:
+ - Vulnerability severity filter.
+ required: false
+
+ filter_status:
+ description:
+ - Selected rules status.
+ required: false
+ choices:
+ - disable
+ - enable
+ - default
+
+ override:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ override_action:
+ description:
+ - Action of override rule.
+ required: false
+ choices:
+ - pass
+ - block
+ - reset
+
+ override_log:
+ description:
+ - Enable/disable logging.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ override_log_packet:
+ description:
+ - Enable/disable packet logging.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ override_quarantine:
+ description:
+ - Quarantine IP or interface.
+ required: false
+ choices:
+ - none
+ - attacker
+
+ override_quarantine_expiry:
+ description:
+ - Duration of quarantine in minute.
+ required: false
+
+ override_quarantine_log:
+ description:
+ - Enable/disable logging of selected quarantine.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ override_rule_id:
+ description:
+ - Override rule ID.
+ required: false
+
+ override_status:
+ description:
+ - Enable/disable status of override rule.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ override_exempt_ip_dst_ip:
+ description:
+ - Destination IP address and netmask.
+ required: false
+
+ override_exempt_ip_src_ip:
+ description:
+ - Source IP address and netmask.
+ required: false
+'''
+
+EXAMPLES = '''
+ - name: DELETE Profile
+ community.fortios.fmgr_secprof_ips:
+ name: "Ansible_IPS_Profile"
+ comment: "Created by Ansible Module TEST"
+ mode: "delete"
+
+ - name: CREATE Profile
+ community.fortios.fmgr_secprof_ips:
+ name: "Ansible_IPS_Profile"
+ comment: "Created by Ansible Module TEST"
+ mode: "set"
+ block_malicious_url: "enable"
+ entries: [{severity: "high", action: "block", log-packet: "enable"}, {severity: "medium", action: "pass"}]
+'''
+
+RETURN = """
+api_result:
+ description: full API response, includes status code and message
+ returned: always
+ type: str
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.connection import Connection
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.fortimanager import FortiManagerHandler
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGBaseException
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRCommon
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import DEFAULT_RESULT_OBJ
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FAIL_SOCKET_MSG
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import prepare_dict
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import scrub_dict
+
+
+###############
+# START METHODS
+###############
+
+
+def fmgr_ips_sensor_modify(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+
+ mode = paramgram["mode"]
+ adom = paramgram["adom"]
+ # INIT A BASIC OBJECTS
+ response = DEFAULT_RESULT_OBJ
+ url = ""
+ datagram = {}
+
+ # EVAL THE MODE PARAMETER FOR SET OR ADD
+ if mode in ['set', 'add', 'update']:
+ url = '/pm/config/adom/{adom}/obj/ips/sensor'.format(adom=adom)
+ datagram = scrub_dict(prepare_dict(paramgram))
+
+ # EVAL THE MODE PARAMETER FOR DELETE
+ elif mode == "delete":
+ # SET THE CORRECT URL FOR DELETE
+ url = '/pm/config/adom/{adom}/obj/ips/sensor/{name}'.format(
+ adom=adom, name=paramgram["name"])
+ datagram = {}
+
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+
+ return response
+
+
+#############
+# END METHODS
+#############
+
+
+def main():
+ argument_spec = dict(
+ adom=dict(type="str", default="root"),
+ mode=dict(choices=["add", "set", "delete", "update"],
+ type="str", default="add"),
+
+ replacemsg_group=dict(required=False, type="str"),
+ name=dict(required=False, type="str"),
+ extended_log=dict(required=False, type="str",
+ choices=["disable", "enable"]),
+ comment=dict(required=False, type="str"),
+ block_malicious_url=dict(required=False, type="str", choices=[
+ "disable", "enable"]),
+ entries=dict(required=False, type="list"),
+ entries_action=dict(required=False, type="str", choices=[
+ "pass", "block", "reset", "default"]),
+ entries_application=dict(required=False, type="str"),
+ entries_location=dict(required=False, type="str"),
+ entries_log=dict(required=False, type="str",
+ choices=["disable", "enable"]),
+ entries_log_attack_context=dict(
+ required=False, type="str", choices=["disable", "enable"]),
+ entries_log_packet=dict(required=False, type="str", choices=[
+ "disable", "enable"]),
+ entries_os=dict(required=False, type="str"),
+ entries_protocol=dict(required=False, type="str"),
+ entries_quarantine=dict(required=False, type="str", choices=[
+ "none", "attacker"]),
+ entries_quarantine_expiry=dict(required=False, type="str"),
+ entries_quarantine_log=dict(
+ required=False, type="str", choices=["disable", "enable"]),
+ entries_rate_count=dict(required=False, type="int"),
+ entries_rate_duration=dict(required=False, type="int"),
+ entries_rate_mode=dict(required=False, type="str", choices=[
+ "periodical", "continuous"]),
+ entries_rate_track=dict(required=False, type="str",
+ choices=["none", "src-ip", "dest-ip", "dhcp-client-mac", "dns-domain"]),
+ entries_rule=dict(required=False, type="str"),
+ entries_severity=dict(required=False, type="str"),
+ entries_status=dict(required=False, type="str", choices=[
+ "disable", "enable", "default"]),
+
+ entries_exempt_ip_dst_ip=dict(required=False, type="str"),
+ entries_exempt_ip_src_ip=dict(required=False, type="str"),
+ filter=dict(required=False, type="list"),
+ filter_action=dict(required=False, type="str", choices=[
+ "pass", "block", "default", "reset"]),
+ filter_application=dict(required=False, type="str"),
+ filter_location=dict(required=False, type="str"),
+ filter_log=dict(required=False, type="str",
+ choices=["disable", "enable"]),
+ filter_log_packet=dict(required=False, type="str",
+ choices=["disable", "enable"]),
+ filter_name=dict(required=False, type="str"),
+ filter_os=dict(required=False, type="str"),
+ filter_protocol=dict(required=False, type="str"),
+ filter_quarantine=dict(required=False, type="str",
+ choices=["none", "attacker"]),
+ filter_quarantine_expiry=dict(required=False, type="int"),
+ filter_quarantine_log=dict(required=False, type="str", choices=[
+ "disable", "enable"]),
+ filter_severity=dict(required=False, type="str"),
+ filter_status=dict(required=False, type="str", choices=[
+ "disable", "enable", "default"]),
+ override=dict(required=False, type="list"),
+ override_action=dict(required=False, type="str",
+ choices=["pass", "block", "reset"]),
+ override_log=dict(required=False, type="str",
+ choices=["disable", "enable"]),
+ override_log_packet=dict(required=False, type="str", choices=[
+ "disable", "enable"]),
+ override_quarantine=dict(required=False, type="str", choices=[
+ "none", "attacker"]),
+ override_quarantine_expiry=dict(required=False, type="int"),
+ override_quarantine_log=dict(
+ required=False, type="str", choices=["disable", "enable"]),
+ override_rule_id=dict(required=False, type="str"),
+ override_status=dict(required=False, type="str",
+ choices=["disable", "enable"]),
+
+ override_exempt_ip_dst_ip=dict(required=False, type="str"),
+ override_exempt_ip_src_ip=dict(required=False, type="str"),
+
+ )
+
+ module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False, )
+ # MODULE PARAMGRAM
+ paramgram = {
+ "mode": module.params["mode"],
+ "adom": module.params["adom"],
+ "replacemsg-group": module.params["replacemsg_group"],
+ "name": module.params["name"],
+ "extended-log": module.params["extended_log"],
+ "comment": module.params["comment"],
+ "block-malicious-url": module.params["block_malicious_url"],
+ "entries": {
+ "action": module.params["entries_action"],
+ "application": module.params["entries_application"],
+ "location": module.params["entries_location"],
+ "log": module.params["entries_log"],
+ "log-attack-context": module.params["entries_log_attack_context"],
+ "log-packet": module.params["entries_log_packet"],
+ "os": module.params["entries_os"],
+ "protocol": module.params["entries_protocol"],
+ "quarantine": module.params["entries_quarantine"],
+ "quarantine-expiry": module.params["entries_quarantine_expiry"],
+ "quarantine-log": module.params["entries_quarantine_log"],
+ "rate-count": module.params["entries_rate_count"],
+ "rate-duration": module.params["entries_rate_duration"],
+ "rate-mode": module.params["entries_rate_mode"],
+ "rate-track": module.params["entries_rate_track"],
+ "rule": module.params["entries_rule"],
+ "severity": module.params["entries_severity"],
+ "status": module.params["entries_status"],
+ "exempt-ip": {
+ "dst-ip": module.params["entries_exempt_ip_dst_ip"],
+ "src-ip": module.params["entries_exempt_ip_src_ip"],
+ },
+ },
+ "filter": {
+ "action": module.params["filter_action"],
+ "application": module.params["filter_application"],
+ "location": module.params["filter_location"],
+ "log": module.params["filter_log"],
+ "log-packet": module.params["filter_log_packet"],
+ "name": module.params["filter_name"],
+ "os": module.params["filter_os"],
+ "protocol": module.params["filter_protocol"],
+ "quarantine": module.params["filter_quarantine"],
+ "quarantine-expiry": module.params["filter_quarantine_expiry"],
+ "quarantine-log": module.params["filter_quarantine_log"],
+ "severity": module.params["filter_severity"],
+ "status": module.params["filter_status"],
+ },
+ "override": {
+ "action": module.params["override_action"],
+ "log": module.params["override_log"],
+ "log-packet": module.params["override_log_packet"],
+ "quarantine": module.params["override_quarantine"],
+ "quarantine-expiry": module.params["override_quarantine_expiry"],
+ "quarantine-log": module.params["override_quarantine_log"],
+ "rule-id": module.params["override_rule_id"],
+ "status": module.params["override_status"],
+ "exempt-ip": {
+ "dst-ip": module.params["override_exempt_ip_dst_ip"],
+ "src-ip": module.params["override_exempt_ip_src_ip"],
+ }
+ }
+ }
+ module.paramgram = paramgram
+ fmgr = None
+ if module._socket_path:
+ connection = Connection(module._socket_path)
+ fmgr = FortiManagerHandler(connection, module)
+ fmgr.tools = FMGRCommon()
+ else:
+ module.fail_json(**FAIL_SOCKET_MSG)
+
+ list_overrides = ['entries', 'filter', 'override']
+
+ paramgram = fmgr.tools.paramgram_child_list_override(list_overrides=list_overrides,
+ paramgram=paramgram, module=module)
+
+ results = DEFAULT_RESULT_OBJ
+ try:
+ results = fmgr_ips_sensor_modify(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ return module.exit_json(**results[1])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_profile_group.py b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_profile_group.py
new file mode 100644
index 00000000..4c65abf5
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_profile_group.py
@@ -0,0 +1,287 @@
+#!/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: fmgr_secprof_profile_group
+notes:
+ - Full Documentation at U(https://ftnt-ansible-docs.readthedocs.io/en/latest/).
+author:
+ - Luke Weighall (@lweighall)
+ - Andrew Welsh (@Ghilli3)
+ - Jim Huber (@p4r4n0y1ng)
+short_description: Manage security profiles within FortiManager
+description:
+ - Manage security profile group which allows you to create a group of security profiles and apply that to a policy.
+
+options:
+ adom:
+ description:
+ - The ADOM the configuration should belong to.
+ required: false
+ default: root
+
+ mode:
+ description:
+ - Sets one of three modes for managing the object.
+ - Allows use of soft-adds instead of overwriting existing values.
+ choices: ['add', 'set', 'delete', 'update']
+ required: false
+ default: add
+
+ webfilter_profile:
+ type: str
+ description:
+ - Name of an existing Web filter profile.
+ required: false
+
+ waf_profile:
+ type: str
+ description:
+ - Name of an existing Web application firewall profile.
+ required: false
+
+ voip_profile:
+ type: str
+ description:
+ - Name of an existing VoIP profile.
+ required: false
+
+ ssl_ssh_profile:
+ type: str
+ description:
+ - Name of an existing SSL SSH profile.
+ required: false
+
+ ssh_filter_profile:
+ type: str
+ description:
+ - Name of an existing SSH filter profile.
+ required: false
+
+ spamfilter_profile:
+ type: str
+ description:
+ - Name of an existing Spam filter profile.
+ required: false
+
+ profile_protocol_options:
+ type: str
+ description:
+ - Name of an existing Protocol options profile.
+ required: false
+
+ name:
+ type: str
+ description:
+ - Profile group name.
+ required: false
+
+ mms_profile:
+ type: str
+ description:
+ - Name of an existing MMS profile.
+ required: false
+
+ ips_sensor:
+ type: str
+ description:
+ - Name of an existing IPS sensor.
+ required: false
+
+ icap_profile:
+ type: str
+ description:
+ - Name of an existing ICAP profile.
+ required: false
+
+ dnsfilter_profile:
+ type: str
+ description:
+ - Name of an existing DNS filter profile.
+ required: false
+
+ dlp_sensor:
+ type: str
+ description:
+ - Name of an existing DLP sensor.
+ required: false
+
+ av_profile:
+ type: str
+ description:
+ - Name of an existing Antivirus profile.
+ required: false
+
+ application_list:
+ type: str
+ description:
+ - Name of an existing Application list.
+ required: false
+
+
+'''
+
+EXAMPLES = '''
+ - name: DELETE Profile
+ community.fortios.fmgr_secprof_profile_group:
+ name: "Ansible_TEST_Profile_Group"
+ mode: "delete"
+
+ - name: CREATE Profile
+ community.fortios.fmgr_secprof_profile_group:
+ name: "Ansible_TEST_Profile_Group"
+ mode: "set"
+ av_profile: "Ansible_AV_Profile"
+ profile_protocol_options: "default"
+'''
+
+RETURN = """
+api_result:
+ description: full API response, includes status code and message
+ returned: always
+ type: str
+"""
+
+from ansible.module_utils.basic import AnsibleModule, env_fallback
+from ansible.module_utils.connection import Connection
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.fortimanager import FortiManagerHandler
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGBaseException
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRCommon
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRMethods
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import DEFAULT_RESULT_OBJ
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FAIL_SOCKET_MSG
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import prepare_dict
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import scrub_dict
+
+
+###############
+# START METHODS
+###############
+
+
+def fmgr_firewall_profile_group_modify(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+
+ mode = paramgram["mode"]
+ adom = paramgram["adom"]
+ url = ""
+ datagram = {}
+
+ response = DEFAULT_RESULT_OBJ
+
+ # EVAL THE MODE PARAMETER FOR SET OR ADD
+ if mode in ['set', 'add', 'update']:
+ url = '/pm/config/adom/{adom}/obj/firewall/profile-group'.format(adom=adom)
+ datagram = scrub_dict(prepare_dict(paramgram))
+
+ # EVAL THE MODE PARAMETER FOR DELETE
+ elif mode == "delete":
+ # SET THE CORRECT URL FOR DELETE
+ url = '/pm/config/adom/{adom}/obj/firewall/profile-group/{name}'.format(adom=adom, name=paramgram["name"])
+ datagram = {}
+
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+
+ return response
+
+
+#############
+# END METHODS
+#############
+
+
+def main():
+ argument_spec = dict(
+ adom=dict(type="str", default="root"),
+ mode=dict(choices=["add", "set", "delete", "update"], type="str", default="add"),
+
+ webfilter_profile=dict(required=False, type="str"),
+ waf_profile=dict(required=False, type="str"),
+ voip_profile=dict(required=False, type="str"),
+ ssl_ssh_profile=dict(required=False, type="str"),
+ ssh_filter_profile=dict(required=False, type="str"),
+ spamfilter_profile=dict(required=False, type="str"),
+ profile_protocol_options=dict(required=False, type="str"),
+ name=dict(required=False, type="str"),
+ mms_profile=dict(required=False, type="str"),
+ ips_sensor=dict(required=False, type="str"),
+ icap_profile=dict(required=False, type="str"),
+ dnsfilter_profile=dict(required=False, type="str"),
+ dlp_sensor=dict(required=False, type="str"),
+ av_profile=dict(required=False, type="str"),
+ application_list=dict(required=False, type="str"),
+
+ )
+
+ module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False, )
+ # MODULE PARAMGRAM
+ paramgram = {
+ "mode": module.params["mode"],
+ "adom": module.params["adom"],
+ "webfilter-profile": module.params["webfilter_profile"],
+ "waf-profile": module.params["waf_profile"],
+ "voip-profile": module.params["voip_profile"],
+ "ssl-ssh-profile": module.params["ssl_ssh_profile"],
+ "ssh-filter-profile": module.params["ssh_filter_profile"],
+ "spamfilter-profile": module.params["spamfilter_profile"],
+ "profile-protocol-options": module.params["profile_protocol_options"],
+ "name": module.params["name"],
+ "mms-profile": module.params["mms_profile"],
+ "ips-sensor": module.params["ips_sensor"],
+ "icap-profile": module.params["icap_profile"],
+ "dnsfilter-profile": module.params["dnsfilter_profile"],
+ "dlp-sensor": module.params["dlp_sensor"],
+ "av-profile": module.params["av_profile"],
+ "application-list": module.params["application_list"],
+
+ }
+ module.paramgram = paramgram
+ fmgr = None
+ if module._socket_path:
+ connection = Connection(module._socket_path)
+ fmgr = FortiManagerHandler(connection, module)
+ fmgr.tools = FMGRCommon()
+ else:
+ module.fail_json(**FAIL_SOCKET_MSG)
+
+ results = DEFAULT_RESULT_OBJ
+
+ try:
+ results = fmgr_firewall_profile_group_modify(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ return module.exit_json(**results[1])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_proxy.py b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_proxy.py
new file mode 100644
index 00000000..1b3ce8d1
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_proxy.py
@@ -0,0 +1,332 @@
+#!/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: fmgr_secprof_proxy
+notes:
+ - Full Documentation at U(https://ftnt-ansible-docs.readthedocs.io/en/latest/).
+author:
+ - Luke Weighall (@lweighall)
+ - Andrew Welsh (@Ghilli3)
+ - Jim Huber (@p4r4n0y1ng)
+short_description: Manage proxy security profiles in FortiManager
+description:
+ - Manage proxy security profiles for FortiGates via FortiManager using the FMG API with playbooks
+
+options:
+ adom:
+ description:
+ - The ADOM the configuration should belong to.
+ required: false
+ default: root
+
+ mode:
+ description:
+ - Sets one of three modes for managing the object.
+ - Allows use of soft-adds instead of overwriting existing values
+ choices: ['add', 'set', 'delete', 'update']
+ required: false
+ default: add
+
+ strip_encoding:
+ description:
+ - Enable/disable stripping unsupported encoding from the request header.
+ - choice | disable | Disable stripping of unsupported encoding from the request header.
+ - choice | enable | Enable stripping of unsupported encoding from the request header.
+ required: false
+ choices: ["disable", "enable"]
+
+ name:
+ description:
+ - Profile name.
+ required: false
+
+ log_header_change:
+ description:
+ - Enable/disable logging HTTP header changes.
+ - choice | disable | Disable Enable/disable logging HTTP header changes.
+ - choice | enable | Enable Enable/disable logging HTTP header changes.
+ required: false
+ choices: ["disable", "enable"]
+
+ header_x_forwarded_for:
+ description:
+ - Action to take on the HTTP x-forwarded-for header in forwarded requests| forwards (pass), adds, or removes the
+ - HTTP header.
+ - choice | pass | Forward the same HTTP header.
+ - choice | add | Add the HTTP header.
+ - choice | remove | Remove the HTTP header.
+ required: false
+ choices: ["pass", "add", "remove"]
+
+ header_x_authenticated_user:
+ description:
+ - Action to take on the HTTP x-authenticated-user header in forwarded requests| forwards (pass), adds, or remove
+ - s the HTTP header.
+ - choice | pass | Forward the same HTTP header.
+ - choice | add | Add the HTTP header.
+ - choice | remove | Remove the HTTP header.
+ required: false
+ choices: ["pass", "add", "remove"]
+
+ header_x_authenticated_groups:
+ description:
+ - Action to take on the HTTP x-authenticated-groups header in forwarded requests| forwards (pass), adds, or remo
+ - ves the HTTP header.
+ - choice | pass | Forward the same HTTP header.
+ - choice | add | Add the HTTP header.
+ - choice | remove | Remove the HTTP header.
+ required: false
+ choices: ["pass", "add", "remove"]
+
+ header_via_response:
+ description:
+ - Action to take on the HTTP via header in forwarded responses| forwards (pass), adds, or removes the HTTP heade
+ - r.
+ - choice | pass | Forward the same HTTP header.
+ - choice | add | Add the HTTP header.
+ - choice | remove | Remove the HTTP header.
+ required: false
+ choices: ["pass", "add", "remove"]
+
+ header_via_request:
+ description:
+ - Action to take on the HTTP via header in forwarded requests| forwards (pass), adds, or removes the HTTP header
+ - .
+ - choice | pass | Forward the same HTTP header.
+ - choice | add | Add the HTTP header.
+ - choice | remove | Remove the HTTP header.
+ required: false
+ choices: ["pass", "add", "remove"]
+
+ header_front_end_https:
+ description:
+ - Action to take on the HTTP front-end-HTTPS header in forwarded requests| forwards (pass), adds, or removes the
+ - HTTP header.
+ - choice | pass | Forward the same HTTP header.
+ - choice | add | Add the HTTP header.
+ - choice | remove | Remove the HTTP header.
+ required: false
+ choices: ["pass", "add", "remove"]
+
+ header_client_ip:
+ description:
+ - Actions to take on the HTTP client-IP header in forwarded requests| forwards (pass), adds, or removes the HTTP
+ - header.
+ - choice | pass | Forward the same HTTP header.
+ - choice | add | Add the HTTP header.
+ - choice | remove | Remove the HTTP header.
+ required: false
+ choices: ["pass", "add", "remove"]
+
+ headers:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ headers_action:
+ description:
+ - Action when HTTP the header forwarded.
+ - choice | add-to-request | Add the HTTP header to request.
+ - choice | add-to-response | Add the HTTP header to response.
+ - choice | remove-from-request | Remove the HTTP header from request.
+ - choice | remove-from-response | Remove the HTTP header from response.
+ required: false
+ choices: ["add-to-request", "add-to-response", "remove-from-request", "remove-from-response"]
+
+ headers_content:
+ description:
+ - HTTP header's content.
+ required: false
+
+ headers_name:
+ description:
+ - HTTP forwarded header name.
+ required: false
+
+
+'''
+
+EXAMPLES = '''
+ - name: DELETE Profile
+ community.fortios.fmgr_secprof_proxy:
+ name: "Ansible_Web_Proxy_Profile"
+ mode: "delete"
+
+ - name: CREATE Profile
+ community.fortios.fmgr_secprof_proxy:
+ name: "Ansible_Web_Proxy_Profile"
+ mode: "set"
+ header_client_ip: "pass"
+ header_front_end_https: "add"
+ header_via_request: "remove"
+ header_via_response: "pass"
+ header_x_authenticated_groups: "add"
+ header_x_authenticated_user: "remove"
+ strip_encoding: "enable"
+ log_header_change: "enable"
+ header_x_forwarded_for: "pass"
+ headers_action: "add-to-request"
+ headers_content: "test"
+ headers_name: "test_header"
+'''
+
+RETURN = """
+api_result:
+ description: full API response, includes status code and message
+ returned: always
+ type: str
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.connection import Connection
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.fortimanager import FortiManagerHandler
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGBaseException
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRCommon
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import DEFAULT_RESULT_OBJ
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FAIL_SOCKET_MSG
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import prepare_dict
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import scrub_dict
+
+
+###############
+# START METHODS
+###############
+
+
+def fmgr_web_proxy_profile_modify(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+
+ mode = paramgram["mode"]
+ adom = paramgram["adom"]
+
+ response = DEFAULT_RESULT_OBJ
+ url = ""
+ datagram = {}
+
+ # EVAL THE MODE PARAMETER FOR SET OR ADD
+ if mode in ['set', 'add', 'update']:
+ url = '/pm/config/adom/{adom}/obj/web-proxy/profile'.format(adom=adom)
+ datagram = scrub_dict(prepare_dict(paramgram))
+
+ # EVAL THE MODE PARAMETER FOR DELETE
+ elif mode == "delete":
+ # SET THE CORRECT URL FOR DELETE
+ url = '/pm/config/adom/{adom}/obj/web-proxy/profile/{name}'.format(adom=adom, name=paramgram["name"])
+ datagram = {}
+
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+
+ return response
+
+
+#############
+# END METHODS
+#############
+
+
+def main():
+ argument_spec = dict(
+ adom=dict(type="str", default="root"),
+ mode=dict(choices=["add", "set", "delete", "update"], type="str", default="add"),
+
+ strip_encoding=dict(required=False, type="str", choices=["disable", "enable"]),
+ name=dict(required=False, type="str"),
+ log_header_change=dict(required=False, type="str", choices=["disable", "enable"]),
+ header_x_forwarded_for=dict(required=False, type="str", choices=["pass", "add", "remove"]),
+ header_x_authenticated_user=dict(required=False, type="str", choices=["pass", "add", "remove"]),
+ header_x_authenticated_groups=dict(required=False, type="str", choices=["pass", "add", "remove"]),
+ header_via_response=dict(required=False, type="str", choices=["pass", "add", "remove"]),
+ header_via_request=dict(required=False, type="str", choices=["pass", "add", "remove"]),
+ header_front_end_https=dict(required=False, type="str", choices=["pass", "add", "remove"]),
+ header_client_ip=dict(required=False, type="str", choices=["pass", "add", "remove"]),
+ headers=dict(required=False, type="list"),
+ headers_action=dict(required=False, type="str", choices=["add-to-request", "add-to-response",
+ "remove-from-request", "remove-from-response"]),
+ headers_content=dict(required=False, type="str"),
+ headers_name=dict(required=False, type="str"),
+
+ )
+
+ module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False, )
+ # MODULE PARAMGRAM
+ paramgram = {
+ "mode": module.params["mode"],
+ "adom": module.params["adom"],
+ "strip-encoding": module.params["strip_encoding"],
+ "name": module.params["name"],
+ "log-header-change": module.params["log_header_change"],
+ "header-x-forwarded-for": module.params["header_x_forwarded_for"],
+ "header-x-authenticated-user": module.params["header_x_authenticated_user"],
+ "header-x-authenticated-groups": module.params["header_x_authenticated_groups"],
+ "header-via-response": module.params["header_via_response"],
+ "header-via-request": module.params["header_via_request"],
+ "header-front-end-https": module.params["header_front_end_https"],
+ "header-client-ip": module.params["header_client_ip"],
+ "headers": {
+ "action": module.params["headers_action"],
+ "content": module.params["headers_content"],
+ "name": module.params["headers_name"],
+ }
+ }
+
+ module.paramgram = paramgram
+ fmgr = None
+ if module._socket_path:
+ connection = Connection(module._socket_path)
+ fmgr = FortiManagerHandler(connection, module)
+ fmgr.tools = FMGRCommon()
+ else:
+ module.fail_json(**FAIL_SOCKET_MSG)
+
+ list_overrides = ['headers']
+ paramgram = fmgr.tools.paramgram_child_list_override(list_overrides=list_overrides,
+ paramgram=paramgram, module=module)
+ module.paramgram = paramgram
+
+ results = DEFAULT_RESULT_OBJ
+ try:
+ results = fmgr_web_proxy_profile_modify(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ return module.exit_json(**results[1])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_spam.py b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_spam.py
new file mode 100644
index 00000000..ac5e918a
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_spam.py
@@ -0,0 +1,607 @@
+#!/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: fmgr_secprof_spam
+notes:
+ - Full Documentation at U(https://ftnt-ansible-docs.readthedocs.io/en/latest/).
+author:
+ - Luke Weighall (@lweighall)
+ - Andrew Welsh (@Ghilli3)
+ - Jim Huber (@p4r4n0y1ng)
+short_description: spam filter profile for FMG
+description:
+ - Manage spam filter security profiles within FortiManager via API
+
+options:
+ adom:
+ description:
+ - The ADOM the configuration should belong to.
+ required: false
+ default: root
+
+ mode:
+ description:
+ - Sets one of three modes for managing the object.
+ - Allows use of soft-adds instead of overwriting existing values
+ choices: ['add', 'set', 'delete', 'update']
+ required: false
+ default: add
+
+ spam_rbl_table:
+ description:
+ - Anti-spam DNSBL table ID.
+ required: false
+
+ spam_mheader_table:
+ description:
+ - Anti-spam MIME header table ID.
+ required: false
+
+ spam_log_fortiguard_response:
+ description:
+ - Enable/disable logging FortiGuard spam response.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ spam_log:
+ description:
+ - Enable/disable spam logging for email filtering.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ spam_iptrust_table:
+ description:
+ - Anti-spam IP trust table ID.
+ required: false
+
+ spam_filtering:
+ description:
+ - Enable/disable spam filtering.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ spam_bword_threshold:
+ description:
+ - Spam banned word threshold.
+ required: false
+
+ spam_bword_table:
+ description:
+ - Anti-spam banned word table ID.
+ required: false
+
+ spam_bwl_table:
+ description:
+ - Anti-spam black/white list table ID.
+ required: false
+
+ replacemsg_group:
+ description:
+ - Replacement message group.
+ required: false
+
+ options:
+ description:
+ - None
+ - FLAG Based Options. Specify multiple in list form.
+ required: false
+ choices:
+ - bannedword
+ - spamfsip
+ - spamfssubmit
+ - spamfschksum
+ - spamfsurl
+ - spamhelodns
+ - spamraddrdns
+ - spamrbl
+ - spamhdrcheck
+ - spamfsphish
+ - spambwl
+
+ name:
+ description:
+ - Profile name.
+ required: false
+
+ flow_based:
+ description:
+ - Enable/disable flow-based spam filtering.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ external:
+ description:
+ - Enable/disable external Email inspection.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ comment:
+ description:
+ - Comment.
+ required: false
+
+ gmail:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ gmail_log:
+ description:
+ - Enable/disable logging.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ imap:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ imap_action:
+ description:
+ - Action for spam email.
+ required: false
+ choices:
+ - pass
+ - tag
+
+ imap_log:
+ description:
+ - Enable/disable logging.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ imap_tag_msg:
+ description:
+ - Subject text or header added to spam email.
+ required: false
+
+ imap_tag_type:
+ description:
+ - Tag subject or header for spam email.
+ - FLAG Based Options. Specify multiple in list form.
+ required: false
+ choices:
+ - subject
+ - header
+ - spaminfo
+
+ mapi:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ mapi_action:
+ description:
+ - Action for spam email.
+ required: false
+ choices:
+ - pass
+ - discard
+
+ mapi_log:
+ description:
+ - Enable/disable logging.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ msn_hotmail:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ msn_hotmail_log:
+ description:
+ - Enable/disable logging.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ pop3:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ pop3_action:
+ description:
+ - Action for spam email.
+ required: false
+ choices:
+ - pass
+ - tag
+
+ pop3_log:
+ description:
+ - Enable/disable logging.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ pop3_tag_msg:
+ description:
+ - Subject text or header added to spam email.
+ required: false
+
+ pop3_tag_type:
+ description:
+ - Tag subject or header for spam email.
+ - FLAG Based Options. Specify multiple in list form.
+ required: false
+ choices:
+ - subject
+ - header
+ - spaminfo
+
+ smtp:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ smtp_action:
+ description:
+ - Action for spam email.
+ required: false
+ choices:
+ - pass
+ - tag
+ - discard
+
+ smtp_hdrip:
+ description:
+ - Enable/disable SMTP email header IP checks for spamfsip, spamrbl and spambwl filters.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ smtp_local_override:
+ description:
+ - Enable/disable local filter to override SMTP remote check result.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ smtp_log:
+ description:
+ - Enable/disable logging.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ smtp_tag_msg:
+ description:
+ - Subject text or header added to spam email.
+ required: false
+
+ smtp_tag_type:
+ description:
+ - Tag subject or header for spam email.
+ - FLAG Based Options. Specify multiple in list form.
+ required: false
+ choices:
+ - subject
+ - header
+ - spaminfo
+
+ yahoo_mail:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ yahoo_mail_log:
+ description:
+ - Enable/disable logging.
+ required: false
+ choices:
+ - disable
+ - enable
+'''
+
+EXAMPLES = '''
+ - name: DELETE Profile
+ community.fortios.fmgr_secprof_spam:
+ name: "Ansible_Spam_Filter_Profile"
+ mode: "delete"
+
+ - name: Create FMGR_SPAMFILTER_PROFILE
+ community.fortios.fmgr_secprof_spam:
+ host: "{{ inventory_hostname }}"
+ username: "{{ username }}"
+ password: "{{ password }}"
+ mode: "set"
+ adom: "root"
+ spam_log_fortiguard_response: "enable"
+ spam_iptrust_table:
+ spam_filtering: "enable"
+ spam_bword_threshold: 10
+ options: ["bannedword", "spamfsip", "spamfsurl", "spamrbl", "spamfsphish", "spambwl"]
+ name: "Ansible_Spam_Filter_Profile"
+ flow_based: "enable"
+ external: "enable"
+ comment: "Created by Ansible"
+ gmail_log: "enable"
+ spam_log: "enable"
+'''
+
+RETURN = """
+api_result:
+ description: full API response, includes status code and message
+ returned: always
+ type: str
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.connection import Connection
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.fortimanager import FortiManagerHandler
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGBaseException
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRCommon
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import DEFAULT_RESULT_OBJ
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FAIL_SOCKET_MSG
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import prepare_dict
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import scrub_dict
+
+###############
+# START METHODS
+###############
+
+
+def fmgr_spamfilter_profile_modify(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+
+ mode = paramgram["mode"]
+ adom = paramgram["adom"]
+
+ response = DEFAULT_RESULT_OBJ
+ url = ""
+ datagram = {}
+
+ # EVAL THE MODE PARAMETER FOR SET OR ADD
+ if mode in ['set', 'add', 'update']:
+ url = '/pm/config/adom/{adom}/obj/spamfilter/profile'.format(adom=adom)
+ datagram = scrub_dict(prepare_dict(paramgram))
+
+ # EVAL THE MODE PARAMETER FOR DELETE
+ elif mode == "delete":
+ # SET THE CORRECT URL FOR DELETE
+ url = '/pm/config/adom/{adom}/obj/spamfilter/profile/{name}'.format(adom=adom, name=paramgram["name"])
+ datagram = {}
+
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+
+ return response
+
+
+#############
+# END METHODS
+#############
+
+
+def main():
+ argument_spec = dict(
+ adom=dict(type="str", default="root"),
+ mode=dict(choices=["add", "set", "delete", "update"], type="str", default="add"),
+
+ spam_rbl_table=dict(required=False, type="str"),
+ spam_mheader_table=dict(required=False, type="str"),
+ spam_log_fortiguard_response=dict(required=False, type="str", choices=["disable", "enable"]),
+ spam_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ spam_iptrust_table=dict(required=False, type="str"),
+ spam_filtering=dict(required=False, type="str", choices=["disable", "enable"]),
+ spam_bword_threshold=dict(required=False, type="int"),
+ spam_bword_table=dict(required=False, type="str"),
+ spam_bwl_table=dict(required=False, type="str"),
+ replacemsg_group=dict(required=False, type="str"),
+ options=dict(required=False, type="list", choices=["bannedword",
+ "spamfsip",
+ "spamfssubmit",
+ "spamfschksum",
+ "spamfsurl",
+ "spamhelodns",
+ "spamraddrdns",
+ "spamrbl",
+ "spamhdrcheck",
+ "spamfsphish",
+ "spambwl"]),
+ name=dict(required=False, type="str"),
+ flow_based=dict(required=False, type="str", choices=["disable", "enable"]),
+ external=dict(required=False, type="str", choices=["disable", "enable"]),
+ comment=dict(required=False, type="str"),
+ gmail=dict(required=False, type="dict"),
+ gmail_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ imap=dict(required=False, type="dict"),
+ imap_action=dict(required=False, type="str", choices=["pass", "tag"]),
+ imap_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ imap_tag_msg=dict(required=False, type="str"),
+ imap_tag_type=dict(required=False, type="str", choices=["subject", "header", "spaminfo"]),
+ mapi=dict(required=False, type="dict"),
+ mapi_action=dict(required=False, type="str", choices=["pass", "discard"]),
+ mapi_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ msn_hotmail=dict(required=False, type="dict"),
+ msn_hotmail_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ pop3=dict(required=False, type="dict"),
+ pop3_action=dict(required=False, type="str", choices=["pass", "tag"]),
+ pop3_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ pop3_tag_msg=dict(required=False, type="str"),
+ pop3_tag_type=dict(required=False, type="str", choices=["subject", "header", "spaminfo"]),
+ smtp=dict(required=False, type="dict"),
+ smtp_action=dict(required=False, type="str", choices=["pass", "tag", "discard"]),
+ smtp_hdrip=dict(required=False, type="str", choices=["disable", "enable"]),
+ smtp_local_override=dict(required=False, type="str", choices=["disable", "enable"]),
+ smtp_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ smtp_tag_msg=dict(required=False, type="str"),
+ smtp_tag_type=dict(required=False, type="str", choices=["subject", "header", "spaminfo"]),
+ yahoo_mail=dict(required=False, type="dict"),
+ yahoo_mail_log=dict(required=False, type="str", choices=["disable", "enable"]),
+
+ )
+
+ module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False, )
+ # MODULE PARAMGRAM
+ paramgram = {
+ "mode": module.params["mode"],
+ "adom": module.params["adom"],
+ "spam-rbl-table": module.params["spam_rbl_table"],
+ "spam-mheader-table": module.params["spam_mheader_table"],
+ "spam-log-fortiguard-response": module.params["spam_log_fortiguard_response"],
+ "spam-log": module.params["spam_log"],
+ "spam-iptrust-table": module.params["spam_iptrust_table"],
+ "spam-filtering": module.params["spam_filtering"],
+ "spam-bword-threshold": module.params["spam_bword_threshold"],
+ "spam-bword-table": module.params["spam_bword_table"],
+ "spam-bwl-table": module.params["spam_bwl_table"],
+ "replacemsg-group": module.params["replacemsg_group"],
+ "options": module.params["options"],
+ "name": module.params["name"],
+ "flow-based": module.params["flow_based"],
+ "external": module.params["external"],
+ "comment": module.params["comment"],
+ "gmail": {
+ "log": module.params["gmail_log"],
+ },
+ "imap": {
+ "action": module.params["imap_action"],
+ "log": module.params["imap_log"],
+ "tag-msg": module.params["imap_tag_msg"],
+ "tag-type": module.params["imap_tag_type"],
+ },
+ "mapi": {
+ "action": module.params["mapi_action"],
+ "log": module.params["mapi_log"],
+ },
+ "msn-hotmail": {
+ "log": module.params["msn_hotmail_log"],
+ },
+ "pop3": {
+ "action": module.params["pop3_action"],
+ "log": module.params["pop3_log"],
+ "tag-msg": module.params["pop3_tag_msg"],
+ "tag-type": module.params["pop3_tag_type"],
+ },
+ "smtp": {
+ "action": module.params["smtp_action"],
+ "hdrip": module.params["smtp_hdrip"],
+ "local-override": module.params["smtp_local_override"],
+ "log": module.params["smtp_log"],
+ "tag-msg": module.params["smtp_tag_msg"],
+ "tag-type": module.params["smtp_tag_type"],
+ },
+ "yahoo-mail": {
+ "log": module.params["yahoo_mail_log"],
+ }
+ }
+ module.paramgram = paramgram
+ fmgr = None
+ if module._socket_path:
+ connection = Connection(module._socket_path)
+ fmgr = FortiManagerHandler(connection, module)
+ fmgr.tools = FMGRCommon()
+ else:
+ module.fail_json(**FAIL_SOCKET_MSG)
+
+ list_overrides = ['gmail', 'imap', 'mapi', 'msn-hotmail', 'pop3', 'smtp', 'yahoo-mail']
+ paramgram = fmgr.tools.paramgram_child_list_override(list_overrides=list_overrides,
+ paramgram=paramgram, module=module)
+
+ results = DEFAULT_RESULT_OBJ
+ try:
+
+ results = fmgr_spamfilter_profile_modify(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ return module.exit_json(**results[1])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_ssl_ssh.py b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_ssl_ssh.py
new file mode 100644
index 00000000..1e9a0f7d
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_ssl_ssh.py
@@ -0,0 +1,954 @@
+#!/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: fmgr_secprof_ssl_ssh
+notes:
+ - Full Documentation at U(https://ftnt-ansible-docs.readthedocs.io/en/latest/).
+author:
+ - Luke Weighall (@lweighall)
+ - Andrew Welsh (@Ghilli3)
+ - Jim Huber (@p4r4n0y1ng)
+short_description: Manage SSL and SSH security profiles in FortiManager
+description:
+ - Manage SSL and SSH security profiles in FortiManager via the FMG API
+
+options:
+ adom:
+ description:
+ - The ADOM the configuration should belong to.
+ required: false
+ default: root
+
+ mode:
+ description:
+ - Sets one of three modes for managing the object.
+ - Allows use of soft-adds instead of overwriting existing values
+ choices: ['add', 'set', 'delete', 'update']
+ required: false
+ default: add
+
+ whitelist:
+ description:
+ - Enable/disable exempting servers by FortiGuard whitelist.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ use_ssl_server:
+ description:
+ - Enable/disable the use of SSL server table for SSL offloading.
+ - choice | disable | Don't use SSL server configuration.
+ - choice | enable | Use SSL server configuration.
+ required: false
+ choices: ["disable", "enable"]
+
+ untrusted_caname:
+ description:
+ - Untrusted CA certificate used by SSL Inspection.
+ required: false
+
+ ssl_exemptions_log:
+ description:
+ - Enable/disable logging SSL exemptions.
+ - choice | disable | Disable logging SSL exemptions.
+ - choice | enable | Enable logging SSL exemptions.
+ required: false
+ choices: ["disable", "enable"]
+
+ ssl_anomalies_log:
+ description:
+ - Enable/disable logging SSL anomalies.
+ - choice | disable | Disable logging SSL anomalies.
+ - choice | enable | Enable logging SSL anomalies.
+ required: false
+ choices: ["disable", "enable"]
+
+ server_cert_mode:
+ description:
+ - Re-sign or replace the server's certificate.
+ - choice | re-sign | Multiple clients connecting to multiple servers.
+ - choice | replace | Protect an SSL server.
+ required: false
+ choices: ["re-sign", "replace"]
+
+ server_cert:
+ description:
+ - Certificate used by SSL Inspection to replace server certificate.
+ required: false
+
+ rpc_over_https:
+ description:
+ - Enable/disable inspection of RPC over HTTPS.
+ - choice | disable | Disable inspection of RPC over HTTPS.
+ - choice | enable | Enable inspection of RPC over HTTPS.
+ required: false
+ choices: ["disable", "enable"]
+
+ name:
+ description:
+ - Name.
+ required: false
+
+ mapi_over_https:
+ description:
+ - Enable/disable inspection of MAPI over HTTPS.
+ - choice | disable | Disable inspection of MAPI over HTTPS.
+ - choice | enable | Enable inspection of MAPI over HTTPS.
+ required: false
+ choices: ["disable", "enable"]
+
+ comment:
+ description:
+ - Optional comments.
+ required: false
+
+ caname:
+ description:
+ - CA certificate used by SSL Inspection.
+ required: false
+
+ ftps:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ ftps_allow_invalid_server_cert:
+ description:
+ - When enabled, allows SSL sessions whose server certificate validation failed.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ ftps_client_cert_request:
+ description:
+ - Action based on client certificate request failure.
+ - choice | bypass | Bypass.
+ - choice | inspect | Inspect.
+ - choice | block | Block.
+ required: false
+ choices: ["bypass", "inspect", "block"]
+
+ ftps_ports:
+ description:
+ - Ports to use for scanning (1 - 65535, default = 443).
+ required: false
+
+ ftps_status:
+ description:
+ - Configure protocol inspection status.
+ - choice | disable | Disable.
+ - choice | deep-inspection | Full SSL inspection.
+ required: false
+ choices: ["disable", "deep-inspection"]
+
+ ftps_unsupported_ssl:
+ description:
+ - Action based on the SSL encryption used being unsupported.
+ - choice | bypass | Bypass.
+ - choice | inspect | Inspect.
+ - choice | block | Block.
+ required: false
+ choices: ["bypass", "inspect", "block"]
+
+ ftps_untrusted_cert:
+ description:
+ - Allow, ignore, or block the untrusted SSL session server certificate.
+ - choice | allow | Allow the untrusted server certificate.
+ - choice | block | Block the connection when an untrusted server certificate is detected.
+ - choice | ignore | Always take the server certificate as trusted.
+ required: false
+ choices: ["allow", "block", "ignore"]
+
+ https:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ https_allow_invalid_server_cert:
+ description:
+ - When enabled, allows SSL sessions whose server certificate validation failed.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ https_client_cert_request:
+ description:
+ - Action based on client certificate request failure.
+ - choice | bypass | Bypass.
+ - choice | inspect | Inspect.
+ - choice | block | Block.
+ required: false
+ choices: ["bypass", "inspect", "block"]
+
+ https_ports:
+ description:
+ - Ports to use for scanning (1 - 65535, default = 443).
+ required: false
+
+ https_status:
+ description:
+ - Configure protocol inspection status.
+ - choice | disable | Disable.
+ - choice | certificate-inspection | Inspect SSL handshake only.
+ - choice | deep-inspection | Full SSL inspection.
+ required: false
+ choices: ["disable", "certificate-inspection", "deep-inspection"]
+
+ https_unsupported_ssl:
+ description:
+ - Action based on the SSL encryption used being unsupported.
+ - choice | bypass | Bypass.
+ - choice | inspect | Inspect.
+ - choice | block | Block.
+ required: false
+ choices: ["bypass", "inspect", "block"]
+
+ https_untrusted_cert:
+ description:
+ - Allow, ignore, or block the untrusted SSL session server certificate.
+ - choice | allow | Allow the untrusted server certificate.
+ - choice | block | Block the connection when an untrusted server certificate is detected.
+ - choice | ignore | Always take the server certificate as trusted.
+ required: false
+ choices: ["allow", "block", "ignore"]
+
+ imaps:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ imaps_allow_invalid_server_cert:
+ description:
+ - When enabled, allows SSL sessions whose server certificate validation failed.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ imaps_client_cert_request:
+ description:
+ - Action based on client certificate request failure.
+ - choice | bypass | Bypass.
+ - choice | inspect | Inspect.
+ - choice | block | Block.
+ required: false
+ choices: ["bypass", "inspect", "block"]
+
+ imaps_ports:
+ description:
+ - Ports to use for scanning (1 - 65535, default = 443).
+ required: false
+
+ imaps_status:
+ description:
+ - Configure protocol inspection status.
+ - choice | disable | Disable.
+ - choice | deep-inspection | Full SSL inspection.
+ required: false
+ choices: ["disable", "deep-inspection"]
+
+ imaps_unsupported_ssl:
+ description:
+ - Action based on the SSL encryption used being unsupported.
+ - choice | bypass | Bypass.
+ - choice | inspect | Inspect.
+ - choice | block | Block.
+ required: false
+ choices: ["bypass", "inspect", "block"]
+
+ imaps_untrusted_cert:
+ description:
+ - Allow, ignore, or block the untrusted SSL session server certificate.
+ - choice | allow | Allow the untrusted server certificate.
+ - choice | block | Block the connection when an untrusted server certificate is detected.
+ - choice | ignore | Always take the server certificate as trusted.
+ required: false
+ choices: ["allow", "block", "ignore"]
+
+ pop3s:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ pop3s_allow_invalid_server_cert:
+ description:
+ - When enabled, allows SSL sessions whose server certificate validation failed.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ pop3s_client_cert_request:
+ description:
+ - Action based on client certificate request failure.
+ - choice | bypass | Bypass.
+ - choice | inspect | Inspect.
+ - choice | block | Block.
+ required: false
+ choices: ["bypass", "inspect", "block"]
+
+ pop3s_ports:
+ description:
+ - Ports to use for scanning (1 - 65535, default = 443).
+ required: false
+
+ pop3s_status:
+ description:
+ - Configure protocol inspection status.
+ - choice | disable | Disable.
+ - choice | deep-inspection | Full SSL inspection.
+ required: false
+ choices: ["disable", "deep-inspection"]
+
+ pop3s_unsupported_ssl:
+ description:
+ - Action based on the SSL encryption used being unsupported.
+ - choice | bypass | Bypass.
+ - choice | inspect | Inspect.
+ - choice | block | Block.
+ required: false
+ choices: ["bypass", "inspect", "block"]
+
+ pop3s_untrusted_cert:
+ description:
+ - Allow, ignore, or block the untrusted SSL session server certificate.
+ - choice | allow | Allow the untrusted server certificate.
+ - choice | block | Block the connection when an untrusted server certificate is detected.
+ - choice | ignore | Always take the server certificate as trusted.
+ required: false
+ choices: ["allow", "block", "ignore"]
+
+ smtps:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ smtps_allow_invalid_server_cert:
+ description:
+ - When enabled, allows SSL sessions whose server certificate validation failed.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ smtps_client_cert_request:
+ description:
+ - Action based on client certificate request failure.
+ - choice | bypass | Bypass.
+ - choice | inspect | Inspect.
+ - choice | block | Block.
+ required: false
+ choices: ["bypass", "inspect", "block"]
+
+ smtps_ports:
+ description:
+ - Ports to use for scanning (1 - 65535, default = 443).
+ required: false
+
+ smtps_status:
+ description:
+ - Configure protocol inspection status.
+ - choice | disable | Disable.
+ - choice | deep-inspection | Full SSL inspection.
+ required: false
+ choices: ["disable", "deep-inspection"]
+
+ smtps_unsupported_ssl:
+ description:
+ - Action based on the SSL encryption used being unsupported.
+ - choice | bypass | Bypass.
+ - choice | inspect | Inspect.
+ - choice | block | Block.
+ required: false
+ choices: ["bypass", "inspect", "block"]
+
+ smtps_untrusted_cert:
+ description:
+ - Allow, ignore, or block the untrusted SSL session server certificate.
+ - choice | allow | Allow the untrusted server certificate.
+ - choice | block | Block the connection when an untrusted server certificate is detected.
+ - choice | ignore | Always take the server certificate as trusted.
+ required: false
+ choices: ["allow", "block", "ignore"]
+
+ ssh:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ ssh_inspect_all:
+ description:
+ - Level of SSL inspection.
+ - choice | disable | Disable.
+ - choice | deep-inspection | Full SSL inspection.
+ required: false
+ choices: ["disable", "deep-inspection"]
+
+ ssh_ports:
+ description:
+ - Ports to use for scanning (1 - 65535, default = 443).
+ required: false
+
+ ssh_ssh_algorithm:
+ description:
+ - Relative strength of encryption algorithms accepted during negotiation.
+ - choice | compatible | Allow a broader set of encryption algorithms for best compatibility.
+ - choice | high-encryption | Allow only AES-CTR, AES-GCM ciphers and high encryption algorithms.
+ required: false
+ choices: ["compatible", "high-encryption"]
+
+ ssh_ssh_policy_check:
+ description:
+ - Enable/disable SSH policy check.
+ - choice | disable | Disable SSH policy check.
+ - choice | enable | Enable SSH policy check.
+ required: false
+ choices: ["disable", "enable"]
+
+ ssh_ssh_tun_policy_check:
+ description:
+ - Enable/disable SSH tunnel policy check.
+ - choice | disable | Disable SSH tunnel policy check.
+ - choice | enable | Enable SSH tunnel policy check.
+ required: false
+ choices: ["disable", "enable"]
+
+ ssh_status:
+ description:
+ - Configure protocol inspection status.
+ - choice | disable | Disable.
+ - choice | deep-inspection | Full SSL inspection.
+ required: false
+ choices: ["disable", "deep-inspection"]
+
+ ssh_unsupported_version:
+ description:
+ - Action based on SSH version being unsupported.
+ - choice | block | Block.
+ - choice | bypass | Bypass.
+ required: false
+ choices: ["block", "bypass"]
+
+ ssl:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ ssl_allow_invalid_server_cert:
+ description:
+ - When enabled, allows SSL sessions whose server certificate validation failed.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ ssl_client_cert_request:
+ description:
+ - Action based on client certificate request failure.
+ - choice | bypass | Bypass.
+ - choice | inspect | Inspect.
+ - choice | block | Block.
+ required: false
+ choices: ["bypass", "inspect", "block"]
+
+ ssl_inspect_all:
+ description:
+ - Level of SSL inspection.
+ - choice | disable | Disable.
+ - choice | certificate-inspection | Inspect SSL handshake only.
+ - choice | deep-inspection | Full SSL inspection.
+ required: false
+ choices: ["disable", "certificate-inspection", "deep-inspection"]
+
+ ssl_unsupported_ssl:
+ description:
+ - Action based on the SSL encryption used being unsupported.
+ - choice | bypass | Bypass.
+ - choice | inspect | Inspect.
+ - choice | block | Block.
+ required: false
+ choices: ["bypass", "inspect", "block"]
+
+ ssl_untrusted_cert:
+ description:
+ - Allow, ignore, or block the untrusted SSL session server certificate.
+ - choice | allow | Allow the untrusted server certificate.
+ - choice | block | Block the connection when an untrusted server certificate is detected.
+ - choice | ignore | Always take the server certificate as trusted.
+ required: false
+ choices: ["allow", "block", "ignore"]
+
+ ssl_exempt:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ ssl_exempt_address:
+ description:
+ - IPv4 address object.
+ required: false
+
+ ssl_exempt_address6:
+ description:
+ - IPv6 address object.
+ required: false
+
+ ssl_exempt_fortiguard_category:
+ description:
+ - FortiGuard category ID.
+ required: false
+
+ ssl_exempt_regex:
+ description:
+ - Exempt servers by regular expression.
+ required: false
+
+ ssl_exempt_type:
+ description:
+ - Type of address object (IPv4 or IPv6) or FortiGuard category.
+ - choice | fortiguard-category | FortiGuard category.
+ - choice | address | Firewall IPv4 address.
+ - choice | address6 | Firewall IPv6 address.
+ - choice | wildcard-fqdn | Fully Qualified Domain Name with wildcard characters.
+ - choice | regex | Regular expression FQDN.
+ required: false
+ choices: ["fortiguard-category", "address", "address6", "wildcard-fqdn", "regex"]
+
+ ssl_exempt_wildcard_fqdn:
+ description:
+ - Exempt servers by wildcard FQDN.
+ required: false
+
+ ssl_server:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ ssl_server_ftps_client_cert_request:
+ description:
+ - Action based on client certificate request failure during the FTPS handshake.
+ - choice | bypass | Bypass.
+ - choice | inspect | Inspect.
+ - choice | block | Block.
+ required: false
+ choices: ["bypass", "inspect", "block"]
+
+ ssl_server_https_client_cert_request:
+ description:
+ - Action based on client certificate request failure during the HTTPS handshake.
+ - choice | bypass | Bypass.
+ - choice | inspect | Inspect.
+ - choice | block | Block.
+ required: false
+ choices: ["bypass", "inspect", "block"]
+
+ ssl_server_imaps_client_cert_request:
+ description:
+ - Action based on client certificate request failure during the IMAPS handshake.
+ - choice | bypass | Bypass.
+ - choice | inspect | Inspect.
+ - choice | block | Block.
+ required: false
+ choices: ["bypass", "inspect", "block"]
+
+ ssl_server_ip:
+ description:
+ - IPv4 address of the SSL server.
+ required: false
+
+ ssl_server_pop3s_client_cert_request:
+ description:
+ - Action based on client certificate request failure during the POP3S handshake.
+ - choice | bypass | Bypass.
+ - choice | inspect | Inspect.
+ - choice | block | Block.
+ required: false
+ choices: ["bypass", "inspect", "block"]
+
+ ssl_server_smtps_client_cert_request:
+ description:
+ - Action based on client certificate request failure during the SMTPS handshake.
+ - choice | bypass | Bypass.
+ - choice | inspect | Inspect.
+ - choice | block | Block.
+ required: false
+ choices: ["bypass", "inspect", "block"]
+
+ ssl_server_ssl_other_client_cert_request:
+ description:
+ - Action based on client certificate request failure during an SSL protocol handshake.
+ - choice | bypass | Bypass.
+ - choice | inspect | Inspect.
+ - choice | block | Block.
+ required: false
+ choices: ["bypass", "inspect", "block"]
+
+
+'''
+
+EXAMPLES = '''
+ - name: DELETE Profile
+ community.fortios.fmgr_secprof_ssl_ssh:
+ name: Ansible_SSL_SSH_Profile
+ mode: delete
+
+ - name: CREATE Profile
+ community.fortios.fmgr_secprof_ssl_ssh:
+ name: Ansible_SSL_SSH_Profile
+ comment: "Created by Ansible Module TEST"
+ mode: set
+ mapi_over_https: enable
+ rpc_over_https: enable
+ server_cert_mode: replace
+ ssl_anomalies_log: enable
+ ssl_exemptions_log: enable
+ use_ssl_server: enable
+ whitelist: enable
+'''
+
+RETURN = """
+api_result:
+ description: full API response, includes status code and message
+ returned: always
+ type: str
+"""
+
+from ansible.module_utils.basic import AnsibleModule, env_fallback
+from ansible.module_utils.connection import Connection
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.fortimanager import FortiManagerHandler
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGBaseException
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRCommon
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRMethods
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import DEFAULT_RESULT_OBJ
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FAIL_SOCKET_MSG
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import prepare_dict
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import scrub_dict
+
+###############
+# START METHODS
+###############
+
+
+def fmgr_firewall_ssl_ssh_profile_modify(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+
+ mode = paramgram["mode"]
+ adom = paramgram["adom"]
+
+ response = DEFAULT_RESULT_OBJ
+ url = ""
+ datagram = {}
+
+ # EVAL THE MODE PARAMETER FOR SET OR ADD
+ if mode in ['set', 'add', 'update']:
+ url = '/pm/config/adom/{adom}/obj/firewall/ssl-ssh-profile'.format(adom=adom)
+ datagram = scrub_dict(prepare_dict(paramgram))
+
+ # EVAL THE MODE PARAMETER FOR DELETE
+ elif mode == "delete":
+ # SET THE CORRECT URL FOR DELETE
+ url = '/pm/config/adom/{adom}/obj/firewall/ssl-ssh-profile/{name}'.format(adom=adom, name=paramgram["name"])
+ datagram = {}
+
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+
+ return response
+
+
+#############
+# END METHODS
+#############
+
+
+def main():
+ argument_spec = dict(
+ adom=dict(type="str", default="root"),
+ mode=dict(choices=["add", "set", "delete", "update"], type="str", default="add"),
+
+ whitelist=dict(required=False, type="str", choices=["disable", "enable"]),
+ use_ssl_server=dict(required=False, type="str", choices=["disable", "enable"]),
+ untrusted_caname=dict(required=False, type="str"),
+ ssl_exemptions_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ ssl_anomalies_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ server_cert_mode=dict(required=False, type="str", choices=["re-sign", "replace"]),
+ server_cert=dict(required=False, type="str"),
+ rpc_over_https=dict(required=False, type="str", choices=["disable", "enable"]),
+ name=dict(required=False, type="str"),
+ mapi_over_https=dict(required=False, type="str", choices=["disable", "enable"]),
+ comment=dict(required=False, type="str"),
+ caname=dict(required=False, type="str"),
+ ftps=dict(required=False, type="list"),
+ ftps_allow_invalid_server_cert=dict(required=False, type="str", choices=["disable", "enable"]),
+ ftps_client_cert_request=dict(required=False, type="str", choices=["bypass", "inspect", "block"]),
+ ftps_ports=dict(required=False, type="str"),
+ ftps_status=dict(required=False, type="str", choices=["disable", "deep-inspection"]),
+ ftps_unsupported_ssl=dict(required=False, type="str", choices=["bypass", "inspect", "block"]),
+ ftps_untrusted_cert=dict(required=False, type="str", choices=["allow", "block", "ignore"]),
+ https=dict(required=False, type="list"),
+ https_allow_invalid_server_cert=dict(required=False, type="str", choices=["disable", "enable"]),
+ https_client_cert_request=dict(required=False, type="str", choices=["bypass", "inspect", "block"]),
+ https_ports=dict(required=False, type="str"),
+ https_status=dict(required=False, type="str", choices=["disable", "certificate-inspection", "deep-inspection"]),
+ https_unsupported_ssl=dict(required=False, type="str", choices=["bypass", "inspect", "block"]),
+ https_untrusted_cert=dict(required=False, type="str", choices=["allow", "block", "ignore"]),
+ imaps=dict(required=False, type="list"),
+ imaps_allow_invalid_server_cert=dict(required=False, type="str", choices=["disable", "enable"]),
+ imaps_client_cert_request=dict(required=False, type="str", choices=["bypass", "inspect", "block"]),
+ imaps_ports=dict(required=False, type="str"),
+ imaps_status=dict(required=False, type="str", choices=["disable", "deep-inspection"]),
+ imaps_unsupported_ssl=dict(required=False, type="str", choices=["bypass", "inspect", "block"]),
+ imaps_untrusted_cert=dict(required=False, type="str", choices=["allow", "block", "ignore"]),
+ pop3s=dict(required=False, type="list"),
+ pop3s_allow_invalid_server_cert=dict(required=False, type="str", choices=["disable", "enable"]),
+ pop3s_client_cert_request=dict(required=False, type="str", choices=["bypass", "inspect", "block"]),
+ pop3s_ports=dict(required=False, type="str"),
+ pop3s_status=dict(required=False, type="str", choices=["disable", "deep-inspection"]),
+ pop3s_unsupported_ssl=dict(required=False, type="str", choices=["bypass", "inspect", "block"]),
+ pop3s_untrusted_cert=dict(required=False, type="str", choices=["allow", "block", "ignore"]),
+ smtps=dict(required=False, type="list"),
+ smtps_allow_invalid_server_cert=dict(required=False, type="str", choices=["disable", "enable"]),
+ smtps_client_cert_request=dict(required=False, type="str", choices=["bypass", "inspect", "block"]),
+ smtps_ports=dict(required=False, type="str"),
+ smtps_status=dict(required=False, type="str", choices=["disable", "deep-inspection"]),
+ smtps_unsupported_ssl=dict(required=False, type="str", choices=["bypass", "inspect", "block"]),
+ smtps_untrusted_cert=dict(required=False, type="str", choices=["allow", "block", "ignore"]),
+ ssh=dict(required=False, type="list"),
+ ssh_inspect_all=dict(required=False, type="str", choices=["disable", "deep-inspection"]),
+ ssh_ports=dict(required=False, type="str"),
+ ssh_ssh_algorithm=dict(required=False, type="str", choices=["compatible", "high-encryption"]),
+ ssh_ssh_policy_check=dict(required=False, type="str", choices=["disable", "enable"]),
+ ssh_ssh_tun_policy_check=dict(required=False, type="str", choices=["disable", "enable"]),
+ ssh_status=dict(required=False, type="str", choices=["disable", "deep-inspection"]),
+ ssh_unsupported_version=dict(required=False, type="str", choices=["block", "bypass"]),
+ ssl=dict(required=False, type="list"),
+ ssl_allow_invalid_server_cert=dict(required=False, type="str", choices=["disable", "enable"]),
+ ssl_client_cert_request=dict(required=False, type="str", choices=["bypass", "inspect", "block"]),
+ ssl_inspect_all=dict(required=False, type="str", choices=["disable", "certificate-inspection",
+ "deep-inspection"]),
+ ssl_unsupported_ssl=dict(required=False, type="str", choices=["bypass", "inspect", "block"]),
+ ssl_untrusted_cert=dict(required=False, type="str", choices=["allow", "block", "ignore"]),
+ ssl_exempt=dict(required=False, type="list"),
+ ssl_exempt_address=dict(required=False, type="str"),
+ ssl_exempt_address6=dict(required=False, type="str"),
+ ssl_exempt_fortiguard_category=dict(required=False, type="str"),
+ ssl_exempt_regex=dict(required=False, type="str"),
+ ssl_exempt_type=dict(required=False, type="str", choices=["fortiguard-category", "address", "address6",
+ "wildcard-fqdn", "regex"]),
+ ssl_exempt_wildcard_fqdn=dict(required=False, type="str"),
+ ssl_server=dict(required=False, type="list"),
+ ssl_server_ftps_client_cert_request=dict(required=False, type="str", choices=["bypass", "inspect", "block"]),
+ ssl_server_https_client_cert_request=dict(required=False, type="str", choices=["bypass", "inspect", "block"]),
+ ssl_server_imaps_client_cert_request=dict(required=False, type="str", choices=["bypass", "inspect", "block"]),
+ ssl_server_ip=dict(required=False, type="str"),
+ ssl_server_pop3s_client_cert_request=dict(required=False, type="str", choices=["bypass", "inspect", "block"]),
+ ssl_server_smtps_client_cert_request=dict(required=False, type="str", choices=["bypass", "inspect", "block"]),
+ ssl_server_ssl_other_client_cert_request=dict(required=False, type="str", choices=["bypass", "inspect",
+ "block"]),
+
+ )
+
+ module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False, )
+ # MODULE PARAMGRAM
+ paramgram = {
+ "mode": module.params["mode"],
+ "adom": module.params["adom"],
+ "whitelist": module.params["whitelist"],
+ "use-ssl-server": module.params["use_ssl_server"],
+ "untrusted-caname": module.params["untrusted_caname"],
+ "ssl-exemptions-log": module.params["ssl_exemptions_log"],
+ "ssl-anomalies-log": module.params["ssl_anomalies_log"],
+ "server-cert-mode": module.params["server_cert_mode"],
+ "server-cert": module.params["server_cert"],
+ "rpc-over-https": module.params["rpc_over_https"],
+ "name": module.params["name"],
+ "mapi-over-https": module.params["mapi_over_https"],
+ "comment": module.params["comment"],
+ "caname": module.params["caname"],
+ "ftps": {
+ "allow-invalid-server-cert": module.params["ftps_allow_invalid_server_cert"],
+ "client-cert-request": module.params["ftps_client_cert_request"],
+ "ports": module.params["ftps_ports"],
+ "status": module.params["ftps_status"],
+ "unsupported-ssl": module.params["ftps_unsupported_ssl"],
+ "untrusted-cert": module.params["ftps_untrusted_cert"],
+ },
+ "https": {
+ "allow-invalid-server-cert": module.params["https_allow_invalid_server_cert"],
+ "client-cert-request": module.params["https_client_cert_request"],
+ "ports": module.params["https_ports"],
+ "status": module.params["https_status"],
+ "unsupported-ssl": module.params["https_unsupported_ssl"],
+ "untrusted-cert": module.params["https_untrusted_cert"],
+ },
+ "imaps": {
+ "allow-invalid-server-cert": module.params["imaps_allow_invalid_server_cert"],
+ "client-cert-request": module.params["imaps_client_cert_request"],
+ "ports": module.params["imaps_ports"],
+ "status": module.params["imaps_status"],
+ "unsupported-ssl": module.params["imaps_unsupported_ssl"],
+ "untrusted-cert": module.params["imaps_untrusted_cert"],
+ },
+ "pop3s": {
+ "allow-invalid-server-cert": module.params["pop3s_allow_invalid_server_cert"],
+ "client-cert-request": module.params["pop3s_client_cert_request"],
+ "ports": module.params["pop3s_ports"],
+ "status": module.params["pop3s_status"],
+ "unsupported-ssl": module.params["pop3s_unsupported_ssl"],
+ "untrusted-cert": module.params["pop3s_untrusted_cert"],
+ },
+ "smtps": {
+ "allow-invalid-server-cert": module.params["smtps_allow_invalid_server_cert"],
+ "client-cert-request": module.params["smtps_client_cert_request"],
+ "ports": module.params["smtps_ports"],
+ "status": module.params["smtps_status"],
+ "unsupported-ssl": module.params["smtps_unsupported_ssl"],
+ "untrusted-cert": module.params["smtps_untrusted_cert"],
+ },
+ "ssh": {
+ "inspect-all": module.params["ssh_inspect_all"],
+ "ports": module.params["ssh_ports"],
+ "ssh-algorithm": module.params["ssh_ssh_algorithm"],
+ "ssh-policy-check": module.params["ssh_ssh_policy_check"],
+ "ssh-tun-policy-check": module.params["ssh_ssh_tun_policy_check"],
+ "status": module.params["ssh_status"],
+ "unsupported-version": module.params["ssh_unsupported_version"],
+ },
+ "ssl": {
+ "allow-invalid-server-cert": module.params["ssl_allow_invalid_server_cert"],
+ "client-cert-request": module.params["ssl_client_cert_request"],
+ "inspect-all": module.params["ssl_inspect_all"],
+ "unsupported-ssl": module.params["ssl_unsupported_ssl"],
+ "untrusted-cert": module.params["ssl_untrusted_cert"],
+ },
+ "ssl-exempt": {
+ "address": module.params["ssl_exempt_address"],
+ "address6": module.params["ssl_exempt_address6"],
+ "fortiguard-category": module.params["ssl_exempt_fortiguard_category"],
+ "regex": module.params["ssl_exempt_regex"],
+ "type": module.params["ssl_exempt_type"],
+ "wildcard-fqdn": module.params["ssl_exempt_wildcard_fqdn"],
+ },
+ "ssl-server": {
+ "ftps-client-cert-request": module.params["ssl_server_ftps_client_cert_request"],
+ "https-client-cert-request": module.params["ssl_server_https_client_cert_request"],
+ "imaps-client-cert-request": module.params["ssl_server_imaps_client_cert_request"],
+ "ip": module.params["ssl_server_ip"],
+ "pop3s-client-cert-request": module.params["ssl_server_pop3s_client_cert_request"],
+ "smtps-client-cert-request": module.params["ssl_server_smtps_client_cert_request"],
+ "ssl-other-client-cert-request": module.params["ssl_server_ssl_other_client_cert_request"],
+ }
+ }
+
+ module.paramgram = paramgram
+ fmgr = None
+ if module._socket_path:
+ connection = Connection(module._socket_path)
+ fmgr = FortiManagerHandler(connection, module)
+ fmgr.tools = FMGRCommon()
+ else:
+ module.fail_json(**FAIL_SOCKET_MSG)
+
+ list_overrides = ['ftps', 'https', 'imaps', 'pop3s', 'smtps', 'ssh', 'ssl', 'ssl-exempt', 'ssl-server']
+ paramgram = fmgr.tools.paramgram_child_list_override(list_overrides=list_overrides,
+ paramgram=paramgram, module=module)
+
+ results = DEFAULT_RESULT_OBJ
+
+ try:
+
+ results = fmgr_firewall_ssl_ssh_profile_modify(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ return module.exit_json(**results[1])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_voip.py b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_voip.py
new file mode 100644
index 00000000..31b71288
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_voip.py
@@ -0,0 +1,1198 @@
+#!/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: fmgr_secprof_voip
+notes:
+ - Full Documentation at U(https://ftnt-ansible-docs.readthedocs.io/en/latest/).
+author:
+ - Luke Weighall (@lweighall)
+ - Andrew Welsh (@Ghilli3)
+ - Jim Huber (@p4r4n0y1ng)
+short_description: VOIP security profiles in FMG
+description:
+ - Manage VOIP security profiles in FortiManager via API
+
+options:
+ adom:
+ description:
+ - The ADOM the configuration should belong to.
+ required: false
+ default: root
+
+ mode:
+ description:
+ - Sets one of three modes for managing the object.
+ - Allows use of soft-adds instead of overwriting existing values
+ choices: ['add', 'set', 'delete', 'update']
+ required: false
+ default: add
+
+ name:
+ description:
+ - Profile name.
+ required: false
+
+ comment:
+ description:
+ - Comment.
+ required: false
+
+ sccp:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ sccp_block_mcast:
+ description:
+ - Enable/disable block multicast RTP connections.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sccp_log_call_summary:
+ description:
+ - Enable/disable log summary of SCCP calls.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sccp_log_violations:
+ description:
+ - Enable/disable logging of SCCP violations.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sccp_max_calls:
+ description:
+ - Maximum calls per minute per SCCP client (max 65535).
+ required: false
+
+ sccp_status:
+ description:
+ - Enable/disable SCCP.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sccp_verify_header:
+ description:
+ - Enable/disable verify SCCP header content.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ sip_ack_rate:
+ description:
+ - ACK request rate limit (per second, per policy).
+ required: false
+
+ sip_block_ack:
+ description:
+ - Enable/disable block ACK requests.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_block_bye:
+ description:
+ - Enable/disable block BYE requests.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_block_cancel:
+ description:
+ - Enable/disable block CANCEL requests.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_block_geo_red_options:
+ description:
+ - Enable/disable block OPTIONS requests, but OPTIONS requests still notify for redundancy.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_block_info:
+ description:
+ - Enable/disable block INFO requests.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_block_invite:
+ description:
+ - Enable/disable block INVITE requests.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_block_long_lines:
+ description:
+ - Enable/disable block requests with headers exceeding max-line-length.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_block_message:
+ description:
+ - Enable/disable block MESSAGE requests.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_block_notify:
+ description:
+ - Enable/disable block NOTIFY requests.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_block_options:
+ description:
+ - Enable/disable block OPTIONS requests and no OPTIONS as notifying message for redundancy either.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_block_prack:
+ description:
+ - Enable/disable block prack requests.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_block_publish:
+ description:
+ - Enable/disable block PUBLISH requests.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_block_refer:
+ description:
+ - Enable/disable block REFER requests.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_block_register:
+ description:
+ - Enable/disable block REGISTER requests.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_block_subscribe:
+ description:
+ - Enable/disable block SUBSCRIBE requests.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_block_unknown:
+ description:
+ - Block unrecognized SIP requests (enabled by default).
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_block_update:
+ description:
+ - Enable/disable block UPDATE requests.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_bye_rate:
+ description:
+ - BYE request rate limit (per second, per policy).
+ required: false
+
+ sip_call_keepalive:
+ description:
+ - Continue tracking calls with no RTP for this many minutes.
+ required: false
+
+ sip_cancel_rate:
+ description:
+ - CANCEL request rate limit (per second, per policy).
+ required: false
+
+ sip_contact_fixup:
+ description:
+ - Fixup contact anyway even if contact's IP|port doesn't match session's IP|port.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_hnt_restrict_source_ip:
+ description:
+ - Enable/disable restrict RTP source IP to be the same as SIP source IP when HNT is enabled.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_hosted_nat_traversal:
+ description:
+ - Hosted NAT Traversal (HNT).
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_info_rate:
+ description:
+ - INFO request rate limit (per second, per policy).
+ required: false
+
+ sip_invite_rate:
+ description:
+ - INVITE request rate limit (per second, per policy).
+ required: false
+
+ sip_ips_rtp:
+ description:
+ - Enable/disable allow IPS on RTP.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_log_call_summary:
+ description:
+ - Enable/disable logging of SIP call summary.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_log_violations:
+ description:
+ - Enable/disable logging of SIP violations.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_malformed_header_allow:
+ description:
+ - Action for malformed Allow header.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_call_id:
+ description:
+ - Action for malformed Call-ID header.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_contact:
+ description:
+ - Action for malformed Contact header.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_content_length:
+ description:
+ - Action for malformed Content-Length header.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_content_type:
+ description:
+ - Action for malformed Content-Type header.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_cseq:
+ description:
+ - Action for malformed CSeq header.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_expires:
+ description:
+ - Action for malformed Expires header.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_from:
+ description:
+ - Action for malformed From header.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_max_forwards:
+ description:
+ - Action for malformed Max-Forwards header.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_p_asserted_identity:
+ description:
+ - Action for malformed P-Asserted-Identity header.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_rack:
+ description:
+ - Action for malformed RAck header.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_record_route:
+ description:
+ - Action for malformed Record-Route header.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_route:
+ description:
+ - Action for malformed Route header.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_rseq:
+ description:
+ - Action for malformed RSeq header.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_sdp_a:
+ description:
+ - Action for malformed SDP a line.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_sdp_b:
+ description:
+ - Action for malformed SDP b line.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_sdp_c:
+ description:
+ - Action for malformed SDP c line.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_sdp_i:
+ description:
+ - Action for malformed SDP i line.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_sdp_k:
+ description:
+ - Action for malformed SDP k line.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_sdp_m:
+ description:
+ - Action for malformed SDP m line.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_sdp_o:
+ description:
+ - Action for malformed SDP o line.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_sdp_r:
+ description:
+ - Action for malformed SDP r line.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_sdp_s:
+ description:
+ - Action for malformed SDP s line.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_sdp_t:
+ description:
+ - Action for malformed SDP t line.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_sdp_v:
+ description:
+ - Action for malformed SDP v line.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_sdp_z:
+ description:
+ - Action for malformed SDP z line.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_to:
+ description:
+ - Action for malformed To header.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_header_via:
+ description:
+ - Action for malformed VIA header.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_malformed_request_line:
+ description:
+ - Action for malformed request line.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_max_body_length:
+ description:
+ - Maximum SIP message body length (0 meaning no limit).
+ required: false
+
+ sip_max_dialogs:
+ description:
+ - Maximum number of concurrent calls/dialogs (per policy).
+ required: false
+
+ sip_max_idle_dialogs:
+ description:
+ - Maximum number established but idle dialogs to retain (per policy).
+ required: false
+
+ sip_max_line_length:
+ description:
+ - Maximum SIP header line length (78-4096).
+ required: false
+
+ sip_message_rate:
+ description:
+ - MESSAGE request rate limit (per second, per policy).
+ required: false
+
+ sip_nat_trace:
+ description:
+ - Enable/disable preservation of original IP in SDP i line.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_no_sdp_fixup:
+ description:
+ - Enable/disable no SDP fix-up.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_notify_rate:
+ description:
+ - NOTIFY request rate limit (per second, per policy).
+ required: false
+
+ sip_open_contact_pinhole:
+ description:
+ - Enable/disable open pinhole for non-REGISTER Contact port.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_open_record_route_pinhole:
+ description:
+ - Enable/disable open pinhole for Record-Route port.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_open_register_pinhole:
+ description:
+ - Enable/disable open pinhole for REGISTER Contact port.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_open_via_pinhole:
+ description:
+ - Enable/disable open pinhole for Via port.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_options_rate:
+ description:
+ - OPTIONS request rate limit (per second, per policy).
+ required: false
+
+ sip_prack_rate:
+ description:
+ - PRACK request rate limit (per second, per policy).
+ required: false
+
+ sip_preserve_override:
+ description:
+ - Override i line to preserve original IPS (default| append).
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_provisional_invite_expiry_time:
+ description:
+ - Expiry time for provisional INVITE (10 - 3600 sec).
+ required: false
+
+ sip_publish_rate:
+ description:
+ - PUBLISH request rate limit (per second, per policy).
+ required: false
+
+ sip_refer_rate:
+ description:
+ - REFER request rate limit (per second, per policy).
+ required: false
+
+ sip_register_contact_trace:
+ description:
+ - Enable/disable trace original IP/port within the contact header of REGISTER requests.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_register_rate:
+ description:
+ - REGISTER request rate limit (per second, per policy).
+ required: false
+
+ sip_rfc2543_branch:
+ description:
+ - Enable/disable support via branch compliant with RFC 2543.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_rtp:
+ description:
+ - Enable/disable create pinholes for RTP traffic to traverse firewall.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_ssl_algorithm:
+ description:
+ - Relative strength of encryption algorithms accepted in negotiation.
+ - choice | high | High encryption. Allow only AES and ChaCha.
+ - choice | medium | Medium encryption. Allow AES, ChaCha, 3DES, and RC4.
+ - choice | low | Low encryption. Allow AES, ChaCha, 3DES, RC4, and DES.
+ required: false
+ choices: ["high", "medium", "low"]
+
+ sip_ssl_auth_client:
+ description:
+ - Require a client certificate and authenticate it with the peer/peergrp.
+ required: false
+
+ sip_ssl_auth_server:
+ description:
+ - Authenticate the server's certificate with the peer/peergrp.
+ required: false
+
+ sip_ssl_client_certificate:
+ description:
+ - Name of Certificate to offer to server if requested.
+ required: false
+
+ sip_ssl_client_renegotiation:
+ description:
+ - Allow/block client renegotiation by server.
+ - choice | allow | Allow a SSL client to renegotiate.
+ - choice | deny | Abort any SSL connection that attempts to renegotiate.
+ - choice | secure | Reject any SSL connection that does not offer a RFC 5746 Secure Renegotiation Indication.
+ required: false
+ choices: ["allow", "deny", "secure"]
+
+ sip_ssl_max_version:
+ description:
+ - Highest SSL/TLS version to negotiate.
+ - choice | ssl-3.0 | SSL 3.0.
+ - choice | tls-1.0 | TLS 1.0.
+ - choice | tls-1.1 | TLS 1.1.
+ - choice | tls-1.2 | TLS 1.2.
+ required: false
+ choices: ["ssl-3.0", "tls-1.0", "tls-1.1", "tls-1.2"]
+
+ sip_ssl_min_version:
+ description:
+ - Lowest SSL/TLS version to negotiate.
+ - choice | ssl-3.0 | SSL 3.0.
+ - choice | tls-1.0 | TLS 1.0.
+ - choice | tls-1.1 | TLS 1.1.
+ - choice | tls-1.2 | TLS 1.2.
+ required: false
+ choices: ["ssl-3.0", "tls-1.0", "tls-1.1", "tls-1.2"]
+
+ sip_ssl_mode:
+ description:
+ - SSL/TLS mode for encryption &amp; decryption of traffic.
+ - choice | off | No SSL.
+ - choice | full | Client to FortiGate and FortiGate to Server SSL.
+ required: false
+ choices: ["off", "full"]
+
+ sip_ssl_pfs:
+ description:
+ - SSL Perfect Forward Secrecy.
+ - choice | require | PFS mandatory.
+ - choice | deny | PFS rejected.
+ - choice | allow | PFS allowed.
+ required: false
+ choices: ["require", "deny", "allow"]
+
+ sip_ssl_send_empty_frags:
+ description:
+ - Send empty fragments to avoid attack on CBC IV (SSL 3.0 &amp; TLS 1.0 only).
+ - choice | disable | Do not send empty fragments.
+ - choice | enable | Send empty fragments.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_ssl_server_certificate:
+ description:
+ - Name of Certificate return to the client in every SSL connection.
+ required: false
+
+ sip_status:
+ description:
+ - Enable/disable SIP.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_strict_register:
+ description:
+ - Enable/disable only allow the registrar to connect.
+ - choice | disable | Disable status.
+ - choice | enable | Enable status.
+ required: false
+ choices: ["disable", "enable"]
+
+ sip_subscribe_rate:
+ description:
+ - SUBSCRIBE request rate limit (per second, per policy).
+ required: false
+
+ sip_unknown_header:
+ description:
+ - Action for unknown SIP header.
+ - choice | pass | Bypass malformed messages.
+ - choice | discard | Discard malformed messages.
+ - choice | respond | Respond with error code.
+ required: false
+ choices: ["pass", "discard", "respond"]
+
+ sip_update_rate:
+ description:
+ - UPDATE request rate limit (per second, per policy).
+ required: false
+
+
+'''
+
+EXAMPLES = '''
+ - name: DELETE Profile
+ community.fortios.fmgr_secprof_voip:
+ name: "Ansible_VOIP_Profile"
+ mode: "delete"
+
+ - name: Create FMGR_VOIP_PROFILE
+ community.fortios.fmgr_secprof_voip:
+ mode: "set"
+ adom: "root"
+ name: "Ansible_VOIP_Profile"
+ comment: "Created by Ansible"
+ sccp: {block-mcast: "enable", log-call-summary: "enable", log-violations: "enable", status: "enable"}
+'''
+
+RETURN = """
+api_result:
+ description: full API response, includes status code and message
+ returned: always
+ type: str
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.connection import Connection
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.fortimanager import FortiManagerHandler
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGBaseException
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRCommon
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import DEFAULT_RESULT_OBJ
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FAIL_SOCKET_MSG
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import prepare_dict
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import scrub_dict
+
+
+###############
+# START METHODS
+###############
+
+
+def fmgr_voip_profile_modify(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+
+ mode = paramgram["mode"]
+ adom = paramgram["adom"]
+
+ response = DEFAULT_RESULT_OBJ
+ url = ""
+ datagram = {}
+
+ # EVAL THE MODE PARAMETER FOR SET OR ADD
+ if mode in ['set', 'add', 'update']:
+ url = '/pm/config/adom/{adom}/obj/voip/profile'.format(adom=adom)
+ datagram = scrub_dict(prepare_dict(paramgram))
+
+ # EVAL THE MODE PARAMETER FOR DELETE
+ elif mode == "delete":
+ # SET THE CORRECT URL FOR DELETE
+ url = '/pm/config/adom/{adom}/obj/voip/profile/{name}'.format(adom=adom, name=paramgram["name"])
+ datagram = {}
+
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+
+ return response
+
+
+#############
+# END METHODS
+#############
+
+
+def main():
+ argument_spec = dict(
+ adom=dict(type="str", default="root"),
+ mode=dict(choices=["add", "set", "delete", "update"], type="str", default="add"),
+
+ name=dict(required=False, type="str"),
+ comment=dict(required=False, type="str"),
+ sccp=dict(required=False, type="dict"),
+ sccp_block_mcast=dict(required=False, type="str", choices=["disable", "enable"]),
+ sccp_log_call_summary=dict(required=False, type="str", choices=["disable", "enable"]),
+ sccp_log_violations=dict(required=False, type="str", choices=["disable", "enable"]),
+ sccp_max_calls=dict(required=False, type="int"),
+ sccp_status=dict(required=False, type="str", choices=["disable", "enable"]),
+ sccp_verify_header=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip=dict(required=False, type="dict"),
+ sip_ack_rate=dict(required=False, type="int"),
+ sip_block_ack=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_block_bye=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_block_cancel=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_block_geo_red_options=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_block_info=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_block_invite=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_block_long_lines=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_block_message=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_block_notify=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_block_options=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_block_prack=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_block_publish=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_block_refer=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_block_register=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_block_subscribe=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_block_unknown=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_block_update=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_bye_rate=dict(required=False, type="int"),
+ sip_call_keepalive=dict(required=False, type="int"),
+ sip_cancel_rate=dict(required=False, type="int"),
+ sip_contact_fixup=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_hnt_restrict_source_ip=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_hosted_nat_traversal=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_info_rate=dict(required=False, type="int"),
+ sip_invite_rate=dict(required=False, type="int"),
+ sip_ips_rtp=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_log_call_summary=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_log_violations=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_malformed_header_allow=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_call_id=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_contact=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_content_length=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_content_type=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_cseq=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_expires=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_from=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_max_forwards=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_p_asserted_identity=dict(required=False, type="str", choices=["pass",
+ "discard",
+ "respond"]),
+ sip_malformed_header_rack=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_record_route=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_route=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_rseq=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_sdp_a=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_sdp_b=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_sdp_c=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_sdp_i=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_sdp_k=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_sdp_m=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_sdp_o=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_sdp_r=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_sdp_s=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_sdp_t=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_sdp_v=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_sdp_z=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_to=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_header_via=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_malformed_request_line=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_max_body_length=dict(required=False, type="int"),
+ sip_max_dialogs=dict(required=False, type="int"),
+ sip_max_idle_dialogs=dict(required=False, type="int"),
+ sip_max_line_length=dict(required=False, type="int"),
+ sip_message_rate=dict(required=False, type="int"),
+ sip_nat_trace=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_no_sdp_fixup=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_notify_rate=dict(required=False, type="int"),
+ sip_open_contact_pinhole=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_open_record_route_pinhole=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_open_register_pinhole=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_open_via_pinhole=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_options_rate=dict(required=False, type="int"),
+ sip_prack_rate=dict(required=False, type="int"),
+ sip_preserve_override=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_provisional_invite_expiry_time=dict(required=False, type="int"),
+ sip_publish_rate=dict(required=False, type="int"),
+ sip_refer_rate=dict(required=False, type="int"),
+ sip_register_contact_trace=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_register_rate=dict(required=False, type="int"),
+ sip_rfc2543_branch=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_rtp=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_ssl_algorithm=dict(required=False, type="str", choices=["high", "medium", "low"]),
+ sip_ssl_auth_client=dict(required=False, type="str"),
+ sip_ssl_auth_server=dict(required=False, type="str"),
+ sip_ssl_client_certificate=dict(required=False, type="str"),
+ sip_ssl_client_renegotiation=dict(required=False, type="str", choices=["allow", "deny", "secure"]),
+ sip_ssl_max_version=dict(required=False, type="str", choices=["ssl-3.0", "tls-1.0", "tls-1.1", "tls-1.2"]),
+ sip_ssl_min_version=dict(required=False, type="str", choices=["ssl-3.0", "tls-1.0", "tls-1.1", "tls-1.2"]),
+ sip_ssl_mode=dict(required=False, type="str", choices=["off", "full"]),
+ sip_ssl_pfs=dict(required=False, type="str", choices=["require", "deny", "allow"]),
+ sip_ssl_send_empty_frags=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_ssl_server_certificate=dict(required=False, type="str"),
+ sip_status=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_strict_register=dict(required=False, type="str", choices=["disable", "enable"]),
+ sip_subscribe_rate=dict(required=False, type="int"),
+ sip_unknown_header=dict(required=False, type="str", choices=["pass", "discard", "respond"]),
+ sip_update_rate=dict(required=False, type="int"),
+
+ )
+
+ module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False, )
+ # MODULE PARAMGRAM
+ paramgram = {
+ "mode": module.params["mode"],
+ "adom": module.params["adom"],
+ "name": module.params["name"],
+ "comment": module.params["comment"],
+ "sccp": {
+ "block-mcast": module.params["sccp_block_mcast"],
+ "log-call-summary": module.params["sccp_log_call_summary"],
+ "log-violations": module.params["sccp_log_violations"],
+ "max-calls": module.params["sccp_max_calls"],
+ "status": module.params["sccp_status"],
+ "verify-header": module.params["sccp_verify_header"],
+ },
+ "sip": {
+ "ack-rate": module.params["sip_ack_rate"],
+ "block-ack": module.params["sip_block_ack"],
+ "block-bye": module.params["sip_block_bye"],
+ "block-cancel": module.params["sip_block_cancel"],
+ "block-geo-red-options": module.params["sip_block_geo_red_options"],
+ "block-info": module.params["sip_block_info"],
+ "block-invite": module.params["sip_block_invite"],
+ "block-long-lines": module.params["sip_block_long_lines"],
+ "block-message": module.params["sip_block_message"],
+ "block-notify": module.params["sip_block_notify"],
+ "block-options": module.params["sip_block_options"],
+ "block-prack": module.params["sip_block_prack"],
+ "block-publish": module.params["sip_block_publish"],
+ "block-refer": module.params["sip_block_refer"],
+ "block-register": module.params["sip_block_register"],
+ "block-subscribe": module.params["sip_block_subscribe"],
+ "block-unknown": module.params["sip_block_unknown"],
+ "block-update": module.params["sip_block_update"],
+ "bye-rate": module.params["sip_bye_rate"],
+ "call-keepalive": module.params["sip_call_keepalive"],
+ "cancel-rate": module.params["sip_cancel_rate"],
+ "contact-fixup": module.params["sip_contact_fixup"],
+ "hnt-restrict-source-ip": module.params["sip_hnt_restrict_source_ip"],
+ "hosted-nat-traversal": module.params["sip_hosted_nat_traversal"],
+ "info-rate": module.params["sip_info_rate"],
+ "invite-rate": module.params["sip_invite_rate"],
+ "ips-rtp": module.params["sip_ips_rtp"],
+ "log-call-summary": module.params["sip_log_call_summary"],
+ "log-violations": module.params["sip_log_violations"],
+ "malformed-header-allow": module.params["sip_malformed_header_allow"],
+ "malformed-header-call-id": module.params["sip_malformed_header_call_id"],
+ "malformed-header-contact": module.params["sip_malformed_header_contact"],
+ "malformed-header-content-length": module.params["sip_malformed_header_content_length"],
+ "malformed-header-content-type": module.params["sip_malformed_header_content_type"],
+ "malformed-header-cseq": module.params["sip_malformed_header_cseq"],
+ "malformed-header-expires": module.params["sip_malformed_header_expires"],
+ "malformed-header-from": module.params["sip_malformed_header_from"],
+ "malformed-header-max-forwards": module.params["sip_malformed_header_max_forwards"],
+ "malformed-header-p-asserted-identity": module.params["sip_malformed_header_p_asserted_identity"],
+ "malformed-header-rack": module.params["sip_malformed_header_rack"],
+ "malformed-header-record-route": module.params["sip_malformed_header_record_route"],
+ "malformed-header-route": module.params["sip_malformed_header_route"],
+ "malformed-header-rseq": module.params["sip_malformed_header_rseq"],
+ "malformed-header-sdp-a": module.params["sip_malformed_header_sdp_a"],
+ "malformed-header-sdp-b": module.params["sip_malformed_header_sdp_b"],
+ "malformed-header-sdp-c": module.params["sip_malformed_header_sdp_c"],
+ "malformed-header-sdp-i": module.params["sip_malformed_header_sdp_i"],
+ "malformed-header-sdp-k": module.params["sip_malformed_header_sdp_k"],
+ "malformed-header-sdp-m": module.params["sip_malformed_header_sdp_m"],
+ "malformed-header-sdp-o": module.params["sip_malformed_header_sdp_o"],
+ "malformed-header-sdp-r": module.params["sip_malformed_header_sdp_r"],
+ "malformed-header-sdp-s": module.params["sip_malformed_header_sdp_s"],
+ "malformed-header-sdp-t": module.params["sip_malformed_header_sdp_t"],
+ "malformed-header-sdp-v": module.params["sip_malformed_header_sdp_v"],
+ "malformed-header-sdp-z": module.params["sip_malformed_header_sdp_z"],
+ "malformed-header-to": module.params["sip_malformed_header_to"],
+ "malformed-header-via": module.params["sip_malformed_header_via"],
+ "malformed-request-line": module.params["sip_malformed_request_line"],
+ "max-body-length": module.params["sip_max_body_length"],
+ "max-dialogs": module.params["sip_max_dialogs"],
+ "max-idle-dialogs": module.params["sip_max_idle_dialogs"],
+ "max-line-length": module.params["sip_max_line_length"],
+ "message-rate": module.params["sip_message_rate"],
+ "nat-trace": module.params["sip_nat_trace"],
+ "no-sdp-fixup": module.params["sip_no_sdp_fixup"],
+ "notify-rate": module.params["sip_notify_rate"],
+ "open-contact-pinhole": module.params["sip_open_contact_pinhole"],
+ "open-record-route-pinhole": module.params["sip_open_record_route_pinhole"],
+ "open-register-pinhole": module.params["sip_open_register_pinhole"],
+ "open-via-pinhole": module.params["sip_open_via_pinhole"],
+ "options-rate": module.params["sip_options_rate"],
+ "prack-rate": module.params["sip_prack_rate"],
+ "preserve-override": module.params["sip_preserve_override"],
+ "provisional-invite-expiry-time": module.params["sip_provisional_invite_expiry_time"],
+ "publish-rate": module.params["sip_publish_rate"],
+ "refer-rate": module.params["sip_refer_rate"],
+ "register-contact-trace": module.params["sip_register_contact_trace"],
+ "register-rate": module.params["sip_register_rate"],
+ "rfc2543-branch": module.params["sip_rfc2543_branch"],
+ "rtp": module.params["sip_rtp"],
+ "ssl-algorithm": module.params["sip_ssl_algorithm"],
+ "ssl-auth-client": module.params["sip_ssl_auth_client"],
+ "ssl-auth-server": module.params["sip_ssl_auth_server"],
+ "ssl-client-certificate": module.params["sip_ssl_client_certificate"],
+ "ssl-client-renegotiation": module.params["sip_ssl_client_renegotiation"],
+ "ssl-max-version": module.params["sip_ssl_max_version"],
+ "ssl-min-version": module.params["sip_ssl_min_version"],
+ "ssl-mode": module.params["sip_ssl_mode"],
+ "ssl-pfs": module.params["sip_ssl_pfs"],
+ "ssl-send-empty-frags": module.params["sip_ssl_send_empty_frags"],
+ "ssl-server-certificate": module.params["sip_ssl_server_certificate"],
+ "status": module.params["sip_status"],
+ "strict-register": module.params["sip_strict_register"],
+ "subscribe-rate": module.params["sip_subscribe_rate"],
+ "unknown-header": module.params["sip_unknown_header"],
+ "update-rate": module.params["sip_update_rate"],
+ }
+ }
+
+ module.paramgram = paramgram
+ fmgr = None
+ if module._socket_path:
+ connection = Connection(module._socket_path)
+ fmgr = FortiManagerHandler(connection, module)
+ fmgr.tools = FMGRCommon()
+ else:
+ module.fail_json(**FAIL_SOCKET_MSG)
+
+ list_overrides = ['sccp', 'sip']
+ paramgram = fmgr.tools.paramgram_child_list_override(list_overrides=list_overrides,
+ paramgram=paramgram, module=module)
+ module.paramgram = paramgram
+
+ results = DEFAULT_RESULT_OBJ
+ try:
+
+ results = fmgr_voip_profile_modify(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ return module.exit_json(**results[1])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_waf.py b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_waf.py
new file mode 100644
index 00000000..6d7f4040
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_waf.py
@@ -0,0 +1,1477 @@
+#!/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: fmgr_secprof_waf
+notes:
+ - Full Documentation at U(https://ftnt-ansible-docs.readthedocs.io/en/latest/).
+author:
+ - Luke Weighall (@lweighall)
+ - Andrew Welsh (@Ghilli3)
+ - Jim Huber (@p4r4n0y1ng)
+short_description: FortiManager web application firewall security profile
+description:
+ - Manage web application firewall security profiles for FGTs via FMG
+
+options:
+ adom:
+ description:
+ - The ADOM the configuration should belong to.
+ required: false
+ default: root
+
+ mode:
+ description:
+ - Sets one of three modes for managing the object.
+ - Allows use of soft-adds instead of overwriting existing values
+ choices: ['add', 'set', 'delete', 'update']
+ required: false
+ default: add
+
+ name:
+ description:
+ - WAF Profile name.
+ required: false
+
+ external:
+ description:
+ - Disable/Enable external HTTP Inspection.
+ - choice | disable | Disable external inspection.
+ - choice | enable | Enable external inspection.
+ required: false
+ choices: ["disable", "enable"]
+
+ extended_log:
+ description:
+ - Enable/disable extended logging.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ comment:
+ description:
+ - Comment.
+ required: false
+
+ address_list:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ address_list_blocked_address:
+ description:
+ - Blocked address.
+ required: false
+
+ address_list_blocked_log:
+ description:
+ - Enable/disable logging on blocked addresses.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ address_list_severity:
+ description:
+ - Severity.
+ - choice | low | Low severity.
+ - choice | medium | Medium severity.
+ - choice | high | High severity.
+ required: false
+ choices: ["low", "medium", "high"]
+
+ address_list_status:
+ description:
+ - Status.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ address_list_trusted_address:
+ description:
+ - Trusted address.
+ required: false
+
+ constraint:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ constraint_content_length_action:
+ description:
+ - Action.
+ - choice | allow | Allow.
+ - choice | block | Block.
+ required: false
+ choices: ["allow", "block"]
+
+ constraint_content_length_length:
+ description:
+ - Length of HTTP content in bytes (0 to 2147483647).
+ required: false
+
+ constraint_content_length_log:
+ description:
+ - Enable/disable logging.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_content_length_severity:
+ description:
+ - Severity.
+ - choice | low | Low severity.
+ - choice | medium | Medium severity.
+ - choice | high | High severity.
+ required: false
+ choices: ["low", "medium", "high"]
+
+ constraint_content_length_status:
+ description:
+ - Enable/disable the constraint.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_exception_address:
+ description:
+ - Host address.
+ required: false
+
+ constraint_exception_content_length:
+ description:
+ - HTTP content length in request.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_exception_header_length:
+ description:
+ - HTTP header length in request.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_exception_hostname:
+ description:
+ - Enable/disable hostname check.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_exception_line_length:
+ description:
+ - HTTP line length in request.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_exception_malformed:
+ description:
+ - Enable/disable malformed HTTP request check.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_exception_max_cookie:
+ description:
+ - Maximum number of cookies in HTTP request.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_exception_max_header_line:
+ description:
+ - Maximum number of HTTP header line.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_exception_max_range_segment:
+ description:
+ - Maximum number of range segments in HTTP range line.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_exception_max_url_param:
+ description:
+ - Maximum number of parameters in URL.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_exception_method:
+ description:
+ - Enable/disable HTTP method check.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_exception_param_length:
+ description:
+ - Maximum length of parameter in URL, HTTP POST request or HTTP body.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_exception_pattern:
+ description:
+ - URL pattern.
+ required: false
+
+ constraint_exception_regex:
+ description:
+ - Enable/disable regular expression based pattern match.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_exception_url_param_length:
+ description:
+ - Maximum length of parameter in URL.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_exception_version:
+ description:
+ - Enable/disable HTTP version check.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_header_length_action:
+ description:
+ - Action.
+ - choice | allow | Allow.
+ - choice | block | Block.
+ required: false
+ choices: ["allow", "block"]
+
+ constraint_header_length_length:
+ description:
+ - Length of HTTP header in bytes (0 to 2147483647).
+ required: false
+
+ constraint_header_length_log:
+ description:
+ - Enable/disable logging.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_header_length_severity:
+ description:
+ - Severity.
+ - choice | low | Low severity.
+ - choice | medium | Medium severity.
+ - choice | high | High severity.
+ required: false
+ choices: ["low", "medium", "high"]
+
+ constraint_header_length_status:
+ description:
+ - Enable/disable the constraint.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_hostname_action:
+ description:
+ - Action for a hostname constraint.
+ - choice | allow | Allow.
+ - choice | block | Block.
+ required: false
+ choices: ["allow", "block"]
+
+ constraint_hostname_log:
+ description:
+ - Enable/disable logging.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_hostname_severity:
+ description:
+ - Severity.
+ - choice | low | Low severity.
+ - choice | medium | Medium severity.
+ - choice | high | High severity.
+ required: false
+ choices: ["low", "medium", "high"]
+
+ constraint_hostname_status:
+ description:
+ - Enable/disable the constraint.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_line_length_action:
+ description:
+ - Action.
+ - choice | allow | Allow.
+ - choice | block | Block.
+ required: false
+ choices: ["allow", "block"]
+
+ constraint_line_length_length:
+ description:
+ - Length of HTTP line in bytes (0 to 2147483647).
+ required: false
+
+ constraint_line_length_log:
+ description:
+ - Enable/disable logging.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_line_length_severity:
+ description:
+ - Severity.
+ - choice | low | Low severity.
+ - choice | medium | Medium severity.
+ - choice | high | High severity.
+ required: false
+ choices: ["low", "medium", "high"]
+
+ constraint_line_length_status:
+ description:
+ - Enable/disable the constraint.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_malformed_action:
+ description:
+ - Action.
+ - choice | allow | Allow.
+ - choice | block | Block.
+ required: false
+ choices: ["allow", "block"]
+
+ constraint_malformed_log:
+ description:
+ - Enable/disable logging.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_malformed_severity:
+ description:
+ - Severity.
+ - choice | low | Low severity.
+ - choice | medium | Medium severity.
+ - choice | high | High severity.
+ required: false
+ choices: ["low", "medium", "high"]
+
+ constraint_malformed_status:
+ description:
+ - Enable/disable the constraint.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_max_cookie_action:
+ description:
+ - Action.
+ - choice | allow | Allow.
+ - choice | block | Block.
+ required: false
+ choices: ["allow", "block"]
+
+ constraint_max_cookie_log:
+ description:
+ - Enable/disable logging.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_max_cookie_max_cookie:
+ description:
+ - Maximum number of cookies in HTTP request (0 to 2147483647).
+ required: false
+
+ constraint_max_cookie_severity:
+ description:
+ - Severity.
+ - choice | low | Low severity.
+ - choice | medium | Medium severity.
+ - choice | high | High severity.
+ required: false
+ choices: ["low", "medium", "high"]
+
+ constraint_max_cookie_status:
+ description:
+ - Enable/disable the constraint.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_max_header_line_action:
+ description:
+ - Action.
+ - choice | allow | Allow.
+ - choice | block | Block.
+ required: false
+ choices: ["allow", "block"]
+
+ constraint_max_header_line_log:
+ description:
+ - Enable/disable logging.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_max_header_line_max_header_line:
+ description:
+ - Maximum number HTTP header lines (0 to 2147483647).
+ required: false
+
+ constraint_max_header_line_severity:
+ description:
+ - Severity.
+ - choice | low | Low severity.
+ - choice | medium | Medium severity.
+ - choice | high | High severity.
+ required: false
+ choices: ["low", "medium", "high"]
+
+ constraint_max_header_line_status:
+ description:
+ - Enable/disable the constraint.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_max_range_segment_action:
+ description:
+ - Action.
+ - choice | allow | Allow.
+ - choice | block | Block.
+ required: false
+ choices: ["allow", "block"]
+
+ constraint_max_range_segment_log:
+ description:
+ - Enable/disable logging.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_max_range_segment_max_range_segment:
+ description:
+ - Maximum number of range segments in HTTP range line (0 to 2147483647).
+ required: false
+
+ constraint_max_range_segment_severity:
+ description:
+ - Severity.
+ - choice | low | Low severity.
+ - choice | medium | Medium severity.
+ - choice | high | High severity.
+ required: false
+ choices: ["low", "medium", "high"]
+
+ constraint_max_range_segment_status:
+ description:
+ - Enable/disable the constraint.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_max_url_param_action:
+ description:
+ - Action.
+ - choice | allow | Allow.
+ - choice | block | Block.
+ required: false
+ choices: ["allow", "block"]
+
+ constraint_max_url_param_log:
+ description:
+ - Enable/disable logging.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_max_url_param_max_url_param:
+ description:
+ - Maximum number of parameters in URL (0 to 2147483647).
+ required: false
+
+ constraint_max_url_param_severity:
+ description:
+ - Severity.
+ - choice | low | Low severity.
+ - choice | medium | Medium severity.
+ - choice | high | High severity.
+ required: false
+ choices: ["low", "medium", "high"]
+
+ constraint_max_url_param_status:
+ description:
+ - Enable/disable the constraint.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_method_action:
+ description:
+ - Action.
+ - choice | allow | Allow.
+ - choice | block | Block.
+ required: false
+ choices: ["allow", "block"]
+
+ constraint_method_log:
+ description:
+ - Enable/disable logging.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_method_severity:
+ description:
+ - Severity.
+ - choice | low | Low severity.
+ - choice | medium | Medium severity.
+ - choice | high | High severity.
+ required: false
+ choices: ["low", "medium", "high"]
+
+ constraint_method_status:
+ description:
+ - Enable/disable the constraint.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_param_length_action:
+ description:
+ - Action.
+ - choice | allow | Allow.
+ - choice | block | Block.
+ required: false
+ choices: ["allow", "block"]
+
+ constraint_param_length_length:
+ description:
+ - Maximum length of parameter in URL, HTTP POST request or HTTP body in bytes (0 to 2147483647).
+ required: false
+
+ constraint_param_length_log:
+ description:
+ - Enable/disable logging.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_param_length_severity:
+ description:
+ - Severity.
+ - choice | low | Low severity.
+ - choice | medium | Medium severity.
+ - choice | high | High severity.
+ required: false
+ choices: ["low", "medium", "high"]
+
+ constraint_param_length_status:
+ description:
+ - Enable/disable the constraint.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_url_param_length_action:
+ description:
+ - Action.
+ - choice | allow | Allow.
+ - choice | block | Block.
+ required: false
+ choices: ["allow", "block"]
+
+ constraint_url_param_length_length:
+ description:
+ - Maximum length of URL parameter in bytes (0 to 2147483647).
+ required: false
+
+ constraint_url_param_length_log:
+ description:
+ - Enable/disable logging.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_url_param_length_severity:
+ description:
+ - Severity.
+ - choice | low | Low severity.
+ - choice | medium | Medium severity.
+ - choice | high | High severity.
+ required: false
+ choices: ["low", "medium", "high"]
+
+ constraint_url_param_length_status:
+ description:
+ - Enable/disable the constraint.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_version_action:
+ description:
+ - Action.
+ - choice | allow | Allow.
+ - choice | block | Block.
+ required: false
+ choices: ["allow", "block"]
+
+ constraint_version_log:
+ description:
+ - Enable/disable logging.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ constraint_version_severity:
+ description:
+ - Severity.
+ - choice | low | Low severity.
+ - choice | medium | Medium severity.
+ - choice | high | High severity.
+ required: false
+ choices: ["low", "medium", "high"]
+
+ constraint_version_status:
+ description:
+ - Enable/disable the constraint.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ method:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ method_default_allowed_methods:
+ description:
+ - Methods.
+ - FLAG Based Options. Specify multiple in list form.
+ - flag | delete | HTTP DELETE method.
+ - flag | get | HTTP GET method.
+ - flag | head | HTTP HEAD method.
+ - flag | options | HTTP OPTIONS method.
+ - flag | post | HTTP POST method.
+ - flag | put | HTTP PUT method.
+ - flag | trace | HTTP TRACE method.
+ - flag | others | Other HTTP methods.
+ - flag | connect | HTTP CONNECT method.
+ required: false
+ choices: ["delete", "get", "head", "options", "post", "put", "trace", "others", "connect"]
+
+ method_log:
+ description:
+ - Enable/disable logging.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ method_severity:
+ description:
+ - Severity.
+ - choice | low | low severity
+ - choice | medium | medium severity
+ - choice | high | High severity
+ required: false
+ choices: ["low", "medium", "high"]
+
+ method_status:
+ description:
+ - Status.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ method_method_policy_address:
+ description:
+ - Host address.
+ required: false
+
+ method_method_policy_allowed_methods:
+ description:
+ - Allowed Methods.
+ - FLAG Based Options. Specify multiple in list form.
+ - flag | delete | HTTP DELETE method.
+ - flag | get | HTTP GET method.
+ - flag | head | HTTP HEAD method.
+ - flag | options | HTTP OPTIONS method.
+ - flag | post | HTTP POST method.
+ - flag | put | HTTP PUT method.
+ - flag | trace | HTTP TRACE method.
+ - flag | others | Other HTTP methods.
+ - flag | connect | HTTP CONNECT method.
+ required: false
+ choices: ["delete", "get", "head", "options", "post", "put", "trace", "others", "connect"]
+
+ method_method_policy_pattern:
+ description:
+ - URL pattern.
+ required: false
+
+ method_method_policy_regex:
+ description:
+ - Enable/disable regular expression based pattern match.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ signature:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ signature_credit_card_detection_threshold:
+ description:
+ - The minimum number of Credit cards to detect violation.
+ required: false
+
+ signature_disabled_signature:
+ description:
+ - Disabled signatures
+ required: false
+
+ signature_disabled_sub_class:
+ description:
+ - Disabled signature subclasses.
+ required: false
+
+ signature_custom_signature_action:
+ description:
+ - Action.
+ - choice | allow | Allow.
+ - choice | block | Block.
+ - choice | erase | Erase credit card numbers.
+ required: false
+ choices: ["allow", "block", "erase"]
+
+ signature_custom_signature_case_sensitivity:
+ description:
+ - Case sensitivity in pattern.
+ - choice | disable | Case insensitive in pattern.
+ - choice | enable | Case sensitive in pattern.
+ required: false
+ choices: ["disable", "enable"]
+
+ signature_custom_signature_direction:
+ description:
+ - Traffic direction.
+ - choice | request | Match HTTP request.
+ - choice | response | Match HTTP response.
+ required: false
+ choices: ["request", "response"]
+
+ signature_custom_signature_log:
+ description:
+ - Enable/disable logging.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ signature_custom_signature_name:
+ description:
+ - Signature name.
+ required: false
+
+ signature_custom_signature_pattern:
+ description:
+ - Match pattern.
+ required: false
+
+ signature_custom_signature_severity:
+ description:
+ - Severity.
+ - choice | low | Low severity.
+ - choice | medium | Medium severity.
+ - choice | high | High severity.
+ required: false
+ choices: ["low", "medium", "high"]
+
+ signature_custom_signature_status:
+ description:
+ - Status.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ signature_custom_signature_target:
+ description:
+ - Match HTTP target.
+ - FLAG Based Options. Specify multiple in list form.
+ - flag | arg | HTTP arguments.
+ - flag | arg-name | Names of HTTP arguments.
+ - flag | req-body | HTTP request body.
+ - flag | req-cookie | HTTP request cookies.
+ - flag | req-cookie-name | HTTP request cookie names.
+ - flag | req-filename | HTTP request file name.
+ - flag | req-header | HTTP request headers.
+ - flag | req-header-name | HTTP request header names.
+ - flag | req-raw-uri | Raw URI of HTTP request.
+ - flag | req-uri | URI of HTTP request.
+ - flag | resp-body | HTTP response body.
+ - flag | resp-hdr | HTTP response headers.
+ - flag | resp-status | HTTP response status.
+ required: false
+ choices: ["arg","arg-name","req-body","req-cookie","req-cookie-name","req-filename","req-header","req-header-name",
+ "req-raw-uri","req-uri","resp-body","resp-hdr","resp-status"]
+
+ signature_main_class_action:
+ description:
+ - Action.
+ - choice | allow | Allow.
+ - choice | block | Block.
+ - choice | erase | Erase credit card numbers.
+ required: false
+ choices: ["allow", "block", "erase"]
+
+ signature_main_class_log:
+ description:
+ - Enable/disable logging.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ signature_main_class_severity:
+ description:
+ - Severity.
+ - choice | low | Low severity.
+ - choice | medium | Medium severity.
+ - choice | high | High severity.
+ required: false
+ choices: ["low", "medium", "high"]
+
+ signature_main_class_status:
+ description:
+ - Status.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ url_access:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ url_access_action:
+ description:
+ - Action.
+ - choice | bypass | Allow the HTTP request, also bypass further WAF scanning.
+ - choice | permit | Allow the HTTP request, and continue further WAF scanning.
+ - choice | block | Block HTTP request.
+ required: false
+ choices: ["bypass", "permit", "block"]
+
+ url_access_address:
+ description:
+ - Host address.
+ required: false
+
+ url_access_log:
+ description:
+ - Enable/disable logging.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ url_access_severity:
+ description:
+ - Severity.
+ - choice | low | Low severity.
+ - choice | medium | Medium severity.
+ - choice | high | High severity.
+ required: false
+ choices: ["low", "medium", "high"]
+
+ url_access_access_pattern_negate:
+ description:
+ - Enable/disable match negation.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ url_access_access_pattern_pattern:
+ description:
+ - URL pattern.
+ required: false
+
+ url_access_access_pattern_regex:
+ description:
+ - Enable/disable regular expression based pattern match.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ url_access_access_pattern_srcaddr:
+ description:
+ - Source address.
+ required: false
+
+'''
+
+EXAMPLES = '''
+ - name: DELETE Profile
+ community.fortios.fmgr_secprof_waf:
+ name: "Ansible_WAF_Profile"
+ comment: "Created by Ansible Module TEST"
+ mode: "delete"
+
+ - name: CREATE Profile
+ community.fortios.fmgr_secprof_waf:
+ name: "Ansible_WAF_Profile"
+ comment: "Created by Ansible Module TEST"
+ mode: "set"
+'''
+
+RETURN = """
+api_result:
+ description: full API response, includes status code and message
+ returned: always
+ type: str
+"""
+
+from ansible.module_utils.basic import AnsibleModule, env_fallback
+from ansible.module_utils.connection import Connection
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.fortimanager import FortiManagerHandler
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGBaseException
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRCommon
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRMethods
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import DEFAULT_RESULT_OBJ
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FAIL_SOCKET_MSG
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import prepare_dict
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import scrub_dict
+
+
+###############
+# START METHODS
+###############
+
+
+def fmgr_waf_profile_modify(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+ mode = paramgram["mode"]
+ adom = paramgram["adom"]
+ # INIT A BASIC OBJECTS
+ response = DEFAULT_RESULT_OBJ
+ url = ""
+ datagram = {}
+
+ # EVAL THE MODE PARAMETER FOR SET OR ADD
+ if mode in ['set', 'add', 'update']:
+ url = '/pm/config/adom/{adom}/obj/waf/profile'.format(adom=adom)
+ datagram = scrub_dict(prepare_dict(paramgram))
+
+ # EVAL THE MODE PARAMETER FOR DELETE
+ elif mode == "delete":
+ # SET THE CORRECT URL FOR DELETE
+ url = '/pm/config/adom/{adom}/obj/waf/profile/{name}'.format(adom=adom, name=paramgram["name"])
+ datagram = {}
+
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+
+ return response
+
+
+#############
+# END METHODS
+#############
+
+
+def main():
+ argument_spec = dict(
+ adom=dict(type="str", default="root"),
+ mode=dict(choices=["add", "set", "delete", "update"], type="str", default="add"),
+
+ name=dict(required=False, type="str"),
+ external=dict(required=False, type="str", choices=["disable", "enable"]),
+ extended_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ comment=dict(required=False, type="str"),
+ address_list=dict(required=False, type="list"),
+ address_list_blocked_address=dict(required=False, type="str"),
+ address_list_blocked_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ address_list_severity=dict(required=False, type="str", choices=["low", "medium", "high"]),
+ address_list_status=dict(required=False, type="str", choices=["disable", "enable"]),
+ address_list_trusted_address=dict(required=False, type="str"),
+ constraint=dict(required=False, type="list"),
+
+ constraint_content_length_action=dict(required=False, type="str", choices=["allow", "block"]),
+ constraint_content_length_length=dict(required=False, type="int"),
+ constraint_content_length_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ constraint_content_length_severity=dict(required=False, type="str", choices=["low", "medium", "high"]),
+ constraint_content_length_status=dict(required=False, type="str", choices=["disable", "enable"]),
+
+ constraint_exception_address=dict(required=False, type="str"),
+ constraint_exception_content_length=dict(required=False, type="str", choices=["disable", "enable"]),
+ constraint_exception_header_length=dict(required=False, type="str", choices=["disable", "enable"]),
+ constraint_exception_hostname=dict(required=False, type="str", choices=["disable", "enable"]),
+ constraint_exception_line_length=dict(required=False, type="str", choices=["disable", "enable"]),
+ constraint_exception_malformed=dict(required=False, type="str", choices=["disable", "enable"]),
+ constraint_exception_max_cookie=dict(required=False, type="str", choices=["disable", "enable"]),
+ constraint_exception_max_header_line=dict(required=False, type="str", choices=["disable", "enable"]),
+ constraint_exception_max_range_segment=dict(required=False, type="str", choices=["disable", "enable"]),
+ constraint_exception_max_url_param=dict(required=False, type="str", choices=["disable", "enable"]),
+ constraint_exception_method=dict(required=False, type="str", choices=["disable", "enable"]),
+ constraint_exception_param_length=dict(required=False, type="str", choices=["disable", "enable"]),
+ constraint_exception_pattern=dict(required=False, type="str"),
+ constraint_exception_regex=dict(required=False, type="str", choices=["disable", "enable"]),
+ constraint_exception_url_param_length=dict(required=False, type="str", choices=["disable", "enable"]),
+ constraint_exception_version=dict(required=False, type="str", choices=["disable", "enable"]),
+
+ constraint_header_length_action=dict(required=False, type="str", choices=["allow", "block"]),
+ constraint_header_length_length=dict(required=False, type="int"),
+ constraint_header_length_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ constraint_header_length_severity=dict(required=False, type="str", choices=["low", "medium", "high"]),
+ constraint_header_length_status=dict(required=False, type="str", choices=["disable", "enable"]),
+
+ constraint_hostname_action=dict(required=False, type="str", choices=["allow", "block"]),
+ constraint_hostname_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ constraint_hostname_severity=dict(required=False, type="str", choices=["low", "medium", "high"]),
+ constraint_hostname_status=dict(required=False, type="str", choices=["disable", "enable"]),
+
+ constraint_line_length_action=dict(required=False, type="str", choices=["allow", "block"]),
+ constraint_line_length_length=dict(required=False, type="int"),
+ constraint_line_length_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ constraint_line_length_severity=dict(required=False, type="str", choices=["low", "medium", "high"]),
+ constraint_line_length_status=dict(required=False, type="str", choices=["disable", "enable"]),
+
+ constraint_malformed_action=dict(required=False, type="str", choices=["allow", "block"]),
+ constraint_malformed_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ constraint_malformed_severity=dict(required=False, type="str", choices=["low", "medium", "high"]),
+ constraint_malformed_status=dict(required=False, type="str", choices=["disable", "enable"]),
+
+ constraint_max_cookie_action=dict(required=False, type="str", choices=["allow", "block"]),
+ constraint_max_cookie_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ constraint_max_cookie_max_cookie=dict(required=False, type="int"),
+ constraint_max_cookie_severity=dict(required=False, type="str", choices=["low", "medium", "high"]),
+ constraint_max_cookie_status=dict(required=False, type="str", choices=["disable", "enable"]),
+
+ constraint_max_header_line_action=dict(required=False, type="str", choices=["allow", "block"]),
+ constraint_max_header_line_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ constraint_max_header_line_max_header_line=dict(required=False, type="int"),
+ constraint_max_header_line_severity=dict(required=False, type="str", choices=["low", "medium", "high"]),
+ constraint_max_header_line_status=dict(required=False, type="str", choices=["disable", "enable"]),
+
+ constraint_max_range_segment_action=dict(required=False, type="str", choices=["allow", "block"]),
+ constraint_max_range_segment_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ constraint_max_range_segment_max_range_segment=dict(required=False, type="int"),
+ constraint_max_range_segment_severity=dict(required=False, type="str", choices=["low", "medium", "high"]),
+ constraint_max_range_segment_status=dict(required=False, type="str", choices=["disable", "enable"]),
+
+ constraint_max_url_param_action=dict(required=False, type="str", choices=["allow", "block"]),
+ constraint_max_url_param_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ constraint_max_url_param_max_url_param=dict(required=False, type="int"),
+ constraint_max_url_param_severity=dict(required=False, type="str", choices=["low", "medium", "high"]),
+ constraint_max_url_param_status=dict(required=False, type="str", choices=["disable", "enable"]),
+
+ constraint_method_action=dict(required=False, type="str", choices=["allow", "block"]),
+ constraint_method_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ constraint_method_severity=dict(required=False, type="str", choices=["low", "medium", "high"]),
+ constraint_method_status=dict(required=False, type="str", choices=["disable", "enable"]),
+
+ constraint_param_length_action=dict(required=False, type="str", choices=["allow", "block"]),
+ constraint_param_length_length=dict(required=False, type="int"),
+ constraint_param_length_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ constraint_param_length_severity=dict(required=False, type="str", choices=["low", "medium", "high"]),
+ constraint_param_length_status=dict(required=False, type="str", choices=["disable", "enable"]),
+
+ constraint_url_param_length_action=dict(required=False, type="str", choices=["allow", "block"]),
+ constraint_url_param_length_length=dict(required=False, type="int"),
+ constraint_url_param_length_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ constraint_url_param_length_severity=dict(required=False, type="str", choices=["low", "medium", "high"]),
+ constraint_url_param_length_status=dict(required=False, type="str", choices=["disable", "enable"]),
+
+ constraint_version_action=dict(required=False, type="str", choices=["allow", "block"]),
+ constraint_version_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ constraint_version_severity=dict(required=False, type="str", choices=["low", "medium", "high"]),
+ constraint_version_status=dict(required=False, type="str", choices=["disable", "enable"]),
+ method=dict(required=False, type="list"),
+ method_default_allowed_methods=dict(required=False, type="str", choices=["delete",
+ "get",
+ "head",
+ "options",
+ "post",
+ "put",
+ "trace",
+ "others",
+ "connect"]),
+ method_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ method_severity=dict(required=False, type="str", choices=["low", "medium", "high"]),
+ method_status=dict(required=False, type="str", choices=["disable", "enable"]),
+
+ method_method_policy_address=dict(required=False, type="str"),
+ method_method_policy_allowed_methods=dict(required=False, type="str", choices=["delete",
+ "get",
+ "head",
+ "options",
+ "post",
+ "put",
+ "trace",
+ "others",
+ "connect"]),
+ method_method_policy_pattern=dict(required=False, type="str"),
+ method_method_policy_regex=dict(required=False, type="str", choices=["disable", "enable"]),
+ signature=dict(required=False, type="list"),
+ signature_credit_card_detection_threshold=dict(required=False, type="int"),
+ signature_disabled_signature=dict(required=False, type="str"),
+ signature_disabled_sub_class=dict(required=False, type="str"),
+
+ signature_custom_signature_action=dict(required=False, type="str", choices=["allow", "block", "erase"]),
+ signature_custom_signature_case_sensitivity=dict(required=False, type="str", choices=["disable", "enable"]),
+ signature_custom_signature_direction=dict(required=False, type="str", choices=["request", "response"]),
+ signature_custom_signature_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ signature_custom_signature_name=dict(required=False, type="str"),
+ signature_custom_signature_pattern=dict(required=False, type="str"),
+ signature_custom_signature_severity=dict(required=False, type="str", choices=["low", "medium", "high"]),
+ signature_custom_signature_status=dict(required=False, type="str", choices=["disable", "enable"]),
+ signature_custom_signature_target=dict(required=False, type="str", choices=["arg",
+ "arg-name",
+ "req-body",
+ "req-cookie",
+ "req-cookie-name",
+ "req-filename",
+ "req-header",
+ "req-header-name",
+ "req-raw-uri",
+ "req-uri",
+ "resp-body",
+ "resp-hdr",
+ "resp-status"]),
+
+ signature_main_class_action=dict(required=False, type="str", choices=["allow", "block", "erase"]),
+ signature_main_class_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ signature_main_class_severity=dict(required=False, type="str", choices=["low", "medium", "high"]),
+ signature_main_class_status=dict(required=False, type="str", choices=["disable", "enable"]),
+ url_access=dict(required=False, type="list"),
+ url_access_action=dict(required=False, type="str", choices=["bypass", "permit", "block"]),
+ url_access_address=dict(required=False, type="str"),
+ url_access_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ url_access_severity=dict(required=False, type="str", choices=["low", "medium", "high"]),
+
+ url_access_access_pattern_negate=dict(required=False, type="str", choices=["disable", "enable"]),
+ url_access_access_pattern_pattern=dict(required=False, type="str"),
+ url_access_access_pattern_regex=dict(required=False, type="str", choices=["disable", "enable"]),
+ url_access_access_pattern_srcaddr=dict(required=False, type="str"),
+
+ )
+
+ module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False, )
+ # MODULE PARAMGRAM
+ paramgram = {
+ "mode": module.params["mode"],
+ "adom": module.params["adom"],
+ "name": module.params["name"],
+ "external": module.params["external"],
+ "extended-log": module.params["extended_log"],
+ "comment": module.params["comment"],
+ "address-list": {
+ "blocked-address": module.params["address_list_blocked_address"],
+ "blocked-log": module.params["address_list_blocked_log"],
+ "severity": module.params["address_list_severity"],
+ "status": module.params["address_list_status"],
+ "trusted-address": module.params["address_list_trusted_address"],
+ },
+ "constraint": {
+ "content-length": {
+ "action": module.params["constraint_content_length_action"],
+ "length": module.params["constraint_content_length_length"],
+ "log": module.params["constraint_content_length_log"],
+ "severity": module.params["constraint_content_length_severity"],
+ "status": module.params["constraint_content_length_status"],
+ },
+ "exception": {
+ "address": module.params["constraint_exception_address"],
+ "content-length": module.params["constraint_exception_content_length"],
+ "header-length": module.params["constraint_exception_header_length"],
+ "hostname": module.params["constraint_exception_hostname"],
+ "line-length": module.params["constraint_exception_line_length"],
+ "malformed": module.params["constraint_exception_malformed"],
+ "max-cookie": module.params["constraint_exception_max_cookie"],
+ "max-header-line": module.params["constraint_exception_max_header_line"],
+ "max-range-segment": module.params["constraint_exception_max_range_segment"],
+ "max-url-param": module.params["constraint_exception_max_url_param"],
+ "method": module.params["constraint_exception_method"],
+ "param-length": module.params["constraint_exception_param_length"],
+ "pattern": module.params["constraint_exception_pattern"],
+ "regex": module.params["constraint_exception_regex"],
+ "url-param-length": module.params["constraint_exception_url_param_length"],
+ "version": module.params["constraint_exception_version"],
+ },
+ "header-length": {
+ "action": module.params["constraint_header_length_action"],
+ "length": module.params["constraint_header_length_length"],
+ "log": module.params["constraint_header_length_log"],
+ "severity": module.params["constraint_header_length_severity"],
+ "status": module.params["constraint_header_length_status"],
+ },
+ "hostname": {
+ "action": module.params["constraint_hostname_action"],
+ "log": module.params["constraint_hostname_log"],
+ "severity": module.params["constraint_hostname_severity"],
+ "status": module.params["constraint_hostname_status"],
+ },
+ "line-length": {
+ "action": module.params["constraint_line_length_action"],
+ "length": module.params["constraint_line_length_length"],
+ "log": module.params["constraint_line_length_log"],
+ "severity": module.params["constraint_line_length_severity"],
+ "status": module.params["constraint_line_length_status"],
+ },
+ "malformed": {
+ "action": module.params["constraint_malformed_action"],
+ "log": module.params["constraint_malformed_log"],
+ "severity": module.params["constraint_malformed_severity"],
+ "status": module.params["constraint_malformed_status"],
+ },
+ "max-cookie": {
+ "action": module.params["constraint_max_cookie_action"],
+ "log": module.params["constraint_max_cookie_log"],
+ "max-cookie": module.params["constraint_max_cookie_max_cookie"],
+ "severity": module.params["constraint_max_cookie_severity"],
+ "status": module.params["constraint_max_cookie_status"],
+ },
+ "max-header-line": {
+ "action": module.params["constraint_max_header_line_action"],
+ "log": module.params["constraint_max_header_line_log"],
+ "max-header-line": module.params["constraint_max_header_line_max_header_line"],
+ "severity": module.params["constraint_max_header_line_severity"],
+ "status": module.params["constraint_max_header_line_status"],
+ },
+ "max-range-segment": {
+ "action": module.params["constraint_max_range_segment_action"],
+ "log": module.params["constraint_max_range_segment_log"],
+ "max-range-segment": module.params["constraint_max_range_segment_max_range_segment"],
+ "severity": module.params["constraint_max_range_segment_severity"],
+ "status": module.params["constraint_max_range_segment_status"],
+ },
+ "max-url-param": {
+ "action": module.params["constraint_max_url_param_action"],
+ "log": module.params["constraint_max_url_param_log"],
+ "max-url-param": module.params["constraint_max_url_param_max_url_param"],
+ "severity": module.params["constraint_max_url_param_severity"],
+ "status": module.params["constraint_max_url_param_status"],
+ },
+ "method": {
+ "action": module.params["constraint_method_action"],
+ "log": module.params["constraint_method_log"],
+ "severity": module.params["constraint_method_severity"],
+ "status": module.params["constraint_method_status"],
+ },
+ "param-length": {
+ "action": module.params["constraint_param_length_action"],
+ "length": module.params["constraint_param_length_length"],
+ "log": module.params["constraint_param_length_log"],
+ "severity": module.params["constraint_param_length_severity"],
+ "status": module.params["constraint_param_length_status"],
+ },
+ "url-param-length": {
+ "action": module.params["constraint_url_param_length_action"],
+ "length": module.params["constraint_url_param_length_length"],
+ "log": module.params["constraint_url_param_length_log"],
+ "severity": module.params["constraint_url_param_length_severity"],
+ "status": module.params["constraint_url_param_length_status"],
+ },
+ "version": {
+ "action": module.params["constraint_version_action"],
+ "log": module.params["constraint_version_log"],
+ "severity": module.params["constraint_version_severity"],
+ "status": module.params["constraint_version_status"],
+ },
+ },
+ "method": {
+ "default-allowed-methods": module.params["method_default_allowed_methods"],
+ "log": module.params["method_log"],
+ "severity": module.params["method_severity"],
+ "status": module.params["method_status"],
+ "method-policy": {
+ "address": module.params["method_method_policy_address"],
+ "allowed-methods": module.params["method_method_policy_allowed_methods"],
+ "pattern": module.params["method_method_policy_pattern"],
+ "regex": module.params["method_method_policy_regex"],
+ },
+ },
+ "signature": {
+ "credit-card-detection-threshold": module.params["signature_credit_card_detection_threshold"],
+ "disabled-signature": module.params["signature_disabled_signature"],
+ "disabled-sub-class": module.params["signature_disabled_sub_class"],
+ "custom-signature": {
+ "action": module.params["signature_custom_signature_action"],
+ "case-sensitivity": module.params["signature_custom_signature_case_sensitivity"],
+ "direction": module.params["signature_custom_signature_direction"],
+ "log": module.params["signature_custom_signature_log"],
+ "name": module.params["signature_custom_signature_name"],
+ "pattern": module.params["signature_custom_signature_pattern"],
+ "severity": module.params["signature_custom_signature_severity"],
+ "status": module.params["signature_custom_signature_status"],
+ "target": module.params["signature_custom_signature_target"],
+ },
+ "main-class": {
+ "action": module.params["signature_main_class_action"],
+ "log": module.params["signature_main_class_log"],
+ "severity": module.params["signature_main_class_severity"],
+ "status": module.params["signature_main_class_status"],
+ },
+ },
+ "url-access": {
+ "action": module.params["url_access_action"],
+ "address": module.params["url_access_address"],
+ "log": module.params["url_access_log"],
+ "severity": module.params["url_access_severity"],
+ "access-pattern": {
+ "negate": module.params["url_access_access_pattern_negate"],
+ "pattern": module.params["url_access_access_pattern_pattern"],
+ "regex": module.params["url_access_access_pattern_regex"],
+ "srcaddr": module.params["url_access_access_pattern_srcaddr"],
+ }
+ }
+ }
+
+ module.paramgram = paramgram
+ fmgr = None
+ if module._socket_path:
+ connection = Connection(module._socket_path)
+ fmgr = FortiManagerHandler(connection, module)
+ fmgr.tools = FMGRCommon()
+ else:
+ module.fail_json(**FAIL_SOCKET_MSG)
+
+ list_overrides = ['address-list', 'constraint', 'method', 'signature', 'url-access']
+ paramgram = fmgr.tools.paramgram_child_list_override(list_overrides=list_overrides,
+ paramgram=paramgram, module=module)
+
+ results = DEFAULT_RESULT_OBJ
+
+ try:
+ results = fmgr_waf_profile_modify(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ return module.exit_json(**results[1])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_wanopt.py b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_wanopt.py
new file mode 100644
index 00000000..68f0962b
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_wanopt.py
@@ -0,0 +1,685 @@
+#!/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: fmgr_secprof_wanopt
+notes:
+ - Full Documentation at U(https://ftnt-ansible-docs.readthedocs.io/en/latest/).
+author:
+ - Luke Weighall (@lweighall)
+ - Andrew Welsh (@Ghilli3)
+ - Jim Huber (@p4r4n0y1ng)
+short_description: WAN optimization
+description:
+ - Manage WanOpt security profiles in FortiManager via API
+
+options:
+ adom:
+ description:
+ - The ADOM the configuration should belong to.
+ required: false
+ default: root
+
+ mode:
+ description:
+ - Sets one of three modes for managing the object.
+ - Allows use of soft-adds instead of overwriting existing values
+ choices: ['add', 'set', 'delete', 'update']
+ required: false
+ default: add
+
+ transparent:
+ description:
+ - Enable/disable transparent mode.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ name:
+ description:
+ - Profile name.
+ required: false
+
+ comments:
+ description:
+ - Comment.
+ required: false
+
+ auth_group:
+ description:
+ - Optionally add an authentication group to restrict access to the WAN Optimization tunnel to
+ peers in the authentication group.
+ required: false
+
+ cifs:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ cifs_byte_caching:
+ description:
+ - Enable/disable byte-caching for HTTP. Byte caching reduces the amount of traffic by caching
+ file data sent across the WAN and in future serving if from the cache.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ cifs_log_traffic:
+ description:
+ - Enable/disable logging.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ cifs_port:
+ description:
+ - Single port number or port number range for CIFS. Only packets with a destination port number
+ that matches this port number or range are accepted by this profile.
+ required: false
+
+ cifs_prefer_chunking:
+ description:
+ - Select dynamic or fixed-size data chunking for HTTP WAN Optimization.
+ required: false
+ choices:
+ - dynamic
+ - fix
+
+ cifs_secure_tunnel:
+ description:
+ - Enable/disable securing the WAN Opt tunnel using SSL. Secure and non-secure tunnels use the
+ same TCP port (7810).
+ required: false
+ choices:
+ - disable
+ - enable
+
+ cifs_status:
+ description:
+ - Enable/disable HTTP WAN Optimization.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ cifs_tunnel_sharing:
+ description:
+ - Tunnel sharing mode for aggressive/non-aggressive and/or interactive/non-interactive protocols.
+ required: false
+ choices:
+ - private
+ - shared
+ - express-shared
+
+ ftp:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ ftp_byte_caching:
+ description:
+ - Enable/disable byte-caching for HTTP. Byte caching reduces the amount of traffic by caching
+ file data sent across the WAN and in future serving if from the cache.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ ftp_log_traffic:
+ description:
+ - Enable/disable logging.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ ftp_port:
+ description:
+ - Single port number or port number range for FTP. Only packets with a destination port number
+ that matches this port number or range are accepted by this profile.
+ required: false
+
+ ftp_prefer_chunking:
+ description:
+ - Select dynamic or fixed-size data chunking for HTTP WAN Optimization.
+ required: false
+ choices:
+ - dynamic
+ - fix
+
+ ftp_secure_tunnel:
+ description:
+ - Enable/disable securing the WAN Opt tunnel using SSL. Secure and non-secure tunnels use the
+ same TCP port (7810).
+ required: false
+ choices:
+ - disable
+ - enable
+
+ ftp_status:
+ description:
+ - Enable/disable HTTP WAN Optimization.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ ftp_tunnel_sharing:
+ description:
+ - Tunnel sharing mode for aggressive/non-aggressive and/or interactive/non-interactive protocols.
+ required: false
+ choices:
+ - private
+ - shared
+ - express-shared
+
+ http:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ http_byte_caching:
+ description:
+ - Enable/disable byte-caching for HTTP. Byte caching reduces the amount of traffic by caching
+ file data sent across the WAN and in future serving if from the cache.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ http_log_traffic:
+ description:
+ - Enable/disable logging.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ http_port:
+ description:
+ - Single port number or port number range for HTTP. Only packets with a destination port number
+ that matches this port number or range are accepted by this profile.
+ required: false
+
+ http_prefer_chunking:
+ description:
+ - Select dynamic or fixed-size data chunking for HTTP WAN Optimization.
+ required: false
+ choices:
+ - dynamic
+ - fix
+
+ http_secure_tunnel:
+ description:
+ - Enable/disable securing the WAN Opt tunnel using SSL. Secure and non-secure tunnels use the
+ same TCP port (7810).
+ required: false
+ choices:
+ - disable
+ - enable
+
+ http_ssl:
+ description:
+ - Enable/disable SSL/TLS offloading (hardware acceleration) for HTTPS traffic in this tunnel.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ http_ssl_port:
+ description:
+ - Port on which to expect HTTPS traffic for SSL/TLS offloading.
+ required: false
+
+ http_status:
+ description:
+ - Enable/disable HTTP WAN Optimization.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ http_tunnel_non_http:
+ description:
+ - Configure how to process non-HTTP traffic when a profile configured for HTTP traffic accepts
+ a non-HTTP session. Can occur if an application sends non-HTTP traffic using an HTTP destination port.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ http_tunnel_sharing:
+ description:
+ - Tunnel sharing mode for aggressive/non-aggressive and/or interactive/non-interactive protocols.
+ required: false
+ choices:
+ - private
+ - shared
+ - express-shared
+
+ http_unknown_http_version:
+ description:
+ - How to handle HTTP sessions that do not comply with HTTP 0.9, 1.0, or 1.1.
+ required: false
+ choices:
+ - best-effort
+ - reject
+ - tunnel
+
+ mapi:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ mapi_byte_caching:
+ description:
+ - Enable/disable byte-caching for HTTP. Byte caching reduces the amount of traffic by caching
+ file data sent across the WAN and in future serving if from the cache.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ mapi_log_traffic:
+ description:
+ - Enable/disable logging.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ mapi_port:
+ description:
+ - Single port number or port number range for MAPI. Only packets with a destination port number
+ that matches this port number or range are accepted by this profile.
+ required: false
+
+ mapi_secure_tunnel:
+ description:
+ - Enable/disable securing the WAN Opt tunnel using SSL. Secure and non-secure tunnels use the
+ same TCP port (7810).
+ required: false
+ choices:
+ - disable
+ - enable
+
+ mapi_status:
+ description:
+ - Enable/disable HTTP WAN Optimization.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ mapi_tunnel_sharing:
+ description:
+ - Tunnel sharing mode for aggressive/non-aggressive and/or interactive/non-interactive protocols.
+ required: false
+ choices:
+ - private
+ - shared
+ - express-shared
+
+ tcp:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ tcp_byte_caching:
+ description:
+ - Enable/disable byte-caching for HTTP. Byte caching reduces the amount of traffic by caching
+ file data sent across the WAN and in future serving if from the cache.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ tcp_byte_caching_opt:
+ description:
+ - Select whether TCP byte-caching uses system memory only or both memory and disk space.
+ required: false
+ choices:
+ - mem-only
+ - mem-disk
+
+ tcp_log_traffic:
+ description:
+ - Enable/disable logging.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ tcp_port:
+ description:
+ - Single port number or port number range for TCP. Only packets with a destination port number
+ that matches this port number or range are accepted by this profile.
+ required: false
+
+ tcp_secure_tunnel:
+ description:
+ - Enable/disable securing the WAN Opt tunnel using SSL. Secure and non-secure tunnels use the
+ same TCP port (7810).
+ required: false
+ choices:
+ - disable
+ - enable
+
+ tcp_ssl:
+ description:
+ - Enable/disable SSL/TLS offloading.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ tcp_ssl_port:
+ description:
+ - Port on which to expect HTTPS traffic for SSL/TLS offloading.
+ required: false
+
+ tcp_status:
+ description:
+ - Enable/disable HTTP WAN Optimization.
+ required: false
+ choices:
+ - disable
+ - enable
+
+ tcp_tunnel_sharing:
+ description:
+ - Tunnel sharing mode for aggressive/non-aggressive and/or interactive/non-interactive protocols.
+ required: false
+ choices:
+ - private
+ - shared
+ - express-shared
+
+'''
+
+EXAMPLES = '''
+ - name: DELETE Profile
+ community.fortios.fmgr_secprof_wanopt:
+ name: "Ansible_WanOpt_Profile"
+ mode: "delete"
+
+ - name: Create FMGR_WANOPT_PROFILE
+ community.fortios.fmgr_secprof_wanopt:
+ mode: "set"
+ adom: "root"
+ transparent: "enable"
+ name: "Ansible_WanOpt_Profile"
+ comments: "Created by Ansible"
+ cifs: {byte-caching: "enable",
+ log-traffic: "enable",
+ port: 80,
+ prefer-chunking: "dynamic",
+ status: "enable",
+ tunnel-sharing: "private"}
+ ftp: {byte-caching: "enable",
+ log-traffic: "enable",
+ port: 80,
+ prefer-chunking: "dynamic",
+ secure-tunnel: "disable",
+ status: "enable",
+ tunnel-sharing: "private"}
+'''
+
+RETURN = """
+api_result:
+ description: full API response, includes status code and message
+ returned: always
+ type: str
+"""
+
+from ansible.module_utils.basic import AnsibleModule, env_fallback
+from ansible.module_utils.connection import Connection
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.fortimanager import FortiManagerHandler
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGBaseException
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRCommon
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import DEFAULT_RESULT_OBJ
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FAIL_SOCKET_MSG
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import prepare_dict
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import scrub_dict
+
+
+###############
+# START METHODS
+###############
+
+
+def fmgr_wanopt_profile_modify(fmgr, paramgram):
+ """
+ :param fmgr: The fmgr object instance from fortimanager.py
+ :type fmgr: class object
+ :param paramgram: The formatted dictionary of options to process
+ :type paramgram: dict
+ :return: The response from the FortiManager
+ :rtype: dict
+ """
+
+ mode = paramgram["mode"]
+ adom = paramgram["adom"]
+
+ response = DEFAULT_RESULT_OBJ
+ url = ""
+ datagram = {}
+
+ # EVAL THE MODE PARAMETER FOR SET OR ADD
+ if mode in ['set', 'add', 'update']:
+ url = '/pm/config/adom/{adom}/obj/wanopt/profile'.format(adom=adom)
+ datagram = scrub_dict(prepare_dict(paramgram))
+
+ # EVAL THE MODE PARAMETER FOR DELETE
+ elif mode == "delete":
+ # SET THE CORRECT URL FOR DELETE
+ url = '/pm/config/adom/{adom}/obj/wanopt/profile/{name}'.format(adom=adom, name=paramgram["name"])
+ datagram = {}
+
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+
+ return response
+
+
+#############
+# END METHODS
+#############
+
+
+def main():
+ argument_spec = dict(
+ adom=dict(type="str", default="root"),
+ mode=dict(choices=["add", "set", "delete", "update"], type="str", default="add"),
+
+ transparent=dict(required=False, type="str", choices=["disable", "enable"]),
+ name=dict(required=False, type="str"),
+ comments=dict(required=False, type="str"),
+ auth_group=dict(required=False, type="str"),
+ cifs=dict(required=False, type="dict"),
+ cifs_byte_caching=dict(required=False, type="str", choices=["disable", "enable"]),
+ cifs_log_traffic=dict(required=False, type="str", choices=["disable", "enable"]),
+ cifs_port=dict(required=False, type="str"),
+ cifs_prefer_chunking=dict(required=False, type="str", choices=["dynamic", "fix"]),
+ cifs_secure_tunnel=dict(required=False, type="str", choices=["disable", "enable"]),
+ cifs_status=dict(required=False, type="str", choices=["disable", "enable"]),
+ cifs_tunnel_sharing=dict(required=False, type="str", choices=["private", "shared", "express-shared"]),
+ ftp=dict(required=False, type="dict"),
+ ftp_byte_caching=dict(required=False, type="str", choices=["disable", "enable"]),
+ ftp_log_traffic=dict(required=False, type="str", choices=["disable", "enable"]),
+ ftp_port=dict(required=False, type="str"),
+ ftp_prefer_chunking=dict(required=False, type="str", choices=["dynamic", "fix"]),
+ ftp_secure_tunnel=dict(required=False, type="str", choices=["disable", "enable"]),
+ ftp_status=dict(required=False, type="str", choices=["disable", "enable"]),
+ ftp_tunnel_sharing=dict(required=False, type="str", choices=["private", "shared", "express-shared"]),
+ http=dict(required=False, type="dict"),
+ http_byte_caching=dict(required=False, type="str", choices=["disable", "enable"]),
+ http_log_traffic=dict(required=False, type="str", choices=["disable", "enable"]),
+ http_port=dict(required=False, type="str"),
+ http_prefer_chunking=dict(required=False, type="str", choices=["dynamic", "fix"]),
+ http_secure_tunnel=dict(required=False, type="str", choices=["disable", "enable"]),
+ http_ssl=dict(required=False, type="str", choices=["disable", "enable"]),
+ http_ssl_port=dict(required=False, type="str"),
+ http_status=dict(required=False, type="str", choices=["disable", "enable"]),
+ http_tunnel_non_http=dict(required=False, type="str", choices=["disable", "enable"]),
+ http_tunnel_sharing=dict(required=False, type="str", choices=["private", "shared", "express-shared"]),
+ http_unknown_http_version=dict(required=False, type="str", choices=["best-effort", "reject", "tunnel"]),
+ mapi=dict(required=False, type="dict"),
+ mapi_byte_caching=dict(required=False, type="str", choices=["disable", "enable"]),
+ mapi_log_traffic=dict(required=False, type="str", choices=["disable", "enable"]),
+ mapi_port=dict(required=False, type="str"),
+ mapi_secure_tunnel=dict(required=False, type="str", choices=["disable", "enable"]),
+ mapi_status=dict(required=False, type="str", choices=["disable", "enable"]),
+ mapi_tunnel_sharing=dict(required=False, type="str", choices=["private", "shared", "express-shared"]),
+ tcp=dict(required=False, type="dict"),
+ tcp_byte_caching=dict(required=False, type="str", choices=["disable", "enable"]),
+ tcp_byte_caching_opt=dict(required=False, type="str", choices=["mem-only", "mem-disk"]),
+ tcp_log_traffic=dict(required=False, type="str", choices=["disable", "enable"]),
+ tcp_port=dict(required=False, type="str"),
+ tcp_secure_tunnel=dict(required=False, type="str", choices=["disable", "enable"]),
+ tcp_ssl=dict(required=False, type="str", choices=["disable", "enable"]),
+ tcp_ssl_port=dict(required=False, type="str"),
+ tcp_status=dict(required=False, type="str", choices=["disable", "enable"]),
+ tcp_tunnel_sharing=dict(required=False, type="str", choices=["private", "shared", "express-shared"]),
+
+ )
+
+ module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False, )
+ # MODULE PARAMGRAM
+ paramgram = {
+ "mode": module.params["mode"],
+ "adom": module.params["adom"],
+ "transparent": module.params["transparent"],
+ "name": module.params["name"],
+ "comments": module.params["comments"],
+ "auth-group": module.params["auth_group"],
+ "cifs": {
+ "byte-caching": module.params["cifs_byte_caching"],
+ "log-traffic": module.params["cifs_log_traffic"],
+ "port": module.params["cifs_port"],
+ "prefer-chunking": module.params["cifs_prefer_chunking"],
+ "secure-tunnel": module.params["cifs_secure_tunnel"],
+ "status": module.params["cifs_status"],
+ "tunnel-sharing": module.params["cifs_tunnel_sharing"],
+ },
+ "ftp": {
+ "byte-caching": module.params["ftp_byte_caching"],
+ "log-traffic": module.params["ftp_log_traffic"],
+ "port": module.params["ftp_port"],
+ "prefer-chunking": module.params["ftp_prefer_chunking"],
+ "secure-tunnel": module.params["ftp_secure_tunnel"],
+ "status": module.params["ftp_status"],
+ "tunnel-sharing": module.params["ftp_tunnel_sharing"],
+ },
+ "http": {
+ "byte-caching": module.params["http_byte_caching"],
+ "log-traffic": module.params["http_log_traffic"],
+ "port": module.params["http_port"],
+ "prefer-chunking": module.params["http_prefer_chunking"],
+ "secure-tunnel": module.params["http_secure_tunnel"],
+ "ssl": module.params["http_ssl"],
+ "ssl-port": module.params["http_ssl_port"],
+ "status": module.params["http_status"],
+ "tunnel-non-http": module.params["http_tunnel_non_http"],
+ "tunnel-sharing": module.params["http_tunnel_sharing"],
+ "unknown-http-version": module.params["http_unknown_http_version"],
+ },
+ "mapi": {
+ "byte-caching": module.params["mapi_byte_caching"],
+ "log-traffic": module.params["mapi_log_traffic"],
+ "port": module.params["mapi_port"],
+ "secure-tunnel": module.params["mapi_secure_tunnel"],
+ "status": module.params["mapi_status"],
+ "tunnel-sharing": module.params["mapi_tunnel_sharing"],
+ },
+ "tcp": {
+ "byte-caching": module.params["tcp_byte_caching"],
+ "byte-caching-opt": module.params["tcp_byte_caching_opt"],
+ "log-traffic": module.params["tcp_log_traffic"],
+ "port": module.params["tcp_port"],
+ "secure-tunnel": module.params["tcp_secure_tunnel"],
+ "ssl": module.params["tcp_ssl"],
+ "ssl-port": module.params["tcp_ssl_port"],
+ "status": module.params["tcp_status"],
+ "tunnel-sharing": module.params["tcp_tunnel_sharing"],
+ }
+ }
+ module.paramgram = paramgram
+ fmgr = None
+ if module._socket_path:
+ connection = Connection(module._socket_path)
+ fmgr = FortiManagerHandler(connection, module)
+ fmgr.tools = FMGRCommon()
+ else:
+ module.fail_json(**FAIL_SOCKET_MSG)
+
+ list_overrides = ['cifs', 'ftp', 'http', 'mapi', 'tcp']
+ paramgram = fmgr.tools.paramgram_child_list_override(list_overrides=list_overrides,
+ paramgram=paramgram, module=module)
+
+ results = DEFAULT_RESULT_OBJ
+
+ try:
+ results = fmgr_wanopt_profile_modify(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ return module.exit_json(**results[1])
+
+
+if __name__ == "__main__":
+ main()
diff --git a/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_web.py b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_web.py
new file mode 100644
index 00000000..427cd2e0
--- /dev/null
+++ b/collections-debian-merged/ansible_collections/community/fortios/plugins/modules/fmgr_secprof_web.py
@@ -0,0 +1,1081 @@
+#!/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: fmgr_secprof_web
+notes:
+ - Full Documentation at U(https://ftnt-ansible-docs.readthedocs.io/en/latest/).
+author:
+ - Luke Weighall (@lweighall)
+ - Andrew Welsh (@Ghilli3)
+ - Jim Huber (@p4r4n0y1ng)
+short_description: Manage web filter security profiles in FortiManager
+description:
+ - Manage web filter security profiles in FortiManager through playbooks using the FMG API
+
+options:
+ adom:
+ description:
+ - The ADOM the configuration should belong to.
+ required: false
+ default: root
+
+ mode:
+ description:
+ - Sets one of three modes for managing the object.
+ - Allows use of soft-adds instead of overwriting existing values
+ choices: ['add', 'set', 'delete', 'update']
+ required: false
+ default: add
+
+ youtube_channel_status:
+ description:
+ - YouTube channel filter status.
+ - choice | disable | Disable YouTube channel filter.
+ - choice | blacklist | Block matches.
+ - choice | whitelist | Allow matches.
+ required: false
+ choices: ["disable", "blacklist", "whitelist"]
+
+ wisp_servers:
+ description:
+ - WISP servers.
+ required: false
+
+ wisp_algorithm:
+ description:
+ - WISP server selection algorithm.
+ - choice | auto-learning | Select the lightest loading healthy server.
+ - choice | primary-secondary | Select the first healthy server in order.
+ - choice | round-robin | Select the next healthy server.
+ required: false
+ choices: ["auto-learning", "primary-secondary", "round-robin"]
+
+ wisp:
+ description:
+ - Enable/disable web proxy WISP.
+ - choice | disable | Disable web proxy WISP.
+ - choice | enable | Enable web proxy WISP.
+ required: false
+ choices: ["disable", "enable"]
+
+ web_url_log:
+ description:
+ - Enable/disable logging URL filtering.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ web_invalid_domain_log:
+ description:
+ - Enable/disable logging invalid domain names.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ web_ftgd_quota_usage:
+ description:
+ - Enable/disable logging daily quota usage.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ web_ftgd_err_log:
+ description:
+ - Enable/disable logging rating errors.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ web_filter_vbs_log:
+ description:
+ - Enable/disable logging VBS scripts.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ web_filter_unknown_log:
+ description:
+ - Enable/disable logging unknown scripts.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ web_filter_referer_log:
+ description:
+ - Enable/disable logging referrers.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ web_filter_jscript_log:
+ description:
+ - Enable/disable logging JScripts.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ web_filter_js_log:
+ description:
+ - Enable/disable logging Java scripts.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ web_filter_cookie_removal_log:
+ description:
+ - Enable/disable logging blocked cookies.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ web_filter_cookie_log:
+ description:
+ - Enable/disable logging cookie filtering.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ web_filter_command_block_log:
+ description:
+ - Enable/disable logging blocked commands.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ web_filter_applet_log:
+ description:
+ - Enable/disable logging Java applets.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ web_filter_activex_log:
+ description:
+ - Enable/disable logging ActiveX.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ web_extended_all_action_log:
+ description:
+ - Enable/disable extended any filter action logging for web filtering.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ web_content_log:
+ description:
+ - Enable/disable logging logging blocked web content.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ replacemsg_group:
+ description:
+ - Replacement message group.
+ required: false
+
+ post_action:
+ description:
+ - Action taken for HTTP POST traffic.
+ - choice | normal | Normal, POST requests are allowed.
+ - choice | block | POST requests are blocked.
+ required: false
+ choices: ["normal", "block"]
+
+ ovrd_perm:
+ description:
+ - FLAG Based Options. Specify multiple in list form.
+ - flag | bannedword-override | Banned word override.
+ - flag | urlfilter-override | URL filter override.
+ - flag | fortiguard-wf-override | FortiGuard Web Filter override.
+ - flag | contenttype-check-override | Content-type header override.
+ required: false
+ choices:
+ - bannedword-override
+ - urlfilter-override
+ - fortiguard-wf-override
+ - contenttype-check-override
+
+ options:
+ description:
+ - FLAG Based Options. Specify multiple in list form.
+ - flag | block-invalid-url | Block sessions contained an invalid domain name.
+ - flag | jscript | Javascript block.
+ - flag | js | JS block.
+ - flag | vbs | VB script block.
+ - flag | unknown | Unknown script block.
+ - flag | wf-referer | Referring block.
+ - flag | intrinsic | Intrinsic script block.
+ - flag | wf-cookie | Cookie block.
+ - flag | per-user-bwl | Per-user black/white list filter
+ - flag | activexfilter | ActiveX filter.
+ - flag | cookiefilter | Cookie filter.
+ - flag | javafilter | Java applet filter.
+ required: false
+ choices:
+ - block-invalid-url
+ - jscript
+ - js
+ - vbs
+ - unknown
+ - wf-referer
+ - intrinsic
+ - wf-cookie
+ - per-user-bwl
+ - activexfilter
+ - cookiefilter
+ - javafilter
+
+ name:
+ description:
+ - Profile name.
+ required: false
+
+ log_all_url:
+ description:
+ - Enable/disable logging all URLs visited.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ inspection_mode:
+ description:
+ - Web filtering inspection mode.
+ - choice | proxy | Proxy.
+ - choice | flow-based | Flow based.
+ required: false
+ choices: ["proxy", "flow-based"]
+
+ https_replacemsg:
+ description:
+ - Enable replacement messages for HTTPS.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ extended_log:
+ description:
+ - Enable/disable extended logging for web filtering.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ comment:
+ description:
+ - Optional comments.
+ required: false
+
+ ftgd_wf:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ ftgd_wf_exempt_quota:
+ description:
+ - Do not stop quota for these categories.
+ required: false
+
+ ftgd_wf_max_quota_timeout:
+ description:
+ - Maximum FortiGuard quota used by single page view in seconds (excludes streams).
+ required: false
+
+ ftgd_wf_options:
+ description:
+ - Options for FortiGuard Web Filter.
+ - FLAG Based Options. Specify multiple in list form.
+ - flag | error-allow | Allow web pages with a rating error to pass through.
+ - flag | rate-server-ip | Rate the server IP in addition to the domain name.
+ - flag | connect-request-bypass | Bypass connection which has CONNECT request.
+ - flag | ftgd-disable | Disable FortiGuard scanning.
+ required: false
+ choices: ["error-allow", "rate-server-ip", "connect-request-bypass", "ftgd-disable"]
+
+ ftgd_wf_ovrd:
+ description:
+ - Allow web filter profile overrides.
+ required: false
+
+ ftgd_wf_rate_crl_urls:
+ description:
+ - Enable/disable rating CRL by URL.
+ - choice | disable | Disable rating CRL by URL.
+ - choice | enable | Enable rating CRL by URL.
+ required: false
+ choices: ["disable", "enable"]
+
+ ftgd_wf_rate_css_urls:
+ description:
+ - Enable/disable rating CSS by URL.
+ - choice | disable | Disable rating CSS by URL.
+ - choice | enable | Enable rating CSS by URL.
+ required: false
+ choices: ["disable", "enable"]
+
+ ftgd_wf_rate_image_urls:
+ description:
+ - Enable/disable rating images by URL.
+ - choice | disable | Disable rating images by URL (blocked images are replaced with blanks).
+ - choice | enable | Enable rating images by URL (blocked images are replaced with blanks).
+ required: false
+ choices: ["disable", "enable"]
+
+ ftgd_wf_rate_javascript_urls:
+ description:
+ - Enable/disable rating JavaScript by URL.
+ - choice | disable | Disable rating JavaScript by URL.
+ - choice | enable | Enable rating JavaScript by URL.
+ required: false
+ choices: ["disable", "enable"]
+
+ ftgd_wf_filters_action:
+ description:
+ - Action to take for matches.
+ - choice | block | Block access.
+ - choice | monitor | Allow access while logging the action.
+ - choice | warning | Allow access after warning the user.
+ - choice | authenticate | Authenticate user before allowing access.
+ required: false
+ choices: ["block", "monitor", "warning", "authenticate"]
+
+ ftgd_wf_filters_auth_usr_grp:
+ description:
+ - Groups with permission to authenticate.
+ required: false
+
+ ftgd_wf_filters_category:
+ description:
+ - Categories and groups the filter examines.
+ required: false
+
+ ftgd_wf_filters_log:
+ description:
+ - Enable/disable logging.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ ftgd_wf_filters_override_replacemsg:
+ description:
+ - Override replacement message.
+ required: false
+
+ ftgd_wf_filters_warn_duration:
+ description:
+ - Duration of warnings.
+ required: false
+
+ ftgd_wf_filters_warning_duration_type:
+ description:
+ - Re-display warning after closing browser or after a timeout.
+ - choice | session | After session ends.
+ - choice | timeout | After timeout occurs.
+ required: false
+ choices: ["session", "timeout"]
+
+ ftgd_wf_filters_warning_prompt:
+ description:
+ - Warning prompts in each category or each domain.
+ - choice | per-domain | Per-domain warnings.
+ - choice | per-category | Per-category warnings.
+ required: false
+ choices: ["per-domain", "per-category"]
+
+ ftgd_wf_quota_category:
+ description:
+ - FortiGuard categories to apply quota to (category action must be set to monitor).
+ required: false
+
+ ftgd_wf_quota_duration:
+ description:
+ - Duration of quota.
+ required: false
+
+ ftgd_wf_quota_override_replacemsg:
+ description:
+ - Override replacement message.
+ required: false
+
+ ftgd_wf_quota_type:
+ description:
+ - Quota type.
+ - choice | time | Use a time-based quota.
+ - choice | traffic | Use a traffic-based quota.
+ required: false
+ choices: ["time", "traffic"]
+
+ ftgd_wf_quota_unit:
+ description:
+ - Traffic quota unit of measurement.
+ - choice | B | Quota in bytes.
+ - choice | KB | Quota in kilobytes.
+ - choice | MB | Quota in megabytes.
+ - choice | GB | Quota in gigabytes.
+ required: false
+ choices: ["B", "KB", "MB", "GB"]
+
+ ftgd_wf_quota_value:
+ description:
+ - Traffic quota value.
+ required: false
+
+ override:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ override_ovrd_cookie:
+ description:
+ - Allow/deny browser-based (cookie) overrides.
+ - choice | deny | Deny browser-based (cookie) override.
+ - choice | allow | Allow browser-based (cookie) override.
+ required: false
+ choices: ["deny", "allow"]
+
+ override_ovrd_dur:
+ description:
+ - Override duration.
+ required: false
+
+ override_ovrd_dur_mode:
+ description:
+ - Override duration mode.
+ - choice | constant | Constant mode.
+ - choice | ask | Prompt for duration when initiating an override.
+ required: false
+ choices: ["constant", "ask"]
+
+ override_ovrd_scope:
+ description:
+ - Override scope.
+ - choice | user | Override for the user.
+ - choice | user-group | Override for the user's group.
+ - choice | ip | Override for the initiating IP.
+ - choice | ask | Prompt for scope when initiating an override.
+ - choice | browser | Create browser-based (cookie) override.
+ required: false
+ choices: ["user", "user-group", "ip", "ask", "browser"]
+
+ override_ovrd_user_group:
+ description:
+ - User groups with permission to use the override.
+ required: false
+
+ override_profile:
+ description:
+ - Web filter profile with permission to create overrides.
+ required: false
+
+ override_profile_attribute:
+ description:
+ - Profile attribute to retrieve from the RADIUS server.
+ - choice | User-Name | Use this attribute.
+ - choice | NAS-IP-Address | Use this attribute.
+ - choice | Framed-IP-Address | Use this attribute.
+ - choice | Framed-IP-Netmask | Use this attribute.
+ - choice | Filter-Id | Use this attribute.
+ - choice | Login-IP-Host | Use this attribute.
+ - choice | Reply-Message | Use this attribute.
+ - choice | Callback-Number | Use this attribute.
+ - choice | Callback-Id | Use this attribute.
+ - choice | Framed-Route | Use this attribute.
+ - choice | Framed-IPX-Network | Use this attribute.
+ - choice | Class | Use this attribute.
+ - choice | Called-Station-Id | Use this attribute.
+ - choice | Calling-Station-Id | Use this attribute.
+ - choice | NAS-Identifier | Use this attribute.
+ - choice | Proxy-State | Use this attribute.
+ - choice | Login-LAT-Service | Use this attribute.
+ - choice | Login-LAT-Node | Use this attribute.
+ - choice | Login-LAT-Group | Use this attribute.
+ - choice | Framed-AppleTalk-Zone | Use this attribute.
+ - choice | Acct-Session-Id | Use this attribute.
+ - choice | Acct-Multi-Session-Id | Use this attribute.
+ required: false
+ choices:
+ - User-Name
+ - NAS-IP-Address
+ - Framed-IP-Address
+ - Framed-IP-Netmask
+ - Filter-Id
+ - Login-IP-Host
+ - Reply-Message
+ - Callback-Number
+ - Callback-Id
+ - Framed-Route
+ - Framed-IPX-Network
+ - Class
+ - Called-Station-Id
+ - Calling-Station-Id
+ - NAS-Identifier
+ - Proxy-State
+ - Login-LAT-Service
+ - Login-LAT-Node
+ - Login-LAT-Group
+ - Framed-AppleTalk-Zone
+ - Acct-Session-Id
+ - Acct-Multi-Session-Id
+
+ override_profile_type:
+ description:
+ - Override profile type.
+ - choice | list | Profile chosen from list.
+ - choice | radius | Profile determined by RADIUS server.
+ required: false
+ choices: ["list", "radius"]
+
+ url_extraction:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ url_extraction_redirect_header:
+ description:
+ - HTTP header name to use for client redirect on blocked requests
+ required: false
+
+ url_extraction_redirect_no_content:
+ description:
+ - Enable / Disable empty message-body entity in HTTP response
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ url_extraction_redirect_url:
+ description:
+ - HTTP header value to use for client redirect on blocked requests
+ required: false
+
+ url_extraction_server_fqdn:
+ description:
+ - URL extraction server FQDN (fully qualified domain name)
+ required: false
+
+ url_extraction_status:
+ description:
+ - Enable URL Extraction
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ web:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ web_blacklist:
+ description:
+ - Enable/disable automatic addition of URLs detected by FortiSandbox to blacklist.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ web_bword_table:
+ description:
+ - Banned word table ID.
+ required: false
+
+ web_bword_threshold:
+ description:
+ - Banned word score threshold.
+ required: false
+
+ web_content_header_list:
+ description:
+ - Content header list.
+ required: false
+
+ web_keyword_match:
+ description:
+ - Search keywords to log when match is found.
+ required: false
+
+ web_log_search:
+ description:
+ - Enable/disable logging all search phrases.
+ - choice | disable | Disable setting.
+ - choice | enable | Enable setting.
+ required: false
+ choices: ["disable", "enable"]
+
+ web_safe_search:
+ description:
+ - Safe search type.
+ - FLAG Based Options. Specify multiple in list form.
+ - flag | url | Insert safe search string into URL.
+ - flag | header | Insert safe search header.
+ required: false
+ choices: ["url", "header"]
+
+ web_urlfilter_table:
+ description:
+ - URL filter table ID.
+ required: false
+
+ web_whitelist:
+ description:
+ - FortiGuard whitelist settings.
+ - FLAG Based Options. Specify multiple in list form.
+ - flag | exempt-av | Exempt antivirus.
+ - flag | exempt-webcontent | Exempt web content.
+ - flag | exempt-activex-java-cookie | Exempt ActiveX-JAVA-Cookie.
+ - flag | exempt-dlp | Exempt DLP.
+ - flag | exempt-rangeblock | Exempt RangeBlock.
+ - flag | extended-log-others | Support extended log.
+ required: false
+ choices:
+ - exempt-av
+ - exempt-webcontent
+ - exempt-activex-java-cookie
+ - exempt-dlp
+ - exempt-rangeblock
+ - extended-log-others
+
+ web_youtube_restrict:
+ description:
+ - YouTube EDU filter level.
+ - choice | strict | Strict access for YouTube.
+ - choice | none | Full access for YouTube.
+ - choice | moderate | Moderate access for YouTube.
+ required: false
+ choices: ["strict", "none", "moderate"]
+
+ youtube_channel_filter:
+ description:
+ - EXPERTS ONLY! KNOWLEDGE OF FMGR JSON API IS REQUIRED!
+ - List of multiple child objects to be added. Expects a list of dictionaries.
+ - Dictionaries must use FortiManager API parameters, not the ansible ones listed below.
+ - If submitted, all other prefixed sub-parameters ARE IGNORED.
+ - This object is MUTUALLY EXCLUSIVE with its options.
+ - We expect that you know what you are doing with these list parameters, and are leveraging the JSON API Guide.
+ - WHEN IN DOUBT, USE THE SUB OPTIONS BELOW INSTEAD TO CREATE OBJECTS WITH MULTIPLE TASKS
+ required: false
+
+ youtube_channel_filter_channel_id:
+ description:
+ - YouTube channel ID to be filtered.
+ required: false
+
+ youtube_channel_filter_comment:
+ description:
+ - Comment.
+ required: false
+
+
+'''
+
+EXAMPLES = '''
+ - name: DELETE Profile
+ community.fortios.fmgr_secprof_web:
+ name: "Ansible_Web_Filter_Profile"
+ mode: "delete"
+
+ - name: CREATE Profile
+ community.fortios.fmgr_secprof_web:
+ name: "Ansible_Web_Filter_Profile"
+ comment: "Created by Ansible Module TEST"
+ mode: "set"
+ extended_log: "enable"
+ inspection_mode: "proxy"
+ log_all_url: "enable"
+ options: "js"
+ ovrd_perm: "bannedword-override"
+ post_action: "block"
+ web_content_log: "enable"
+ web_extended_all_action_log: "enable"
+ web_filter_activex_log: "enable"
+ web_filter_applet_log: "enable"
+ web_filter_command_block_log: "enable"
+ web_filter_cookie_log: "enable"
+ web_filter_cookie_removal_log: "enable"
+ web_filter_js_log: "enable"
+ web_filter_jscript_log: "enable"
+ web_filter_referer_log: "enable"
+ web_filter_unknown_log: "enable"
+ web_filter_vbs_log: "enable"
+ web_ftgd_err_log: "enable"
+ web_ftgd_quota_usage: "enable"
+ web_invalid_domain_log: "enable"
+ web_url_log: "enable"
+ wisp: "enable"
+ wisp_algorithm: "auto-learning"
+ youtube_channel_status: "blacklist"
+'''
+
+RETURN = """
+api_result:
+ description: full API response, includes status code and message
+ returned: always
+ type: str
+"""
+
+from ansible.module_utils.basic import AnsibleModule, env_fallback
+from ansible.module_utils.connection import Connection
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.fortimanager import FortiManagerHandler
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGBaseException
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRCommon
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FMGRMethods
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import DEFAULT_RESULT_OBJ
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FAIL_SOCKET_MSG
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import prepare_dict
+from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import scrub_dict
+
+
+def fmgr_webfilter_profile_modify(fmgr, paramgram):
+
+ mode = paramgram["mode"]
+ adom = paramgram["adom"]
+
+ response = DEFAULT_RESULT_OBJ
+ url = ""
+ datagram = {}
+
+ # EVAL THE MODE PARAMETER FOR SET OR ADD
+ if mode in ['set', 'add', 'update']:
+ url = '/pm/config/adom/{adom}/obj/webfilter/profile'.format(adom=adom)
+ datagram = scrub_dict(prepare_dict(paramgram))
+
+ # EVAL THE MODE PARAMETER FOR DELETE
+ elif mode == "delete":
+ # SET THE CORRECT URL FOR DELETE
+ url = '/pm/config/adom/{adom}/obj/webfilter/profile/{name}'.format(adom=adom, name=paramgram["name"])
+ datagram = {}
+
+ response = fmgr.process_request(url, datagram, paramgram["mode"])
+
+ return response
+
+
+#############
+# END METHODS
+#############
+
+
+def main():
+ argument_spec = dict(
+ adom=dict(type="str", default="root"),
+ mode=dict(choices=["add", "set", "delete", "update"], type="str", default="add"),
+
+ youtube_channel_status=dict(required=False, type="str", choices=["disable", "blacklist", "whitelist"]),
+ wisp_servers=dict(required=False, type="str"),
+ wisp_algorithm=dict(required=False, type="str", choices=["auto-learning", "primary-secondary", "round-robin"]),
+ wisp=dict(required=False, type="str", choices=["disable", "enable"]),
+ web_url_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ web_invalid_domain_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ web_ftgd_quota_usage=dict(required=False, type="str", choices=["disable", "enable"]),
+ web_ftgd_err_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ web_filter_vbs_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ web_filter_unknown_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ web_filter_referer_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ web_filter_jscript_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ web_filter_js_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ web_filter_cookie_removal_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ web_filter_cookie_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ web_filter_command_block_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ web_filter_applet_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ web_filter_activex_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ web_extended_all_action_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ web_content_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ replacemsg_group=dict(required=False, type="str"),
+ post_action=dict(required=False, type="str", choices=["normal", "block"]),
+ ovrd_perm=dict(required=False, type="list", choices=["bannedword-override",
+ "urlfilter-override",
+ "fortiguard-wf-override",
+ "contenttype-check-override"]),
+ options=dict(required=False, type="list", choices=["block-invalid-url",
+ "jscript",
+ "js",
+ "vbs",
+ "unknown",
+ "wf-referer",
+ "intrinsic",
+ "wf-cookie",
+ "per-user-bwl",
+ "activexfilter",
+ "cookiefilter",
+ "javafilter"]),
+ name=dict(required=False, type="str"),
+ log_all_url=dict(required=False, type="str", choices=["disable", "enable"]),
+ inspection_mode=dict(required=False, type="str", choices=["proxy", "flow-based"]),
+ https_replacemsg=dict(required=False, type="str", choices=["disable", "enable"]),
+ extended_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ comment=dict(required=False, type="str"),
+ ftgd_wf=dict(required=False, type="list"),
+ ftgd_wf_exempt_quota=dict(required=False, type="str"),
+ ftgd_wf_max_quota_timeout=dict(required=False, type="int"),
+ ftgd_wf_options=dict(required=False, type="str", choices=["error-allow", "rate-server-ip",
+ "connect-request-bypass", "ftgd-disable"]),
+ ftgd_wf_ovrd=dict(required=False, type="str"),
+ ftgd_wf_rate_crl_urls=dict(required=False, type="str", choices=["disable", "enable"]),
+ ftgd_wf_rate_css_urls=dict(required=False, type="str", choices=["disable", "enable"]),
+ ftgd_wf_rate_image_urls=dict(required=False, type="str", choices=["disable", "enable"]),
+ ftgd_wf_rate_javascript_urls=dict(required=False, type="str", choices=["disable", "enable"]),
+
+ ftgd_wf_filters_action=dict(required=False, type="str", choices=["block", "monitor",
+ "warning", "authenticate"]),
+ ftgd_wf_filters_auth_usr_grp=dict(required=False, type="str"),
+ ftgd_wf_filters_category=dict(required=False, type="str"),
+ ftgd_wf_filters_log=dict(required=False, type="str", choices=["disable", "enable"]),
+ ftgd_wf_filters_override_replacemsg=dict(required=False, type="str"),
+ ftgd_wf_filters_warn_duration=dict(required=False, type="str"),
+ ftgd_wf_filters_warning_duration_type=dict(required=False, type="str", choices=["session", "timeout"]),
+ ftgd_wf_filters_warning_prompt=dict(required=False, type="str", choices=["per-domain", "per-category"]),
+
+ ftgd_wf_quota_category=dict(required=False, type="str"),
+ ftgd_wf_quota_duration=dict(required=False, type="str"),
+ ftgd_wf_quota_override_replacemsg=dict(required=False, type="str"),
+ ftgd_wf_quota_type=dict(required=False, type="str", choices=["time", "traffic"]),
+ ftgd_wf_quota_unit=dict(required=False, type="str", choices=["B", "KB", "MB", "GB"]),
+ ftgd_wf_quota_value=dict(required=False, type="int"),
+ override=dict(required=False, type="list"),
+ override_ovrd_cookie=dict(required=False, type="str", choices=["deny", "allow"]),
+ override_ovrd_dur=dict(required=False, type="str"),
+ override_ovrd_dur_mode=dict(required=False, type="str", choices=["constant", "ask"]),
+ override_ovrd_scope=dict(required=False, type="str", choices=["user", "user-group", "ip", "ask", "browser"]),
+ override_ovrd_user_group=dict(required=False, type="str"),
+ override_profile=dict(required=False, type="str"),
+ override_profile_attribute=dict(required=False, type="list", choices=["User-Name",
+ "NAS-IP-Address",
+ "Framed-IP-Address",
+ "Framed-IP-Netmask",
+ "Filter-Id",
+ "Login-IP-Host",
+ "Reply-Message",
+ "Callback-Number",
+ "Callback-Id",
+ "Framed-Route",
+ "Framed-IPX-Network",
+ "Class",
+ "Called-Station-Id",
+ "Calling-Station-Id",
+ "NAS-Identifier",
+ "Proxy-State",
+ "Login-LAT-Service",
+ "Login-LAT-Node",
+ "Login-LAT-Group",
+ "Framed-AppleTalk-Zone",
+ "Acct-Session-Id",
+ "Acct-Multi-Session-Id"]),
+ override_profile_type=dict(required=False, type="str", choices=["list", "radius"]),
+ url_extraction=dict(required=False, type="list"),
+ url_extraction_redirect_header=dict(required=False, type="str"),
+ url_extraction_redirect_no_content=dict(required=False, type="str", choices=["disable", "enable"]),
+ url_extraction_redirect_url=dict(required=False, type="str"),
+ url_extraction_server_fqdn=dict(required=False, type="str"),
+ url_extraction_status=dict(required=False, type="str", choices=["disable", "enable"]),
+ web=dict(required=False, type="list"),
+ web_blacklist=dict(required=False, type="str", choices=["disable", "enable"]),
+ web_bword_table=dict(required=False, type="str"),
+ web_bword_threshold=dict(required=False, type="int"),
+ web_content_header_list=dict(required=False, type="str"),
+ web_keyword_match=dict(required=False, type="str"),
+ web_log_search=dict(required=False, type="str", choices=["disable", "enable"]),
+ web_safe_search=dict(required=False, type="str", choices=["url", "header"]),
+ web_urlfilter_table=dict(required=False, type="str"),
+ web_whitelist=dict(required=False, type="list", choices=["exempt-av",
+ "exempt-webcontent",
+ "exempt-activex-java-cookie",
+ "exempt-dlp",
+ "exempt-rangeblock",
+ "extended-log-others"]),
+ web_youtube_restrict=dict(required=False, type="str", choices=["strict", "none", "moderate"]),
+ youtube_channel_filter=dict(required=False, type="list"),
+ youtube_channel_filter_channel_id=dict(required=False, type="str"),
+ youtube_channel_filter_comment=dict(required=False, type="str"),
+
+ )
+
+ module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False, )
+ # MODULE PARAMGRAM
+ paramgram = {
+ "mode": module.params["mode"],
+ "adom": module.params["adom"],
+ "youtube-channel-status": module.params["youtube_channel_status"],
+ "wisp-servers": module.params["wisp_servers"],
+ "wisp-algorithm": module.params["wisp_algorithm"],
+ "wisp": module.params["wisp"],
+ "web-url-log": module.params["web_url_log"],
+ "web-invalid-domain-log": module.params["web_invalid_domain_log"],
+ "web-ftgd-quota-usage": module.params["web_ftgd_quota_usage"],
+ "web-ftgd-err-log": module.params["web_ftgd_err_log"],
+ "web-filter-vbs-log": module.params["web_filter_vbs_log"],
+ "web-filter-unknown-log": module.params["web_filter_unknown_log"],
+ "web-filter-referer-log": module.params["web_filter_referer_log"],
+ "web-filter-jscript-log": module.params["web_filter_jscript_log"],
+ "web-filter-js-log": module.params["web_filter_js_log"],
+ "web-filter-cookie-removal-log": module.params["web_filter_cookie_removal_log"],
+ "web-filter-cookie-log": module.params["web_filter_cookie_log"],
+ "web-filter-command-block-log": module.params["web_filter_command_block_log"],
+ "web-filter-applet-log": module.params["web_filter_applet_log"],
+ "web-filter-activex-log": module.params["web_filter_activex_log"],
+ "web-extended-all-action-log": module.params["web_extended_all_action_log"],
+ "web-content-log": module.params["web_content_log"],
+ "replacemsg-group": module.params["replacemsg_group"],
+ "post-action": module.params["post_action"],
+ "ovrd-perm": module.params["ovrd_perm"],
+ "options": module.params["options"],
+ "name": module.params["name"],
+ "log-all-url": module.params["log_all_url"],
+ "inspection-mode": module.params["inspection_mode"],
+ "https-replacemsg": module.params["https_replacemsg"],
+ "extended-log": module.params["extended_log"],
+ "comment": module.params["comment"],
+ "ftgd-wf": {
+ "exempt-quota": module.params["ftgd_wf_exempt_quota"],
+ "max-quota-timeout": module.params["ftgd_wf_max_quota_timeout"],
+ "options": module.params["ftgd_wf_options"],
+ "ovrd": module.params["ftgd_wf_ovrd"],
+ "rate-crl-urls": module.params["ftgd_wf_rate_crl_urls"],
+ "rate-css-urls": module.params["ftgd_wf_rate_css_urls"],
+ "rate-image-urls": module.params["ftgd_wf_rate_image_urls"],
+ "rate-javascript-urls": module.params["ftgd_wf_rate_javascript_urls"],
+ "filters": {
+ "action": module.params["ftgd_wf_filters_action"],
+ "auth-usr-grp": module.params["ftgd_wf_filters_auth_usr_grp"],
+ "category": module.params["ftgd_wf_filters_category"],
+ "log": module.params["ftgd_wf_filters_log"],
+ "override-replacemsg": module.params["ftgd_wf_filters_override_replacemsg"],
+ "warn-duration": module.params["ftgd_wf_filters_warn_duration"],
+ "warning-duration-type": module.params["ftgd_wf_filters_warning_duration_type"],
+ "warning-prompt": module.params["ftgd_wf_filters_warning_prompt"],
+ },
+ "quota": {
+ "category": module.params["ftgd_wf_quota_category"],
+ "duration": module.params["ftgd_wf_quota_duration"],
+ "override-replacemsg": module.params["ftgd_wf_quota_override_replacemsg"],
+ "type": module.params["ftgd_wf_quota_type"],
+ "unit": module.params["ftgd_wf_quota_unit"],
+ "value": module.params["ftgd_wf_quota_value"],
+ },
+ },
+ "override": {
+ "ovrd-cookie": module.params["override_ovrd_cookie"],
+ "ovrd-dur": module.params["override_ovrd_dur"],
+ "ovrd-dur-mode": module.params["override_ovrd_dur_mode"],
+ "ovrd-scope": module.params["override_ovrd_scope"],
+ "ovrd-user-group": module.params["override_ovrd_user_group"],
+ "profile": module.params["override_profile"],
+ "profile-attribute": module.params["override_profile_attribute"],
+ "profile-type": module.params["override_profile_type"],
+ },
+ "url-extraction": {
+ "redirect-header": module.params["url_extraction_redirect_header"],
+ "redirect-no-content": module.params["url_extraction_redirect_no_content"],
+ "redirect-url": module.params["url_extraction_redirect_url"],
+ "server-fqdn": module.params["url_extraction_server_fqdn"],
+ "status": module.params["url_extraction_status"],
+ },
+ "web": {
+ "blacklist": module.params["web_blacklist"],
+ "bword-table": module.params["web_bword_table"],
+ "bword-threshold": module.params["web_bword_threshold"],
+ "content-header-list": module.params["web_content_header_list"],
+ "keyword-match": module.params["web_keyword_match"],
+ "log-search": module.params["web_log_search"],
+ "safe-search": module.params["web_safe_search"],
+ "urlfilter-table": module.params["web_urlfilter_table"],
+ "whitelist": module.params["web_whitelist"],
+ "youtube-restrict": module.params["web_youtube_restrict"],
+ },
+ "youtube-channel-filter": {
+ "channel-id": module.params["youtube_channel_filter_channel_id"],
+ "comment": module.params["youtube_channel_filter_comment"],
+ }
+ }
+ module.paramgram = paramgram
+ fmgr = None
+ if module._socket_path:
+ connection = Connection(module._socket_path)
+ fmgr = FortiManagerHandler(connection, module)
+ fmgr.tools = FMGRCommon()
+ else:
+ module.fail_json(**FAIL_SOCKET_MSG)
+
+ list_overrides = ['ftgd-wf', 'override', 'url-extraction', 'web', 'youtube-channel-filter']
+ paramgram = fmgr.tools.paramgram_child_list_override(list_overrides=list_overrides,
+ paramgram=paramgram, module=module)
+
+ results = DEFAULT_RESULT_OBJ
+
+ try:
+
+ results = fmgr_webfilter_profile_modify(fmgr, paramgram)
+ fmgr.govern_response(module=module, results=results,
+ ansible_facts=fmgr.construct_ansible_facts(results, module.params, paramgram))
+
+ except Exception as err:
+ raise FMGBaseException(err)
+
+ return module.exit_json(**results[1])
+
+
+if __name__ == "__main__":
+ main()