Migrated to fortinet.fortios

pull/68117/head
Ansible Core Team 6 years ago
parent a73c1da43a
commit 74c95055e9

@ -1,288 +0,0 @@
# 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.
# BEGIN STATIC DATA / MESSAGES
class FMGRMethods:
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'
}
# FMGR RETURN CODES
FMGR_RC = {
"fmgr_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 FortiManager. Serial number already in use.",
"good_codes": [0, -20010],
"changed": False,
"stop_on_success": True
},
-20002: {
"msg": "Invalid Argument -- Does this Device exist on FortiManager?",
"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 FMGBaseException(Exception):
"""Wrapper to catch the unexpected"""
def __init__(self, msg=None, *args, **kwargs):
if msg is None:
msg = "An exception occurred within the fortimanager.py httpapi connection plugin."
super(FMGBaseException, self).__init__(msg, *args)
# END ERROR CLASSES
# BEGIN CLASSES
class FMGRCommon(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 FortiManager.
: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 FMGBaseException("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. FortiManager 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. FortiManager 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

@ -1,466 +0,0 @@
# 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 ansible.module_utils.network.fortimanager.common import FMGR_RC
from ansible.module_utils.network.fortimanager.common import FMGBaseException
from ansible.module_utils.network.fortimanager.common import FMGRCommon
from ansible.module_utils.network.fortimanager.common import scrub_dict
# check for pyFMG lib - DEPRECATING
try:
from pyFMG.fortimgr import FortiManager
HAS_PYFMGR = True
except ImportError:
HAS_PYFMGR = False
# 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.network.fortimanager.fortimanager_debug import debug_dump
# HAS_FMGR_DEBUG = True
# except:
# HAS_FMGR_DEBUG = False
# BEGIN HANDLER CLASSES
class FortiManagerHandler(object):
def __init__(self, conn, module):
self._conn = conn
self._module = module
self._tools = FMGRCommon
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
"""
data = self._tools.format_request(method, url, **datagram)
response = self._conn.send_request(method, data)
# if HAS_FMGR_DEBUG:
# try:
# debug_dump(response, datagram, self._module.paramgram, url, method)
# except BaseException:
# pass
return response
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 FortiManager 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 FortiManager
: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 FMGBaseException("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 FMGBaseException("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 = FMGR_RC.get('fmgr_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()))
@staticmethod
def return_response(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 FortiManager
: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:
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:
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
def construct_ansible_facts(self, 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 FortiManager.
: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),
"connected_fmgr": self._conn.return_connected_fmgr()
}
if args:
facts["custom_args"] = args
if kwargs:
facts.update(kwargs)
return facts
##########################
# BEGIN DEPRECATED METHODS
##########################
# SOME OF THIS CODE IS DUPLICATED IN THE PLUGIN, BUT THOSE ARE PLUGIN SPECIFIC. THIS VERSION STILL ALLOWS FOR
# THE USAGE OF PYFMG FOR CUSTOMERS WHO HAVE NOT YET UPGRADED TO ANSIBLE 2.7
# LEGACY PYFMG METHODS START
# USED TO DETERMINE LOCK CONTEXT ON A FORTIMANAGER. A DATABASE LOCKING CONCEPT THAT NEEDS TO BE ACCOUNTED FOR.
class FMGLockContext(object):
"""
- DEPRECATING: USING CONNECTION MANAGER NOW INSTEAD. EVENTUALLY THIS CLASS WILL DISAPPEAR. PLEASE
- CONVERT ALL MODULES TO CONNECTION MANAGER METHOD.
- LEGACY pyFMG HANDLER OBJECT: REQUIRES A CHECK FOR PY FMG AT TOP OF PAGE
"""
def __init__(self, fmg):
self._fmg = fmg
self._locked_adom_list = list()
self._uses_workspace = False
self._uses_adoms = False
@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):
url = "/cli/global/system/global"
code, resp_obj = self._fmg.get(url, fields=["workspace-mode", "adom-status"])
try:
if resp_obj["workspace-mode"] != 0:
self.uses_workspace = True
except KeyError:
self.uses_workspace = False
try:
if resp_obj["adom-status"] == 1:
self.uses_adoms = True
except KeyError:
self.uses_adoms = False
def run_unlock(self):
for adom_locked in self._locked_adom_list:
self.unlock_adom(adom_locked)
def lock_adom(self, adom=None, *args, **kwargs):
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._fmg.execute(url, {}, *args, **kwargs)
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):
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._fmg.execute(url, {}, *args, **kwargs)
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):
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._fmg.execute(url, {}, *args, **kwargs)
# DEPRECATED -- USE PLUGIN INSTEAD
class AnsibleFortiManager(object):
"""
- DEPRECATING: USING CONNECTION MANAGER NOW INSTEAD. EVENTUALLY THIS CLASS WILL DISAPPEAR. PLEASE
- CONVERT ALL MODULES TO CONNECTION MANAGER METHOD.
- LEGACY pyFMG HANDLER OBJECT: REQUIRES A CHECK FOR PY FMG AT TOP OF PAGE
"""
def __init__(self, module, ip=None, username=None, passwd=None, use_ssl=True, verify_ssl=False, timeout=300):
self.ip = ip
self.username = username
self.passwd = passwd
self.use_ssl = use_ssl
self.verify_ssl = verify_ssl
self.timeout = timeout
self.fmgr_instance = None
if not HAS_PYFMGR:
module.fail_json(msg='Could not import the python library pyFMG required by this module')
self.module = module
def login(self):
if self.ip is not None:
self.fmgr_instance = FortiManager(self.ip, self.username, self.passwd, use_ssl=self.use_ssl,
verify_ssl=self.verify_ssl, timeout=self.timeout, debug=False,
disable_request_warnings=True)
return self.fmgr_instance.login()
def logout(self):
if self.fmgr_instance.sid is not None:
self.fmgr_instance.logout()
def get(self, url, data):
return self.fmgr_instance.get(url, **data)
def set(self, url, data):
return self.fmgr_instance.set(url, **data)
def update(self, url, data):
return self.fmgr_instance.update(url, **data)
def delete(self, url, data):
return self.fmgr_instance.delete(url, **data)
def add(self, url, data):
return self.fmgr_instance.add(url, **data)
def execute(self, url, data):
return self.fmgr_instance.execute(url, **data)
def move(self, url, data):
return self.fmgr_instance.move(url, **data)
def clone(self, url, data):
return self.fmgr_instance.clone(url, **data)
##########################
# END DEPRECATED METHODS
##########################

@ -1,45 +0,0 @@
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
"""
The arg spec for the fortios monitor module.
"""
class FactsArgs(object):
""" The arg spec for the fortios monitor module
"""
def __init__(self, **kwargs):
pass
argument_spec = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": False},
"gather_subset": {
"required": True, "type": "list", "elements": "dict",
"options": {
"fact": {"required": True, "type": "str"},
"filters": {"required": False, "type": "list", "elements": "dict"}
}
}
}

@ -1,28 +0,0 @@
#
# -*- coding: utf-8 -*-
# Copyright 2019 Fortinet, Inc.
# GNU General Public License v3.0+
# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
"""
The arg spec for the fortios_facts module
"""
from __future__ import absolute_import, division, print_function
__metaclass__ = type
class SystemArgs(object):
"""The arg spec for the fortios_facts module
"""
FACT_SYSTEM_SUBSETS = frozenset([
'system_current-admins_select',
'system_firmware_select',
'system_fortimanager_status',
'system_ha-checksums_select',
'system_interface_select',
'system_status_select',
'system_time_select',
])
def __init__(self, **kwargs):
pass

@ -1,92 +0,0 @@
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
"""
The facts class for fortios
this file validates each subset of monitor and selectively
calls the appropriate facts gathering and monitoring function
"""
from ansible.module_utils.network.fortios.argspec.facts.facts import FactsArgs
from ansible.module_utils.network.fortios.argspec.system.system import SystemArgs
from ansible.module_utils.network.common.facts.facts import FactsBase
from ansible.module_utils.network.fortios.facts.system.system import SystemFacts
class Facts(FactsBase):
""" The facts class for fortios
"""
FACT_SUBSETS = {
"system": SystemFacts
}
def __init__(self, module, fos=None, subset=None):
super(Facts, self).__init__(module)
self._fos = fos
self._subset = subset
def gen_runable(self, subsets, valid_subsets):
""" Generate the runable subset
:param module: The module instance
:param subsets: The provided subsets
:param valid_subsets: The valid subsets
:rtype: list
:returns: The runable subsets
"""
runable_subsets = []
FACT_DETAIL_SUBSETS = []
FACT_DETAIL_SUBSETS.extend(SystemArgs.FACT_SYSTEM_SUBSETS)
for subset in subsets:
if subset['fact'] not in FACT_DETAIL_SUBSETS:
self._module.fail_json(msg='Subset must be one of [%s], got %s' %
(', '.join(sorted([item for item in FACT_DETAIL_SUBSETS])), subset['fact']))
for valid_subset in frozenset(self.FACT_SUBSETS.keys()):
if subset['fact'].startswith(valid_subset):
runable_subsets.append((subset, valid_subset))
return runable_subsets
def get_network_legacy_facts(self, fact_legacy_obj_map, legacy_facts_type=None):
if not legacy_facts_type:
legacy_facts_type = self._gather_subset
runable_subsets = self.gen_runable(legacy_facts_type, frozenset(fact_legacy_obj_map.keys()))
if runable_subsets:
self.ansible_facts['ansible_net_gather_subset'] = []
instances = list()
for (subset, valid_subset) in runable_subsets:
instances.append(fact_legacy_obj_map[valid_subset](self._module, self._fos, subset))
for inst in instances:
inst.populate_facts(self._connection, self.ansible_facts)
def get_facts(self, facts_type=None, data=None):
""" Collect the facts for fortios
:param facts_type: List of facts types
:param data: previously collected conf
:rtype: dict
:return: the facts gathered
"""
self.get_network_legacy_facts(self.FACT_SUBSETS, facts_type)
return self.ansible_facts, self._warnings

@ -1,63 +0,0 @@
#
# -*- coding: utf-8 -*-
# Copyright 2019 Fortinet, Inc.
# GNU General Public License v3.0+
# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
"""
The fortios system facts class
It is in this file the runtime information is collected from the device
for a given resource, parsed, and the facts tree is populated
based on the configuration.
"""
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import re
from ansible.module_utils.network.common import utils
from ansible.module_utils.network.fortios.argspec.system.system import SystemArgs
class SystemFacts(object):
""" The fortios system facts class
"""
def __init__(self, module, fos=None, subset=None, subspec='config', options='options'):
self._module = module
self._fos = fos
self._subset = subset
def populate_facts(self, connection, ansible_facts, data=None):
""" Populate the facts for system
:param connection: the device connection
:param ansible_facts: Facts dictionary
:rtype: dictionary
:returns: facts
"""
ansible_facts['ansible_network_resources'].pop('system', None)
facts = {}
if self._subset['fact'].startswith(tuple(SystemArgs.FACT_SYSTEM_SUBSETS)):
gather_method = getattr(self, self._subset['fact'].replace('-', '_'), self.system_fact)
resp = gather_method()
facts.update({self._subset['fact']: resp})
ansible_facts['ansible_network_resources'].update(facts)
return ansible_facts
def system_fact(self):
fos = self._fos
vdom = self._module.params['vdom']
return fos.monitor('system', self._subset['fact'][len('system_'):].replace('_', '/'), vdom=vdom)
def system_interface_select(self):
fos = self._fos
vdom = self._module.params['vdom']
query_string = '?vdom=' + vdom
system_interface_select_param = self._subset['filters']
if system_interface_select_param:
for filter in system_interface_select_param:
for key, val in filter.items():
if val:
query_string += '&' + str(key) + '=' + str(val)
return fos.monitor('system', self._subset['fact'][len('system_'):].replace('_', '/') + query_string, vdom=None)

@ -1,338 +0,0 @@
# 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.
#
# Copyright (c), Benjamin Jolivot <bjolivot@gmail.com>, 2014,
# Miguel Angel Munoz <magonzalez@fortinet.com>, 2019
# 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
#
import os
import time
import traceback
from ansible.module_utils._text import to_text
from ansible.module_utils.basic import env_fallback
import json
# BEGIN DEPRECATED
# check for pyFG lib
try:
from pyFG import FortiOS, FortiConfig
from pyFG.exceptions import FailedCommit
HAS_PYFG = True
except ImportError:
HAS_PYFG = False
fortios_argument_spec = dict(
file_mode=dict(type='bool', default=False),
config_file=dict(type='path'),
host=dict(),
username=dict(fallback=(env_fallback, ['ANSIBLE_NET_USERNAME'])),
password=dict(fallback=(env_fallback, ['ANSIBLE_NET_PASSWORD']), no_log=True),
timeout=dict(type='int', default=60),
vdom=dict(type='str'),
backup=dict(type='bool', default=False),
backup_path=dict(type='path'),
backup_filename=dict(type='str'),
)
fortios_required_if = [
['file_mode', False, ['host', 'username', 'password']],
['file_mode', True, ['config_file']],
['backup', True, ['backup_path']],
]
fortios_mutually_exclusive = [
['config_file', 'host'],
['config_file', 'username'],
['config_file', 'password']
]
fortios_error_codes = {
'-3': "Object not found",
'-61': "Command error"
}
# END DEPRECATED
class FortiOSHandler(object):
def __init__(self, conn):
self._conn = conn
def cmdb_url(self, path, name, vdom=None, mkey=None):
url = '/api/v2/cmdb/' + path + '/' + name
if mkey:
url = url + '/' + str(mkey)
if vdom:
if vdom == "global":
url += '?global=1'
else:
url += '?vdom=' + vdom
return url
def mon_url(self, path, name, vdom=None, mkey=None):
url = '/api/v2/monitor/' + path + '/' + name
if mkey:
url = url + '/' + str(mkey)
if vdom:
if vdom == "global":
url += '?global=1'
else:
url += '?vdom=' + vdom
return url
def schema(self, path, name, vdom=None):
if vdom is None:
url = self.cmdb_url(path, name) + "?action=schema"
else:
url = self.cmdb_url(path, name, vdom=vdom) + "&action=schema"
status, result_data = self._conn.send_request(url=url)
if status == 200:
if vdom == "global":
return json.loads(to_text(result_data))[0]['results']
else:
return json.loads(to_text(result_data))['results']
else:
return json.loads(to_text(result_data))
def get_mkeyname(self, path, name, vdom=None):
schema = self.schema(path, name, vdom=vdom)
try:
keyname = schema['mkey']
except KeyError:
return False
return keyname
def get_mkey(self, path, name, data, vdom=None):
keyname = self.get_mkeyname(path, name, vdom)
if not keyname:
return None
else:
try:
mkey = data[keyname]
except KeyError:
return None
return mkey
def get(self, path, name, vdom=None, mkey=None, parameters=None):
url = self.cmdb_url(path, name, vdom, mkey=mkey)
status, result_data = self._conn.send_request(url=url, params=parameters, method='GET')
return self.formatresponse(result_data, vdom=vdom)
def monitor(self, path, name, vdom=None, mkey=None, parameters=None):
url = self.mon_url(path, name, vdom, mkey)
status, result_data = self._conn.send_request(url=url, params=parameters, method='GET')
return self.formatresponse(result_data, vdom=vdom)
def set(self, path, name, data, mkey=None, vdom=None, parameters=None):
if not mkey:
mkey = self.get_mkey(path, name, data, vdom=vdom)
url = self.cmdb_url(path, name, vdom, mkey)
status, result_data = self._conn.send_request(url=url, params=parameters, data=json.dumps(data), method='PUT')
if status == 404 or status == 405 or status == 500:
return self.post(path, name, data, vdom, mkey)
else:
return self.formatresponse(result_data, vdom=vdom)
def post(self, path, name, data, vdom=None,
mkey=None, parameters=None):
if mkey:
mkeyname = self.get_mkeyname(path, name, vdom)
data[mkeyname] = mkey
url = self.cmdb_url(path, name, vdom, mkey=None)
status, result_data = self._conn.send_request(url=url, params=parameters, data=json.dumps(data), method='POST')
return self.formatresponse(result_data, vdom=vdom)
def execute(self, path, name, data, vdom=None,
mkey=None, parameters=None, timeout=300):
url = self.mon_url(path, name, vdom, mkey=mkey)
status, result_data = self._conn.send_request(url=url, params=parameters, data=json.dumps(data), method='POST', timeout=timeout)
return self.formatresponse(result_data, vdom=vdom)
def delete(self, path, name, vdom=None, mkey=None, parameters=None, data=None):
if not mkey:
mkey = self.get_mkey(path, name, data, vdom=vdom)
url = self.cmdb_url(path, name, vdom, mkey)
status, result_data = self._conn.send_request(url=url, params=parameters, data=json.dumps(data), method='DELETE')
return self.formatresponse(result_data, vdom=vdom)
def formatresponse(self, res, vdom=None):
if vdom == "global":
resp = json.loads(to_text(res))[0]
resp['vdom'] = "global"
else:
resp = json.loads(to_text(res))
return resp
# BEGIN DEPRECATED
def backup(module, running_config):
backup_path = module.params['backup_path']
backup_filename = module.params['backup_filename']
if not os.path.exists(backup_path):
try:
os.mkdir(backup_path)
except Exception:
module.fail_json(msg="Can't create directory {0} Permission denied ?".format(backup_path))
tstamp = time.strftime("%Y-%m-%d@%H:%M:%S", time.localtime(time.time()))
if 0 < len(backup_filename):
filename = '%s/%s' % (backup_path, backup_filename)
else:
filename = '%s/%s_config.%s' % (backup_path, module.params['host'], tstamp)
try:
open(filename, 'w').write(running_config)
except Exception:
module.fail_json(msg="Can't create backup file {0} Permission denied ?".format(filename))
class AnsibleFortios(object):
def __init__(self, module):
if not HAS_PYFG:
module.fail_json(msg='Could not import the python library pyFG required by this module')
self.result = {
'changed': False,
}
self.module = module
def _connect(self):
if self.module.params['file_mode']:
self.forti_device = FortiOS('')
else:
host = self.module.params['host']
username = self.module.params['username']
password = self.module.params['password']
timeout = self.module.params['timeout']
vdom = self.module.params['vdom']
self.forti_device = FortiOS(host, username=username, password=password, timeout=timeout, vdom=vdom)
try:
self.forti_device.open()
except Exception as e:
self.module.fail_json(msg='Error connecting device. %s' % to_text(e),
exception=traceback.format_exc())
def load_config(self, path):
self.path = path
self._connect()
# load in file_mode
if self.module.params['file_mode']:
try:
f = open(self.module.params['config_file'], 'r')
running = f.read()
f.close()
except IOError as e:
self.module.fail_json(msg='Error reading configuration file. %s' % to_text(e),
exception=traceback.format_exc())
self.forti_device.load_config(config_text=running, path=path)
else:
# get config
try:
self.forti_device.load_config(path=path)
except Exception as e:
self.forti_device.close()
self.module.fail_json(msg='Error reading running config. %s' % to_text(e),
exception=traceback.format_exc())
# set configs in object
self.result['running_config'] = self.forti_device.running_config.to_text()
self.candidate_config = self.forti_device.candidate_config
# backup if needed
if self.module.params['backup']:
backup(self.module, self.forti_device.running_config.to_text())
def apply_changes(self):
change_string = self.forti_device.compare_config()
if change_string:
self.result['change_string'] = change_string
self.result['changed'] = True
# Commit if not check mode
if change_string and not self.module.check_mode:
if self.module.params['file_mode']:
try:
f = open(self.module.params['config_file'], 'w')
f.write(self.candidate_config.to_text())
f.close()
except IOError as e:
self.module.fail_json(msg='Error writing configuration file. %s' %
to_text(e), exception=traceback.format_exc())
else:
try:
self.forti_device.commit()
except FailedCommit as e:
# Something's wrong (rollback is automatic)
self.forti_device.close()
error_list = self.get_error_infos(e)
self.module.fail_json(msg_error_list=error_list, msg="Unable to commit change, check your args, the error was %s" % e.message)
self.forti_device.close()
self.module.exit_json(**self.result)
def del_block(self, block_id):
self.forti_device.candidate_config[self.path].del_block(block_id)
def add_block(self, block_id, block):
self.forti_device.candidate_config[self.path][block_id] = block
def get_error_infos(self, cli_errors):
error_list = []
for errors in cli_errors.args:
for error in errors:
error_code = error[0]
error_string = error[1]
error_type = fortios_error_codes.get(error_code, "unknown")
error_list.append(dict(error_code=error_code, error_type=error_type, error_string=error_string))
return error_list
def get_empty_configuration_block(self, block_name, block_type):
return FortiConfig(block_name, block_type)
# END DEPRECATED

@ -1,291 +0,0 @@
#!/usr/bin/python
#
# Ansible module to manage IP addresses on fortios devices
# (c) 2016, Benjamin Jolivot <bjolivot@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = """
---
module: fortios_address
version_added: "2.4"
author: "Benjamin Jolivot (@bjolivot)"
short_description: Manage fortios firewall address objects
description:
- This module provide management of firewall addresses on FortiOS devices.
extends_documentation_fragment: fortios
options:
state:
description:
- Specifies if address need to be added or deleted.
required: true
choices: ['present', 'absent']
name:
description:
- Name of the address to add or delete.
required: true
type:
description:
- Type of the address.
choices: ['iprange', 'fqdn', 'ipmask', 'geography']
value:
description:
- Address value, based on type.
If type=fqdn, something like www.google.com.
If type=ipmask, you can use simple ip (192.168.0.1), ip+mask (192.168.0.1 255.255.255.0) or CIDR (192.168.0.1/32).
start_ip:
description:
- First ip in range (used only with type=iprange).
end_ip:
description:
- Last ip in range (used only with type=iprange).
country:
description:
- 2 letter country code (like FR).
interface:
description:
- interface name the address apply to.
default: any
comment:
description:
- free text to describe address.
notes:
- This module requires netaddr python library.
"""
EXAMPLES = """
- name: Register french addresses
fortios_address:
host: 192.168.0.254
username: admin
password: p4ssw0rd
state: present
name: "fromfrance"
type: geography
country: FR
comment: "French geoip address"
- name: Register some fqdn
fortios_address:
host: 192.168.0.254
username: admin
password: p4ssw0rd
state: present
name: "Ansible"
type: fqdn
value: www.ansible.com
comment: "Ansible website"
- name: Register google DNS
fortios_address:
host: 192.168.0.254
username: admin
password: p4ssw0rd
state: present
name: "google_dns"
type: ipmask
value: 8.8.8.8
"""
RETURN = """
firewall_address_config:
description: full firewall addresses config string.
returned: always
type: str
change_string:
description: The commands executed by the module.
returned: only if config changed
type: str
"""
from ansible.module_utils.network.fortios.fortios import fortios_argument_spec, fortios_required_if
from ansible.module_utils.network.fortios.fortios import backup, AnsibleFortios
from ansible.module_utils.basic import AnsibleModule
# check for netaddr lib
try:
from netaddr import IPNetwork
HAS_NETADDR = True
except Exception:
HAS_NETADDR = False
# define valid country list for GEOIP address type
FG_COUNTRY_LIST = (
'ZZ', 'A1', 'A2', 'O1', 'AD', 'AE', 'AF', 'AG', 'AI', 'AL', 'AM', 'AN', 'AO',
'AP', 'AQ', 'AR', 'AS', 'AT', 'AU', 'AW', 'AX', 'AZ', 'BA', 'BB', 'BD', 'BE',
'BF', 'BG', 'BH', 'BI', 'BJ', 'BL', 'BM', 'BN', 'BO', 'BQ', 'BR', 'BS', 'BT',
'BV', 'BW', 'BY', 'BZ', 'CA', 'CC', 'CD', 'CF', 'CG', 'CH', 'CI', 'CK', 'CL',
'CM', 'CN', 'CO', 'CR', 'CU', 'CV', 'CW', 'CX', 'CY', 'CZ', 'DE', 'DJ', 'DK',
'DM', 'DO', 'DZ', 'EC', 'EE', 'EG', 'EH', 'ER', 'ES', 'ET', 'EU', 'FI', 'FJ',
'FK', 'FM', 'FO', 'FR', 'GA', 'GB', 'GD', 'GE', 'GF', 'GG', 'GH', 'GI', 'GL',
'GM', 'GN', 'GP', 'GQ', 'GR', 'GS', 'GT', 'GU', 'GW', 'GY', 'HK', 'HM', 'HN',
'HR', 'HT', 'HU', 'ID', 'IE', 'IL', 'IM', 'IN', 'IO', 'IQ', 'IR', 'IS', 'IT',
'JE', 'JM', 'JO', 'JP', 'KE', 'KG', 'KH', 'KI', 'KM', 'KN', 'KP', 'KR', 'KW',
'KY', 'KZ', 'LA', 'LB', 'LC', 'LI', 'LK', 'LR', 'LS', 'LT', 'LU', 'LV', 'LY',
'MA', 'MC', 'MD', 'ME', 'MF', 'MG', 'MH', 'MK', 'ML', 'MM', 'MN', 'MO', 'MP',
'MQ', 'MR', 'MS', 'MT', 'MU', 'MV', 'MW', 'MX', 'MY', 'MZ', 'NA', 'NC', 'NE',
'NF', 'NG', 'NI', 'NL', 'NO', 'NP', 'NR', 'NU', 'NZ', 'OM', 'PA', 'PE', 'PF',
'PG', 'PH', 'PK', 'PL', 'PM', 'PN', 'PR', 'PS', 'PT', 'PW', 'PY', 'QA', 'RE',
'RO', 'RS', 'RU', 'RW', 'SA', 'SB', 'SC', 'SD', 'SE', 'SG', 'SH', 'SI', 'SJ',
'SK', 'SL', 'SM', 'SN', 'SO', 'SR', 'SS', 'ST', 'SV', 'SX', 'SY', 'SZ', 'TC',
'TD', 'TF', 'TG', 'TH', 'TJ', 'TK', 'TL', 'TM', 'TN', 'TO', 'TR', 'TT', 'TV',
'TW', 'TZ', 'UA', 'UG', 'UM', 'US', 'UY', 'UZ', 'VA', 'VC', 'VE', 'VG', 'VI',
'VN', 'VU', 'WF', 'WS', 'YE', 'YT', 'ZA', 'ZM', 'ZW'
)
def get_formated_ipaddr(input_ip):
"""
Format given ip address string to fortigate format (ip netmask)
Args:
* **ip_str** (string) : string representing ip address
accepted format:
- ip netmask (ex: 192.168.0.10 255.255.255.0)
- ip (ex: 192.168.0.10)
- CIDR (ex: 192.168.0.10/24)
Returns:
formated ip if ip is valid (ex: "192.168.0.10 255.255.255.0")
False if ip is not valid
"""
try:
if " " in input_ip:
# ip netmask format
str_ip, str_netmask = input_ip.split(" ")
ip = IPNetwork(str_ip)
mask = IPNetwork(str_netmask)
return "%s %s" % (str_ip, str_netmask)
else:
ip = IPNetwork(input_ip)
return "%s %s" % (str(ip.ip), str(ip.netmask))
except Exception:
return False
return False
def main():
argument_spec = dict(
state=dict(required=True, choices=['present', 'absent']),
name=dict(required=True),
type=dict(choices=['iprange', 'fqdn', 'ipmask', 'geography'], default='ipmask'),
value=dict(),
start_ip=dict(),
end_ip=dict(),
country=dict(),
interface=dict(default='any'),
comment=dict(),
)
# merge argument_spec from module_utils/fortios.py
argument_spec.update(fortios_argument_spec)
# Load module
module = AnsibleModule(
argument_spec=argument_spec,
required_if=fortios_required_if,
supports_check_mode=True,
)
result = dict(changed=False)
if not HAS_NETADDR:
module.fail_json(msg='Could not import the python library netaddr required by this module')
# check params
if module.params['state'] == 'absent':
if module.params['type'] != "ipmask":
module.fail_json(msg='Invalid argument type=%s when state=absent' % module.params['type'])
if module.params['value'] is not None:
module.fail_json(msg='Invalid argument `value` when state=absent')
if module.params['start_ip'] is not None:
module.fail_json(msg='Invalid argument `start_ip` when state=absent')
if module.params['end_ip'] is not None:
module.fail_json(msg='Invalid argument `end_ip` when state=absent')
if module.params['country'] is not None:
module.fail_json(msg='Invalid argument `country` when state=absent')
if module.params['interface'] != "any":
module.fail_json(msg='Invalid argument `interface` when state=absent')
if module.params['comment'] is not None:
module.fail_json(msg='Invalid argument `comment` when state=absent')
else:
# state=present
# validate IP
if module.params['type'] == "ipmask":
formated_ip = get_formated_ipaddr(module.params['value'])
if formated_ip is not False:
module.params['value'] = get_formated_ipaddr(module.params['value'])
else:
module.fail_json(msg="Bad ip address format")
# validate country
if module.params['type'] == "geography":
if module.params['country'] not in FG_COUNTRY_LIST:
module.fail_json(msg="Invalid country argument, need to be in `diagnose firewall ipgeo country-list`")
# validate iprange
if module.params['type'] == "iprange":
if module.params['start_ip'] is None:
module.fail_json(msg="Missing argument 'start_ip' when type is iprange")
if module.params['end_ip'] is None:
module.fail_json(msg="Missing argument 'end_ip' when type is iprange")
# init forti object
fortigate = AnsibleFortios(module)
# Config path
config_path = 'firewall address'
# load config
fortigate.load_config(config_path)
# Absent State
if module.params['state'] == 'absent':
fortigate.candidate_config[config_path].del_block(module.params['name'])
# Present state
if module.params['state'] == 'present':
# define address params
new_addr = fortigate.get_empty_configuration_block(module.params['name'], 'edit')
if module.params['comment'] is not None:
new_addr.set_param('comment', '"%s"' % (module.params['comment']))
if module.params['type'] == 'iprange':
new_addr.set_param('type', 'iprange')
new_addr.set_param('start-ip', module.params['start_ip'])
new_addr.set_param('end-ip', module.params['end_ip'])
if module.params['type'] == 'geography':
new_addr.set_param('type', 'geography')
new_addr.set_param('country', '"%s"' % (module.params['country']))
if module.params['interface'] != 'any':
new_addr.set_param('associated-interface', '"%s"' % (module.params['interface']))
if module.params['value'] is not None:
if module.params['type'] == 'fqdn':
new_addr.set_param('type', 'fqdn')
new_addr.set_param('fqdn', '"%s"' % (module.params['value']))
if module.params['type'] == 'ipmask':
new_addr.set_param('subnet', module.params['value'])
# add the new address object to the device
fortigate.add_block(module.params['name'], new_addr)
# Apply changes (check mode is managed directly by the fortigate object)
fortigate.apply_changes()
if __name__ == '__main__':
main()

@ -1,602 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_alertemail_setting
short_description: Configure alert email settings in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify alertemail feature and setting category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.9"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
alertemail_setting:
description:
- Configure alert email settings.
default: null
type: dict
suboptions:
admin_login_logs:
description:
- Enable/disable administrator login/logout logs in alert email.
type: str
choices:
- enable
- disable
alert_interval:
description:
- Alert alert interval in minutes.
type: int
amc_interface_bypass_mode:
description:
- Enable/disable Fortinet Advanced Mezzanine Card (AMC) interface bypass mode logs in alert email.
type: str
choices:
- enable
- disable
antivirus_logs:
description:
- Enable/disable antivirus logs in alert email.
type: str
choices:
- enable
- disable
configuration_changes_logs:
description:
- Enable/disable configuration change logs in alert email.
type: str
choices:
- enable
- disable
critical_interval:
description:
- Critical alert interval in minutes.
type: int
debug_interval:
description:
- Debug alert interval in minutes.
type: int
email_interval:
description:
- Interval between sending alert emails (1 - 99999 min).
type: int
emergency_interval:
description:
- Emergency alert interval in minutes.
type: int
error_interval:
description:
- Error alert interval in minutes.
type: int
FDS_license_expiring_days:
description:
- Number of days to send alert email prior to FortiGuard license expiration (1 - 100 days).
type: int
FDS_license_expiring_warning:
description:
- Enable/disable FortiGuard license expiration warnings in alert email.
type: str
choices:
- enable
- disable
FDS_update_logs:
description:
- Enable/disable FortiGuard update logs in alert email.
type: str
choices:
- enable
- disable
filter_mode:
description:
- How to filter log messages that are sent to alert emails.
type: str
choices:
- category
- threshold
FIPS_CC_errors:
description:
- Enable/disable FIPS and Common Criteria error logs in alert email.
type: str
choices:
- enable
- disable
firewall_authentication_failure_logs:
description:
- Enable/disable firewall authentication failure logs in alert email.
type: str
choices:
- enable
- disable
fortiguard_log_quota_warning:
description:
- Enable/disable FortiCloud log quota warnings in alert email.
type: str
choices:
- enable
- disable
FSSO_disconnect_logs:
description:
- Enable/disable logging of FSSO collector agent disconnect.
type: str
choices:
- enable
- disable
HA_logs:
description:
- Enable/disable HA logs in alert email.
type: str
choices:
- enable
- disable
information_interval:
description:
- Information alert interval in minutes.
type: int
IPS_logs:
description:
- Enable/disable IPS logs in alert email.
type: str
choices:
- enable
- disable
IPsec_errors_logs:
description:
- Enable/disable IPsec error logs in alert email.
type: str
choices:
- enable
- disable
local_disk_usage:
description:
- Disk usage percentage at which to send alert email (1 - 99 percent).
type: int
log_disk_usage_warning:
description:
- Enable/disable disk usage warnings in alert email.
type: str
choices:
- enable
- disable
mailto1:
description:
- Email address to send alert email to (usually a system administrator) (max. 64 characters).
type: str
mailto2:
description:
- Optional second email address to send alert email to (max. 64 characters).
type: str
mailto3:
description:
- Optional third email address to send alert email to (max. 64 characters).
type: str
notification_interval:
description:
- Notification alert interval in minutes.
type: int
PPP_errors_logs:
description:
- Enable/disable PPP error logs in alert email.
type: str
choices:
- enable
- disable
severity:
description:
- Lowest severity level to log.
type: str
choices:
- emergency
- alert
- critical
- error
- warning
- notification
- information
- debug
ssh_logs:
description:
- Enable/disable SSH logs in alert email.
type: str
choices:
- enable
- disable
sslvpn_authentication_errors_logs:
description:
- Enable/disable SSL-VPN authentication error logs in alert email.
type: str
choices:
- enable
- disable
username:
description:
- "Name that appears in the From: field of alert emails (max. 36 characters)."
type: str
violation_traffic_logs:
description:
- Enable/disable violation traffic logs in alert email.
type: str
choices:
- enable
- disable
warning_interval:
description:
- Warning alert interval in minutes.
type: int
webfilter_logs:
description:
- Enable/disable web filter logs in alert email.
type: str
choices:
- enable
- disable
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure alert email settings.
fortios_alertemail_setting:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
alertemail_setting:
admin_login_logs: "enable"
alert_interval: "4"
amc_interface_bypass_mode: "enable"
antivirus_logs: "enable"
configuration_changes_logs: "enable"
critical_interval: "8"
debug_interval: "9"
email_interval: "10"
emergency_interval: "11"
error_interval: "12"
FDS_license_expiring_days: "13"
FDS_license_expiring_warning: "enable"
FDS_update_logs: "enable"
filter_mode: "category"
FIPS_CC_errors: "enable"
firewall_authentication_failure_logs: "enable"
fortiguard_log_quota_warning: "enable"
FSSO_disconnect_logs: "enable"
HA_logs: "enable"
information_interval: "22"
IPS_logs: "enable"
IPsec_errors_logs: "enable"
local_disk_usage: "25"
log_disk_usage_warning: "enable"
mailto1: "<your_own_value>"
mailto2: "<your_own_value>"
mailto3: "<your_own_value>"
notification_interval: "30"
PPP_errors_logs: "enable"
severity: "emergency"
ssh_logs: "enable"
sslvpn_authentication_errors_logs: "enable"
username: "<your_own_value>"
violation_traffic_logs: "enable"
warning_interval: "37"
webfilter_logs: "enable"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_alertemail_setting_data(json):
option_list = ['admin_login_logs', 'alert_interval', 'amc_interface_bypass_mode',
'antivirus_logs', 'configuration_changes_logs', 'critical_interval',
'debug_interval', 'email_interval', 'emergency_interval',
'error_interval', 'FDS_license_expiring_days', 'FDS_license_expiring_warning',
'FDS_update_logs', 'filter_mode', 'FIPS_CC_errors',
'firewall_authentication_failure_logs', 'fortiguard_log_quota_warning', 'FSSO_disconnect_logs',
'HA_logs', 'information_interval', 'IPS_logs',
'IPsec_errors_logs', 'local_disk_usage', 'log_disk_usage_warning',
'mailto1', 'mailto2', 'mailto3',
'notification_interval', 'PPP_errors_logs', 'severity',
'ssh_logs', 'sslvpn_authentication_errors_logs', 'username',
'violation_traffic_logs', 'warning_interval', 'webfilter_logs']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def alertemail_setting(data, fos):
vdom = data['vdom']
alertemail_setting_data = data['alertemail_setting']
filtered_data = underscore_to_hyphen(filter_alertemail_setting_data(alertemail_setting_data))
return fos.set('alertemail',
'setting',
data=filtered_data,
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_alertemail(data, fos):
if data['alertemail_setting']:
resp = alertemail_setting(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"alertemail_setting": {
"required": False, "type": "dict", "default": None,
"options": {
"admin_login_logs": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"alert_interval": {"required": False, "type": "int"},
"amc_interface_bypass_mode": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"antivirus_logs": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"configuration_changes_logs": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"critical_interval": {"required": False, "type": "int"},
"debug_interval": {"required": False, "type": "int"},
"email_interval": {"required": False, "type": "int"},
"emergency_interval": {"required": False, "type": "int"},
"error_interval": {"required": False, "type": "int"},
"FDS_license_expiring_days": {"required": False, "type": "int"},
"FDS_license_expiring_warning": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"FDS_update_logs": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"filter_mode": {"required": False, "type": "str",
"choices": ["category", "threshold"]},
"FIPS_CC_errors": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"firewall_authentication_failure_logs": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"fortiguard_log_quota_warning": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"FSSO_disconnect_logs": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"HA_logs": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"information_interval": {"required": False, "type": "int"},
"IPS_logs": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"IPsec_errors_logs": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"local_disk_usage": {"required": False, "type": "int"},
"log_disk_usage_warning": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"mailto1": {"required": False, "type": "str"},
"mailto2": {"required": False, "type": "str"},
"mailto3": {"required": False, "type": "str"},
"notification_interval": {"required": False, "type": "int"},
"PPP_errors_logs": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"severity": {"required": False, "type": "str",
"choices": ["emergency", "alert", "critical",
"error", "warning", "notification",
"information", "debug"]},
"ssh_logs": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"sslvpn_authentication_errors_logs": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"username": {"required": False, "type": "str"},
"violation_traffic_logs": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"warning_interval": {"required": False, "type": "int"},
"webfilter_logs": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_alertemail(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_alertemail(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,295 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_antivirus_heuristic
short_description: Configure global heuristic options in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify antivirus feature and heuristic category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
antivirus_heuristic:
description:
- Configure global heuristic options.
default: null
type: dict
suboptions:
mode:
description:
- Enable/disable heuristics and determine how the system behaves if heuristics detects a problem.
type: str
choices:
- pass
- block
- disable
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure global heuristic options.
fortios_antivirus_heuristic:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
antivirus_heuristic:
mode: "pass"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_antivirus_heuristic_data(json):
option_list = ['mode']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def antivirus_heuristic(data, fos):
vdom = data['vdom']
antivirus_heuristic_data = data['antivirus_heuristic']
filtered_data = underscore_to_hyphen(filter_antivirus_heuristic_data(antivirus_heuristic_data))
return fos.set('antivirus',
'heuristic',
data=filtered_data,
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_antivirus(data, fos):
if data['antivirus_heuristic']:
resp = antivirus_heuristic(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"antivirus_heuristic": {
"required": False, "type": "dict", "default": None,
"options": {
"mode": {"required": False, "type": "str",
"choices": ["pass", "block", "disable"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_antivirus(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_antivirus(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,505 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_antivirus_quarantine
short_description: Configure quarantine options in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify antivirus feature and quarantine category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
antivirus_quarantine:
description:
- Configure quarantine options.
default: null
type: dict
suboptions:
agelimit:
description:
- Age limit for quarantined files (0 - 479 hours, 0 means forever).
type: int
destination:
description:
- Choose whether to quarantine files to the FortiGate disk or to FortiAnalyzer or to delete them instead of quarantining them.
type: str
choices:
- NULL
- disk
- FortiAnalyzer
drop_blocked:
description:
- Do not quarantine dropped files found in sessions using the selected protocols. Dropped files are deleted instead of being quarantined.
type: str
choices:
- imap
- smtp
- pop3
- http
- ftp
- nntp
- imaps
- smtps
- pop3s
- ftps
- mapi
- cifs
- mm1
- mm3
- mm4
- mm7
drop_heuristic:
description:
- Do not quarantine files detected by heuristics found in sessions using the selected protocols. Dropped files are deleted instead of
being quarantined.
type: str
choices:
- imap
- smtp
- pop3
- http
- ftp
- nntp
- imaps
- smtps
- pop3s
- https
- ftps
- mapi
- cifs
- mm1
- mm3
- mm4
- mm7
drop_infected:
description:
- Do not quarantine infected files found in sessions using the selected protocols. Dropped files are deleted instead of being quarantined.
type: str
choices:
- imap
- smtp
- pop3
- http
- ftp
- nntp
- imaps
- smtps
- pop3s
- https
- ftps
- mapi
- cifs
- mm1
- mm3
- mm4
- mm7
lowspace:
description:
- Select the method for handling additional files when running low on disk space.
type: str
choices:
- drop-new
- ovrw-old
maxfilesize:
description:
- Maximum file size to quarantine (0 - 500 Mbytes, 0 means unlimited).
type: int
quarantine_quota:
description:
- The amount of disk space to reserve for quarantining files (0 - 4294967295 Mbytes, depends on disk space).
type: int
store_blocked:
description:
- Quarantine blocked files found in sessions using the selected protocols.
type: str
choices:
- imap
- smtp
- pop3
- http
- ftp
- nntp
- imaps
- smtps
- pop3s
- ftps
- mapi
- cifs
- mm1
- mm3
- mm4
- mm7
store_heuristic:
description:
- Quarantine files detected by heuristics found in sessions using the selected protocols.
type: str
choices:
- imap
- smtp
- pop3
- http
- ftp
- nntp
- imaps
- smtps
- pop3s
- https
- ftps
- mapi
- cifs
- mm1
- mm3
- mm4
- mm7
store_infected:
description:
- Quarantine infected files found in sessions using the selected protocols.
type: str
choices:
- imap
- smtp
- pop3
- http
- ftp
- nntp
- imaps
- smtps
- pop3s
- https
- ftps
- mapi
- cifs
- mm1
- mm3
- mm4
- mm7
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure quarantine options.
fortios_antivirus_quarantine:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
antivirus_quarantine:
agelimit: "3"
destination: "NULL"
drop_blocked: "imap"
drop_heuristic: "imap"
drop_infected: "imap"
lowspace: "drop-new"
maxfilesize: "9"
quarantine_quota: "10"
store_blocked: "imap"
store_heuristic: "imap"
store_infected: "imap"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_antivirus_quarantine_data(json):
option_list = ['agelimit', 'destination', 'drop_blocked',
'drop_heuristic', 'drop_infected', 'lowspace',
'maxfilesize', 'quarantine_quota', 'store_blocked',
'store_heuristic', 'store_infected']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def antivirus_quarantine(data, fos):
vdom = data['vdom']
antivirus_quarantine_data = data['antivirus_quarantine']
filtered_data = underscore_to_hyphen(filter_antivirus_quarantine_data(antivirus_quarantine_data))
return fos.set('antivirus',
'quarantine',
data=filtered_data,
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_antivirus(data, fos):
if data['antivirus_quarantine']:
resp = antivirus_quarantine(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"antivirus_quarantine": {
"required": False, "type": "dict", "default": None,
"options": {
"agelimit": {"required": False, "type": "int"},
"destination": {"required": False, "type": "str",
"choices": ["NULL", "disk", "FortiAnalyzer"]},
"drop_blocked": {"required": False, "type": "str",
"choices": ["imap", "smtp", "pop3",
"http", "ftp", "nntp",
"imaps", "smtps", "pop3s",
"ftps", "mapi", "cifs",
"mm1", "mm3", "mm4",
"mm7"]},
"drop_heuristic": {"required": False, "type": "str",
"choices": ["imap", "smtp", "pop3",
"http", "ftp", "nntp",
"imaps", "smtps", "pop3s",
"https", "ftps", "mapi",
"cifs", "mm1", "mm3",
"mm4", "mm7"]},
"drop_infected": {"required": False, "type": "str",
"choices": ["imap", "smtp", "pop3",
"http", "ftp", "nntp",
"imaps", "smtps", "pop3s",
"https", "ftps", "mapi",
"cifs", "mm1", "mm3",
"mm4", "mm7"]},
"lowspace": {"required": False, "type": "str",
"choices": ["drop-new", "ovrw-old"]},
"maxfilesize": {"required": False, "type": "int"},
"quarantine_quota": {"required": False, "type": "int"},
"store_blocked": {"required": False, "type": "str",
"choices": ["imap", "smtp", "pop3",
"http", "ftp", "nntp",
"imaps", "smtps", "pop3s",
"ftps", "mapi", "cifs",
"mm1", "mm3", "mm4",
"mm7"]},
"store_heuristic": {"required": False, "type": "str",
"choices": ["imap", "smtp", "pop3",
"http", "ftp", "nntp",
"imaps", "smtps", "pop3s",
"https", "ftps", "mapi",
"cifs", "mm1", "mm3",
"mm4", "mm7"]},
"store_infected": {"required": False, "type": "str",
"choices": ["imap", "smtp", "pop3",
"http", "ftp", "nntp",
"imaps", "smtps", "pop3s",
"https", "ftps", "mapi",
"cifs", "mm1", "mm3",
"mm4", "mm7"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_antivirus(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_antivirus(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,312 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_antivirus_settings
short_description: Configure AntiVirus settings in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify antivirus feature and settings category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
antivirus_settings:
description:
- Configure AntiVirus settings.
default: null
type: dict
suboptions:
default_db:
description:
- Select the AV database to be used for AV scanning.
type: str
choices:
- normal
- extended
- extreme
grayware:
description:
- Enable/disable grayware detection when an AntiVirus profile is applied to traffic.
type: str
choices:
- enable
- disable
override_timeout:
description:
- Override the large file scan timeout value in seconds (30 - 3600). Zero is the default value and is used to disable this command. When
disabled, the daemon adjusts the large file scan timeout based on the file size.
type: int
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure AntiVirus settings.
fortios_antivirus_settings:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
antivirus_settings:
default_db: "normal"
grayware: "enable"
override_timeout: "5"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_antivirus_settings_data(json):
option_list = ['default_db', 'grayware', 'override_timeout']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def antivirus_settings(data, fos):
vdom = data['vdom']
antivirus_settings_data = data['antivirus_settings']
filtered_data = underscore_to_hyphen(filter_antivirus_settings_data(antivirus_settings_data))
return fos.set('antivirus',
'settings',
data=filtered_data,
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_antivirus(data, fos):
if data['antivirus_settings']:
resp = antivirus_settings(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"antivirus_settings": {
"required": False, "type": "dict", "default": None,
"options": {
"default_db": {"required": False, "type": "str",
"choices": ["normal", "extended", "extreme"]},
"grayware": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"override_timeout": {"required": False, "type": "int"}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_antivirus(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_antivirus(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,388 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_application_custom
short_description: Configure custom application signatures in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify application feature and custom category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
application_custom:
description:
- Configure custom application signatures.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
behavior:
description:
- Custom application signature behavior.
type: str
category:
description:
- Custom application category ID (use ? to view available options).
type: int
comment:
description:
- Comment.
type: str
id:
description:
- Custom application category ID (use ? to view available options).
type: int
name:
description:
- Name of this custom application signature.
type: str
protocol:
description:
- Custom application signature protocol.
type: str
signature:
description:
- The text that makes up the actual custom application signature.
type: str
tag:
description:
- Signature tag.
required: true
type: str
technology:
description:
- Custom application signature technology.
type: str
vendor:
description:
- Custom application signature vendor.
type: str
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure custom application signatures.
fortios_application_custom:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
application_custom:
behavior: "<your_own_value>"
category: "4"
comment: "Comment."
id: "6"
name: "default_name_7"
protocol: "<your_own_value>"
signature: "<your_own_value>"
tag: "<your_own_value>"
technology: "<your_own_value>"
vendor: "<your_own_value>"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_application_custom_data(json):
option_list = ['behavior', 'category', 'comment',
'id', 'name', 'protocol',
'signature', 'tag', 'technology',
'vendor']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def application_custom(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['application_custom'] and data['application_custom']:
state = data['application_custom']['state']
else:
state = True
application_custom_data = data['application_custom']
filtered_data = underscore_to_hyphen(filter_application_custom_data(application_custom_data))
if state == "present":
return fos.set('application',
'custom',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('application',
'custom',
mkey=filtered_data['tag'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_application(data, fos):
if data['application_custom']:
resp = application_custom(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"application_custom": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"behavior": {"required": False, "type": "str"},
"category": {"required": False, "type": "int"},
"comment": {"required": False, "type": "str"},
"id": {"required": False, "type": "int"},
"name": {"required": False, "type": "str"},
"protocol": {"required": False, "type": "str"},
"signature": {"required": False, "type": "str"},
"tag": {"required": True, "type": "str"},
"technology": {"required": False, "type": "str"},
"vendor": {"required": False, "type": "str"}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_application(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_application(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,382 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_application_group
short_description: Configure firewall application groups in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify application feature and group category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
application_group:
description:
- Configure firewall application groups.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
application:
description:
- Application ID list.
type: list
suboptions:
id:
description:
- Application IDs.
required: true
type: int
category:
description:
- Application category ID list.
type: list
suboptions:
id:
description:
- Category IDs.
required: true
type: int
comment:
description:
- Comment
type: str
name:
description:
- Application group name.
required: true
type: str
type:
description:
- Application group type.
type: str
choices:
- application
- category
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure firewall application groups.
fortios_application_group:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
application_group:
application:
-
id: "4"
category:
-
id: "6"
comment: "Comment"
name: "default_name_8"
type: "application"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_application_group_data(json):
option_list = ['application', 'category', 'comment',
'name', 'type']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def application_group(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['application_group'] and data['application_group']:
state = data['application_group']['state']
else:
state = True
application_group_data = data['application_group']
filtered_data = underscore_to_hyphen(filter_application_group_data(application_group_data))
if state == "present":
return fos.set('application',
'group',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('application',
'group',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_application(data, fos):
if data['application_group']:
resp = application_group(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"application_group": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"application": {"required": False, "type": "list",
"options": {
"id": {"required": True, "type": "int"}
}},
"category": {"required": False, "type": "list",
"options": {
"id": {"required": True, "type": "int"}
}},
"comment": {"required": False, "type": "str"},
"name": {"required": True, "type": "str"},
"type": {"required": False, "type": "str",
"choices": ["application", "category"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_application(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_application(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,705 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_application_list
short_description: Configure application control lists in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify application feature and list category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
application_list:
description:
- Configure application control lists.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
app_replacemsg:
description:
- Enable/disable replacement messages for blocked applications.
type: str
choices:
- disable
- enable
comment:
description:
- comments
type: str
deep_app_inspection:
description:
- Enable/disable deep application inspection.
type: str
choices:
- disable
- enable
entries:
description:
- Application list entries.
type: list
suboptions:
action:
description:
- Pass or block traffic, or reset connection for traffic from this application.
type: str
choices:
- pass
- block
- reset
application:
description:
- ID of allowed applications.
type: list
suboptions:
id:
description:
- Application IDs.
required: true
type: int
behavior:
description:
- Application behavior filter.
type: str
category:
description:
- Category ID list.
type: list
suboptions:
id:
description:
- Application category ID.
required: true
type: int
id:
description:
- Entry ID.
required: true
type: int
log:
description:
- Enable/disable logging for this application list.
type: str
choices:
- disable
- enable
log_packet:
description:
- Enable/disable packet logging.
type: str
choices:
- disable
- enable
parameters:
description:
- Application parameters.
type: list
suboptions:
id:
description:
- Parameter ID.
required: true
type: int
value:
description:
- Parameter value.
type: str
per_ip_shaper:
description:
- Per-IP traffic shaper. Source firewall.shaper.per-ip-shaper.name.
type: str
popularity:
description:
- Application popularity filter (1 - 5, from least to most popular).
type: str
choices:
- 1
- 2
- 3
- 4
- 5
protocols:
description:
- Application protocol filter.
type: str
quarantine:
description:
- Quarantine method.
type: str
choices:
- none
- attacker
quarantine_expiry:
description:
- Duration of quarantine. (Format ###d##h##m, minimum 1m, maximum 364d23h59m). Requires quarantine set to attacker.
type: str
quarantine_log:
description:
- Enable/disable quarantine logging.
type: str
choices:
- disable
- enable
rate_count:
description:
- Count of the rate.
type: int
rate_duration:
description:
- Duration (sec) of the rate.
type: int
rate_mode:
description:
- Rate limit mode.
type: str
choices:
- periodical
- continuous
rate_track:
description:
- Track the packet protocol field.
type: str
choices:
- none
- src-ip
- dest-ip
- dhcp-client-mac
- dns-domain
risk:
description:
- Risk, or impact, of allowing traffic from this application to occur (1 - 5; Low, Elevated, Medium, High, and Critical).
type: list
suboptions:
level:
description:
- Risk, or impact, of allowing traffic from this application to occur (1 - 5; Low, Elevated, Medium, High, and Critical).
required: true
type: int
session_ttl:
description:
- Session TTL (0 = default).
type: int
shaper:
description:
- Traffic shaper. Source firewall.shaper.traffic-shaper.name.
type: str
shaper_reverse:
description:
- Reverse traffic shaper. Source firewall.shaper.traffic-shaper.name.
type: str
sub_category:
description:
- Application Sub-category ID list.
type: list
suboptions:
id:
description:
- Application sub-category ID.
required: true
type: int
technology:
description:
- Application technology filter.
type: str
vendor:
description:
- Application vendor filter.
type: str
extended_log:
description:
- Enable/disable extended logging.
type: str
choices:
- enable
- disable
name:
description:
- List name.
required: true
type: str
options:
description:
- Basic application protocol signatures allowed by default.
type: str
choices:
- allow-dns
- allow-icmp
- allow-http
- allow-ssl
- allow-quic
other_application_action:
description:
- Action for other applications.
type: str
choices:
- pass
- block
other_application_log:
description:
- Enable/disable logging for other applications.
type: str
choices:
- disable
- enable
p2p_black_list:
description:
- P2P applications to be black listed.
type: str
choices:
- skype
- edonkey
- bittorrent
replacemsg_group:
description:
- Replacement message group. Source system.replacemsg-group.name.
type: str
unknown_application_action:
description:
- Pass or block traffic from unknown applications.
type: str
choices:
- pass
- block
unknown_application_log:
description:
- Enable/disable logging for unknown applications.
type: str
choices:
- disable
- enable
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure application control lists.
fortios_application_list:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
application_list:
app_replacemsg: "disable"
comment: "comments"
deep_app_inspection: "disable"
entries:
-
action: "pass"
application:
-
id: "9"
behavior: "<your_own_value>"
category:
-
id: "12"
id: "13"
log: "disable"
log_packet: "disable"
parameters:
-
id: "17"
value: "<your_own_value>"
per_ip_shaper: "<your_own_value> (source firewall.shaper.per-ip-shaper.name)"
popularity: "1"
protocols: "<your_own_value>"
quarantine: "none"
quarantine_expiry: "<your_own_value>"
quarantine_log: "disable"
rate_count: "25"
rate_duration: "26"
rate_mode: "periodical"
rate_track: "none"
risk:
-
level: "30"
session_ttl: "31"
shaper: "<your_own_value> (source firewall.shaper.traffic-shaper.name)"
shaper_reverse: "<your_own_value> (source firewall.shaper.traffic-shaper.name)"
sub_category:
-
id: "35"
technology: "<your_own_value>"
vendor: "<your_own_value>"
extended_log: "enable"
name: "default_name_39"
options: "allow-dns"
other_application_action: "pass"
other_application_log: "disable"
p2p_black_list: "skype"
replacemsg_group: "<your_own_value> (source system.replacemsg-group.name)"
unknown_application_action: "pass"
unknown_application_log: "disable"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_application_list_data(json):
option_list = ['app_replacemsg', 'comment', 'deep_app_inspection',
'entries', 'extended_log', 'name',
'options', 'other_application_action', 'other_application_log',
'p2p_black_list', 'replacemsg_group', 'unknown_application_action',
'unknown_application_log']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def application_list(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['application_list'] and data['application_list']:
state = data['application_list']['state']
else:
state = True
application_list_data = data['application_list']
filtered_data = underscore_to_hyphen(filter_application_list_data(application_list_data))
if state == "present":
return fos.set('application',
'list',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('application',
'list',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_application(data, fos):
if data['application_list']:
resp = application_list(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"application_list": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"app_replacemsg": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"comment": {"required": False, "type": "str"},
"deep_app_inspection": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"entries": {"required": False, "type": "list",
"options": {
"action": {"required": False, "type": "str",
"choices": ["pass", "block", "reset"]},
"application": {"required": False, "type": "list",
"options": {
"id": {"required": True, "type": "int"}
}},
"behavior": {"required": False, "type": "str"},
"category": {"required": False, "type": "list",
"options": {
"id": {"required": True, "type": "int"}
}},
"id": {"required": True, "type": "int"},
"log": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"log_packet": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"parameters": {"required": False, "type": "list",
"options": {
"id": {"required": True, "type": "int"},
"value": {"required": False, "type": "str"}
}},
"per_ip_shaper": {"required": False, "type": "str"},
"popularity": {"required": False, "type": "str",
"choices": ["1", "2", "3",
"4", "5"]},
"protocols": {"required": False, "type": "str"},
"quarantine": {"required": False, "type": "str",
"choices": ["none", "attacker"]},
"quarantine_expiry": {"required": False, "type": "str"},
"quarantine_log": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"rate_count": {"required": False, "type": "int"},
"rate_duration": {"required": False, "type": "int"},
"rate_mode": {"required": False, "type": "str",
"choices": ["periodical", "continuous"]},
"rate_track": {"required": False, "type": "str",
"choices": ["none", "src-ip", "dest-ip",
"dhcp-client-mac", "dns-domain"]},
"risk": {"required": False, "type": "list",
"options": {
"level": {"required": True, "type": "int"}
}},
"session_ttl": {"required": False, "type": "int"},
"shaper": {"required": False, "type": "str"},
"shaper_reverse": {"required": False, "type": "str"},
"sub_category": {"required": False, "type": "list",
"options": {
"id": {"required": True, "type": "int"}
}},
"technology": {"required": False, "type": "str"},
"vendor": {"required": False, "type": "str"}
}},
"extended_log": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"name": {"required": True, "type": "str"},
"options": {"required": False, "type": "str",
"choices": ["allow-dns", "allow-icmp", "allow-http",
"allow-ssl", "allow-quic"]},
"other_application_action": {"required": False, "type": "str",
"choices": ["pass", "block"]},
"other_application_log": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"p2p_black_list": {"required": False, "type": "str",
"choices": ["skype", "edonkey", "bittorrent"]},
"replacemsg_group": {"required": False, "type": "str"},
"unknown_application_action": {"required": False, "type": "str",
"choices": ["pass", "block"]},
"unknown_application_log": {"required": False, "type": "str",
"choices": ["disable", "enable"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_application(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_application(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,430 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_application_name
short_description: Configure application signatures in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify application feature and name category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
application_name:
description:
- Configure application signatures.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
behavior:
description:
- Application behavior.
type: str
category:
description:
- Application category ID.
type: int
id:
description:
- Application ID.
type: int
metadata:
description:
- Meta data.
type: list
suboptions:
id:
description:
- ID.
required: true
type: int
metaid:
description:
- Meta ID.
type: int
valueid:
description:
- Value ID.
type: int
name:
description:
- Application name.
required: true
type: str
parameter:
description:
- Application parameter name.
type: str
popularity:
description:
- Application popularity.
type: int
protocol:
description:
- Application protocol.
type: str
risk:
description:
- Application risk.
type: int
sub_category:
description:
- Application sub-category ID.
type: int
technology:
description:
- Application technology.
type: str
vendor:
description:
- Application vendor.
type: str
weight:
description:
- Application weight.
type: int
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure application signatures.
fortios_application_name:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
application_name:
behavior: "<your_own_value>"
category: "4"
id: "5"
metadata:
-
id: "7"
metaid: "8"
valueid: "9"
name: "default_name_10"
parameter: "<your_own_value>"
popularity: "12"
protocol: "<your_own_value>"
risk: "14"
sub_category: "15"
technology: "<your_own_value>"
vendor: "<your_own_value>"
weight: "18"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_application_name_data(json):
option_list = ['behavior', 'category', 'id',
'metadata', 'name', 'parameter',
'popularity', 'protocol', 'risk',
'sub_category', 'technology', 'vendor',
'weight']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def application_name(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['application_name'] and data['application_name']:
state = data['application_name']['state']
else:
state = True
application_name_data = data['application_name']
filtered_data = underscore_to_hyphen(filter_application_name_data(application_name_data))
if state == "present":
return fos.set('application',
'name',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('application',
'name',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_application(data, fos):
if data['application_name']:
resp = application_name(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"application_name": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"behavior": {"required": False, "type": "str"},
"category": {"required": False, "type": "int"},
"id": {"required": False, "type": "int"},
"metadata": {"required": False, "type": "list",
"options": {
"id": {"required": True, "type": "int"},
"metaid": {"required": False, "type": "int"},
"valueid": {"required": False, "type": "int"}
}},
"name": {"required": True, "type": "str"},
"parameter": {"required": False, "type": "str"},
"popularity": {"required": False, "type": "int"},
"protocol": {"required": False, "type": "str"},
"risk": {"required": False, "type": "int"},
"sub_category": {"required": False, "type": "int"},
"technology": {"required": False, "type": "str"},
"vendor": {"required": False, "type": "str"},
"weight": {"required": False, "type": "int"}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_application(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_application(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,331 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_application_rule_settings
short_description: Configure application rule settings in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify application feature and rule_settings category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
application_rule_settings:
description:
- Configure application rule settings.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
id:
description:
- Rule ID.
required: true
type: int
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure application rule settings.
fortios_application_rule_settings:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
application_rule_settings:
id: "3"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_application_rule_settings_data(json):
option_list = ['id']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def application_rule_settings(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['application_rule_settings'] and data['application_rule_settings']:
state = data['application_rule_settings']['state']
else:
state = True
application_rule_settings_data = data['application_rule_settings']
filtered_data = underscore_to_hyphen(filter_application_rule_settings_data(application_rule_settings_data))
if state == "present":
return fos.set('application',
'rule-settings',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('application',
'rule-settings',
mkey=filtered_data['id'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_application(data, fos):
if data['application_rule_settings']:
resp = application_rule_settings(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"application_rule_settings": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"id": {"required": True, "type": "int"}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_application(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_application(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,439 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_authentication_rule
short_description: Configure Authentication Rules in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify authentication feature and rule category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
authentication_rule:
description:
- Configure Authentication Rules.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
active_auth_method:
description:
- Select an active authentication method. Source authentication.scheme.name.
type: str
comments:
description:
- Comment.
type: str
ip_based:
description:
- Enable/disable IP-based authentication. Once a user authenticates all traffic from the IP address the user authenticated from is allowed.
type: str
choices:
- enable
- disable
name:
description:
- Authentication rule name.
required: true
type: str
protocol:
description:
- Select the protocol to use for authentication . Users connect to the FortiGate using this protocol and are asked to authenticate.
type: str
choices:
- http
- ftp
- socks
- ssh
srcaddr:
description:
- Select an IPv4 source address from available options. Required for web proxy authentication.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address.name firewall.addrgrp.name firewall.proxy-address.name firewall.proxy-addrgrp.name.
required: true
type: str
srcaddr6:
description:
- Select an IPv6 source address. Required for web proxy authentication.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address6.name firewall.addrgrp6.name.
required: true
type: str
sso_auth_method:
description:
- Select a single-sign on (SSO) authentication method. Source authentication.scheme.name.
type: str
status:
description:
- Enable/disable this authentication rule.
type: str
choices:
- enable
- disable
transaction_based:
description:
- Enable/disable transaction based authentication .
type: str
choices:
- enable
- disable
web_auth_cookie:
description:
- Enable/disable Web authentication cookies .
type: str
choices:
- enable
- disable
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure Authentication Rules.
fortios_authentication_rule:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
authentication_rule:
active_auth_method: "<your_own_value> (source authentication.scheme.name)"
comments: "<your_own_value>"
ip_based: "enable"
name: "default_name_6"
protocol: "http"
srcaddr:
-
name: "default_name_9 (source firewall.address.name firewall.addrgrp.name firewall.proxy-address.name firewall.proxy-addrgrp.name)"
srcaddr6:
-
name: "default_name_11 (source firewall.address6.name firewall.addrgrp6.name)"
sso_auth_method: "<your_own_value> (source authentication.scheme.name)"
status: "enable"
transaction_based: "enable"
web_auth_cookie: "enable"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_authentication_rule_data(json):
option_list = ['active_auth_method', 'comments', 'ip_based',
'name', 'protocol', 'srcaddr',
'srcaddr6', 'sso_auth_method', 'status',
'transaction_based', 'web_auth_cookie']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def authentication_rule(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['authentication_rule'] and data['authentication_rule']:
state = data['authentication_rule']['state']
else:
state = True
authentication_rule_data = data['authentication_rule']
filtered_data = underscore_to_hyphen(filter_authentication_rule_data(authentication_rule_data))
if state == "present":
return fos.set('authentication',
'rule',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('authentication',
'rule',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_authentication(data, fos):
if data['authentication_rule']:
resp = authentication_rule(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"authentication_rule": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"active_auth_method": {"required": False, "type": "str"},
"comments": {"required": False, "type": "str"},
"ip_based": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"name": {"required": True, "type": "str"},
"protocol": {"required": False, "type": "str",
"choices": ["http", "ftp", "socks",
"ssh"]},
"srcaddr": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"srcaddr6": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"sso_auth_method": {"required": False, "type": "str"},
"status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"transaction_based": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"web_auth_cookie": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_authentication(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_authentication(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,423 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_authentication_scheme
short_description: Configure Authentication Schemes in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify authentication feature and scheme category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
authentication_scheme:
description:
- Configure Authentication Schemes.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
domain_controller:
description:
- Domain controller setting. Source user.domain-controller.name.
type: str
fsso_agent_for_ntlm:
description:
- FSSO agent to use for NTLM authentication. Source user.fsso.name.
type: str
fsso_guest:
description:
- Enable/disable user fsso-guest authentication .
type: str
choices:
- enable
- disable
kerberos_keytab:
description:
- Kerberos keytab setting. Source user.krb-keytab.name.
type: str
method:
description:
- Authentication methods .
type: str
choices:
- ntlm
- basic
- digest
- form
- negotiate
- fsso
- rsso
- ssh-publickey
name:
description:
- Authentication scheme name.
required: true
type: str
negotiate_ntlm:
description:
- Enable/disable negotiate authentication for NTLM .
type: str
choices:
- enable
- disable
require_tfa:
description:
- Enable/disable two-factor authentication .
type: str
choices:
- enable
- disable
ssh_ca:
description:
- SSH CA name. Source firewall.ssh.local-ca.name.
type: str
user_database:
description:
- Authentication server to contain user information; "local" (default) or "123" (for LDAP).
type: list
suboptions:
name:
description:
- Authentication server name. Source system.datasource.name user.radius.name user.tacacs+.name user.ldap.name user.group.name.
required: true
type: str
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure Authentication Schemes.
fortios_authentication_scheme:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
authentication_scheme:
domain_controller: "<your_own_value> (source user.domain-controller.name)"
fsso_agent_for_ntlm: "<your_own_value> (source user.fsso.name)"
fsso_guest: "enable"
kerberos_keytab: "<your_own_value> (source user.krb-keytab.name)"
method: "ntlm"
name: "default_name_8"
negotiate_ntlm: "enable"
require_tfa: "enable"
ssh_ca: "<your_own_value> (source firewall.ssh.local-ca.name)"
user_database:
-
name: "default_name_13 (source system.datasource.name user.radius.name user.tacacs+.name user.ldap.name user.group.name)"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_authentication_scheme_data(json):
option_list = ['domain_controller', 'fsso_agent_for_ntlm', 'fsso_guest',
'kerberos_keytab', 'method', 'name',
'negotiate_ntlm', 'require_tfa', 'ssh_ca',
'user_database']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def authentication_scheme(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['authentication_scheme'] and data['authentication_scheme']:
state = data['authentication_scheme']['state']
else:
state = True
authentication_scheme_data = data['authentication_scheme']
filtered_data = underscore_to_hyphen(filter_authentication_scheme_data(authentication_scheme_data))
if state == "present":
return fos.set('authentication',
'scheme',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('authentication',
'scheme',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_authentication(data, fos):
if data['authentication_scheme']:
resp = authentication_scheme(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"authentication_scheme": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"domain_controller": {"required": False, "type": "str"},
"fsso_agent_for_ntlm": {"required": False, "type": "str"},
"fsso_guest": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"kerberos_keytab": {"required": False, "type": "str"},
"method": {"required": False, "type": "str",
"choices": ["ntlm", "basic", "digest",
"form", "negotiate", "fsso",
"rsso", "ssh-publickey"]},
"name": {"required": True, "type": "str"},
"negotiate_ntlm": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"require_tfa": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"ssh_ca": {"required": False, "type": "str"},
"user_database": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_authentication(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_authentication(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,338 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_authentication_setting
short_description: Configure authentication setting in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify authentication feature and setting category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
authentication_setting:
description:
- Configure authentication setting.
default: null
type: dict
suboptions:
active_auth_scheme:
description:
- Active authentication method (scheme name). Source authentication.scheme.name.
type: str
captive_portal:
description:
- Captive portal host name. Source firewall.address.name.
type: str
captive_portal_ip:
description:
- Captive portal IP address.
type: str
captive_portal_ip6:
description:
- Captive portal IPv6 address.
type: str
captive_portal_port:
description:
- Captive portal port number (1 - 65535).
type: int
captive_portal_type:
description:
- Captive portal type.
type: str
choices:
- fqdn
- ip
captive_portal6:
description:
- IPv6 captive portal host name. Source firewall.address6.name.
type: str
sso_auth_scheme:
description:
- Single-Sign-On authentication method (scheme name). Source authentication.scheme.name.
type: str
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure authentication setting.
fortios_authentication_setting:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
authentication_setting:
active_auth_scheme: "<your_own_value> (source authentication.scheme.name)"
captive_portal: "<your_own_value> (source firewall.address.name)"
captive_portal_ip: "<your_own_value>"
captive_portal_ip6: "<your_own_value>"
captive_portal_port: "7"
captive_portal_type: "fqdn"
captive_portal6: "<your_own_value> (source firewall.address6.name)"
sso_auth_scheme: "<your_own_value> (source authentication.scheme.name)"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_authentication_setting_data(json):
option_list = ['active_auth_scheme', 'captive_portal', 'captive_portal_ip',
'captive_portal_ip6', 'captive_portal_port', 'captive_portal_type',
'captive_portal6', 'sso_auth_scheme']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def authentication_setting(data, fos):
vdom = data['vdom']
authentication_setting_data = data['authentication_setting']
filtered_data = underscore_to_hyphen(filter_authentication_setting_data(authentication_setting_data))
return fos.set('authentication',
'setting',
data=filtered_data,
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_authentication(data, fos):
if data['authentication_setting']:
resp = authentication_setting(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"authentication_setting": {
"required": False, "type": "dict", "default": None,
"options": {
"active_auth_scheme": {"required": False, "type": "str"},
"captive_portal": {"required": False, "type": "str"},
"captive_portal_ip": {"required": False, "type": "str"},
"captive_portal_ip6": {"required": False, "type": "str"},
"captive_portal_port": {"required": False, "type": "int"},
"captive_portal_type": {"required": False, "type": "str",
"choices": ["fqdn", "ip"]},
"captive_portal6": {"required": False, "type": "str"},
"sso_auth_scheme": {"required": False, "type": "str"}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_authentication(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_authentication(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,182 +0,0 @@
#!/usr/bin/python
#
# Ansible module to manage configuration on fortios devices
# (c) 2016, Benjamin Jolivot <bjolivot@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = """
---
module: fortios_config
version_added: "2.3"
author: "Benjamin Jolivot (@bjolivot)"
short_description: Manage config on Fortinet FortiOS firewall devices
description:
- This module provides management of FortiOS Devices configuration.
extends_documentation_fragment: fortios
options:
src:
description:
- The I(src) argument provides a path to the configuration template
to load into the remote device.
filter:
description:
- Only for partial backup, you can restrict by giving expected configuration path (ex. firewall address).
default: ""
requirements:
- pyFG
"""
EXAMPLES = """
- name: Backup current config
fortios_config:
host: 192.168.0.254
username: admin
password: password
backup: yes
- name: Backup only address objects
fortios_config:
host: 192.168.0.254
username: admin
password: password
backup: yes
backup_path: /tmp/forti_backup/
filter: "firewall address"
- name: Update configuration from file
fortios_config:
host: 192.168.0.254
username: admin
password: password
src: new_configuration.conf.j2
"""
RETURN = """
running_config:
description: full config string
returned: always
type: str
change_string:
description: The commands really executed by the module
returned: only if config changed
type: str
"""
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.network.fortios.fortios import fortios_argument_spec, fortios_required_if
from ansible.module_utils.network.fortios.fortios import backup
# check for pyFG lib
try:
from pyFG import FortiOS, FortiConfig
from pyFG.fortios import logger
from pyFG.exceptions import CommandExecutionException, FailedCommit, ForcedCommit
HAS_PYFG = True
except Exception:
HAS_PYFG = False
# some blocks don't support update, so remove them
NOT_UPDATABLE_CONFIG_OBJECTS = [
"vpn certificate local",
]
def main():
argument_spec = dict(
src=dict(type='str', default=None),
filter=dict(type='str', default=""),
)
argument_spec.update(fortios_argument_spec)
required_if = fortios_required_if
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=True,
required_if=required_if,
)
result = dict(changed=False)
# fail if pyFG not present
if not HAS_PYFG:
module.fail_json(msg='Could not import the python library pyFG required by this module')
# define device
f = FortiOS(module.params['host'],
username=module.params['username'],
password=module.params['password'],
timeout=module.params['timeout'],
vdom=module.params['vdom'])
# connect
try:
f.open()
except Exception:
module.fail_json(msg='Error connecting device')
# get config
try:
f.load_config(path=module.params['filter'])
result['running_config'] = f.running_config.to_text()
except Exception:
module.fail_json(msg='Error reading running config')
# backup config
if module.params['backup']:
backup(module, f.running_config.to_text())
# update config
if module.params['src'] is not None:
# store config in str
try:
conf_str = module.params['src']
f.load_config(in_candidate=True, config_text=conf_str)
except Exception:
module.fail_json(msg="Can't open configuration file, or configuration invalid")
# get updates lines
change_string = f.compare_config()
# remove not updatable parts
c = FortiConfig()
c.parse_config_output(change_string)
for o in NOT_UPDATABLE_CONFIG_OBJECTS:
c.del_block(o)
change_string = c.to_text()
if change_string != "":
result['change_string'] = change_string
result['changed'] = True
# Commit if not check mode
if module.check_mode is False and change_string != "":
try:
f.commit(change_string)
except CommandExecutionException as e:
module.fail_json(msg="Unable to execute command, check your args, the error was {0}".format(e.message))
except FailedCommit as e:
module.fail_json(msg="Unable to commit, check your args, the error was {0}".format(e.message))
except ForcedCommit as e:
module.fail_json(msg="Failed to force commit, check your args, the error was {0}".format(e.message))
module.exit_json(**result)
if __name__ == '__main__':
main()

@ -1,457 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_dlp_filepattern
short_description: Configure file patterns used by DLP blocking in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify dlp feature and filepattern category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
dlp_filepattern:
description:
- Configure file patterns used by DLP blocking.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
comment:
description:
- Optional comments.
type: str
entries:
description:
- Configure file patterns used by DLP blocking.
type: list
suboptions:
file_type:
description:
- Select a file type.
type: str
choices:
- 7z
- arj
- cab
- lzh
- rar
- tar
- zip
- bzip
- gzip
- bzip2
- xz
- bat
- msc
- uue
- mime
- base64
- binhex
- elf
- exe
- hta
- html
- jad
- class
- cod
- javascript
- msoffice
- msofficex
- fsg
- upx
- petite
- aspack
- sis
- hlp
- activemime
- jpeg
- gif
- tiff
- png
- bmp
- ignored
- unknown
- mpeg
- mov
- mp3
- wma
- wav
- pdf
- avi
- rm
- torrent
- hibun
- msi
- mach-o
- dmg
- .net
- xar
- chm
- iso
- crx
filter_type:
description:
- Filter by file name pattern or by file type.
type: str
choices:
- pattern
- type
pattern:
description:
- Add a file name pattern.
required: true
type: str
id:
description:
- ID.
required: true
type: int
name:
description:
- Name of table containing the file pattern list.
type: str
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure file patterns used by DLP blocking.
fortios_dlp_filepattern:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
dlp_filepattern:
comment: "Optional comments."
entries:
-
file_type: "7z"
filter_type: "pattern"
pattern: "<your_own_value>"
id: "8"
name: "default_name_9"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_dlp_filepattern_data(json):
option_list = ['comment', 'entries', 'id',
'name']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def dlp_filepattern(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['dlp_filepattern'] and data['dlp_filepattern']:
state = data['dlp_filepattern']['state']
else:
state = True
dlp_filepattern_data = data['dlp_filepattern']
filtered_data = underscore_to_hyphen(filter_dlp_filepattern_data(dlp_filepattern_data))
if state == "present":
return fos.set('dlp',
'filepattern',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('dlp',
'filepattern',
mkey=filtered_data['id'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_dlp(data, fos):
if data['dlp_filepattern']:
resp = dlp_filepattern(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"dlp_filepattern": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"comment": {"required": False, "type": "str"},
"entries": {"required": False, "type": "list",
"options": {
"file_type": {"required": False, "type": "str",
"choices": ["7z", "arj", "cab",
"lzh", "rar", "tar",
"zip", "bzip", "gzip",
"bzip2", "xz", "bat",
"msc", "uue", "mime",
"base64", "binhex", "elf",
"exe", "hta", "html",
"jad", "class", "cod",
"javascript", "msoffice", "msofficex",
"fsg", "upx", "petite",
"aspack", "sis", "hlp",
"activemime", "jpeg", "gif",
"tiff", "png", "bmp",
"ignored", "unknown", "mpeg",
"mov", "mp3", "wma",
"wav", "pdf", "avi",
"rm", "torrent", "hibun",
"msi", "mach-o", "dmg",
".net", "xar", "chm",
"iso", "crx"]},
"filter_type": {"required": False, "type": "str",
"choices": ["pattern", "type"]},
"pattern": {"required": True, "type": "str"}
}},
"id": {"required": True, "type": "int"},
"name": {"required": False, "type": "str"}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_dlp(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_dlp(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,481 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_dlp_fp_doc_source
short_description: Create a DLP fingerprint database by allowing the FortiGate to access a file server containing files from which to create fingerprints in
Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify dlp feature and fp_doc_source category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
dlp_fp_doc_source:
description:
- Create a DLP fingerprint database by allowing the FortiGate to access a file server containing files from which to create fingerprints.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
date:
description:
- Day of the month on which to scan the server (1 - 31).
type: int
file_path:
description:
- Path on the server to the fingerprint files (max 119 characters).
type: str
file_pattern:
description:
- Files matching this pattern on the server are fingerprinted. Optionally use the * and ? wildcards.
type: str
keep_modified:
description:
- Enable so that when a file is changed on the server the FortiGate keeps the old fingerprint and adds a new fingerprint to the database.
type: str
choices:
- enable
- disable
name:
description:
- Name of the DLP fingerprint database.
required: true
type: str
password:
description:
- Password required to log into the file server.
type: str
period:
description:
- Frequency for which the FortiGate checks the server for new or changed files.
type: str
choices:
- none
- daily
- weekly
- monthly
remove_deleted:
description:
- Enable to keep the fingerprint database up to date when a file is deleted from the server.
type: str
choices:
- enable
- disable
scan_on_creation:
description:
- Enable to keep the fingerprint database up to date when a file is added or changed on the server.
type: str
choices:
- enable
- disable
scan_subdirectories:
description:
- Enable/disable scanning subdirectories to find files to create fingerprints from.
type: str
choices:
- enable
- disable
sensitivity:
description:
- Select a sensitivity or threat level for matches with this fingerprint database. Add sensitivities using fp-sensitivity. Source dlp
.fp-sensitivity.name.
type: str
server:
description:
- IPv4 or IPv6 address of the server.
type: str
server_type:
description:
- Protocol used to communicate with the file server. Currently only Samba (SMB) servers are supported.
type: str
choices:
- samba
tod_hour:
description:
- Hour of the day on which to scan the server (0 - 23).
type: int
tod_min:
description:
- Minute of the hour on which to scan the server (0 - 59).
type: int
username:
description:
- User name required to log into the file server.
type: str
vdom:
description:
- Select the VDOM that can communicate with the file server.
type: str
choices:
- mgmt
- current
weekday:
description:
- Day of the week on which to scan the server.
type: str
choices:
- sunday
- monday
- tuesday
- wednesday
- thursday
- friday
- saturday
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Create a DLP fingerprint database by allowing the FortiGate to access a file server containing files from which to create fingerprints.
fortios_dlp_fp_doc_source:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
dlp_fp_doc_source:
date: "3"
file_path: "<your_own_value>"
file_pattern: "<your_own_value>"
keep_modified: "enable"
name: "default_name_7"
password: "<your_own_value>"
period: "none"
remove_deleted: "enable"
scan_on_creation: "enable"
scan_subdirectories: "enable"
sensitivity: "<your_own_value> (source dlp.fp-sensitivity.name)"
server: "192.168.100.40"
server_type: "samba"
tod_hour: "16"
tod_min: "17"
username: "<your_own_value>"
vdom: "mgmt"
weekday: "sunday"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_dlp_fp_doc_source_data(json):
option_list = ['date', 'file_path', 'file_pattern',
'keep_modified', 'name', 'password',
'period', 'remove_deleted', 'scan_on_creation',
'scan_subdirectories', 'sensitivity', 'server',
'server_type', 'tod_hour', 'tod_min',
'username', 'vdom', 'weekday']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def dlp_fp_doc_source(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['dlp_fp_doc_source'] and data['dlp_fp_doc_source']:
state = data['dlp_fp_doc_source']['state']
else:
state = True
dlp_fp_doc_source_data = data['dlp_fp_doc_source']
filtered_data = underscore_to_hyphen(filter_dlp_fp_doc_source_data(dlp_fp_doc_source_data))
if state == "present":
return fos.set('dlp',
'fp-doc-source',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('dlp',
'fp-doc-source',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_dlp(data, fos):
if data['dlp_fp_doc_source']:
resp = dlp_fp_doc_source(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"dlp_fp_doc_source": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"date": {"required": False, "type": "int"},
"file_path": {"required": False, "type": "str"},
"file_pattern": {"required": False, "type": "str"},
"keep_modified": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"name": {"required": True, "type": "str"},
"password": {"required": False, "type": "str"},
"period": {"required": False, "type": "str",
"choices": ["none", "daily", "weekly",
"monthly"]},
"remove_deleted": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"scan_on_creation": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"scan_subdirectories": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"sensitivity": {"required": False, "type": "str"},
"server": {"required": False, "type": "str"},
"server_type": {"required": False, "type": "str",
"choices": ["samba"]},
"tod_hour": {"required": False, "type": "int"},
"tod_min": {"required": False, "type": "int"},
"username": {"required": False, "type": "str"},
"vdom": {"required": False, "type": "str",
"choices": ["mgmt", "current"]},
"weekday": {"required": False, "type": "str",
"choices": ["sunday", "monday", "tuesday",
"wednesday", "thursday", "friday",
"saturday"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_dlp(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_dlp(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,332 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_dlp_fp_sensitivity
short_description: Create self-explanatory DLP sensitivity levels to be used when setting sensitivity under config fp-doc-source in Fortinet's FortiOS and
FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify dlp feature and fp_sensitivity category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
dlp_fp_sensitivity:
description:
- Create self-explanatory DLP sensitivity levels to be used when setting sensitivity under config fp-doc-source.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
name:
description:
- DLP Sensitivity Levels.
required: true
type: str
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Create self-explanatory DLP sensitivity levels to be used when setting sensitivity under config fp-doc-source.
fortios_dlp_fp_sensitivity:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
dlp_fp_sensitivity:
name: "default_name_3"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_dlp_fp_sensitivity_data(json):
option_list = ['name']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def dlp_fp_sensitivity(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['dlp_fp_sensitivity'] and data['dlp_fp_sensitivity']:
state = data['dlp_fp_sensitivity']['state']
else:
state = True
dlp_fp_sensitivity_data = data['dlp_fp_sensitivity']
filtered_data = underscore_to_hyphen(filter_dlp_fp_sensitivity_data(dlp_fp_sensitivity_data))
if state == "present":
return fos.set('dlp',
'fp-sensitivity',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('dlp',
'fp-sensitivity',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_dlp(data, fos):
if data['dlp_fp_sensitivity']:
resp = dlp_fp_sensitivity(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"dlp_fp_sensitivity": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"name": {"required": True, "type": "str"}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_dlp(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_dlp(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,602 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_dlp_sensor
short_description: Configure DLP sensors in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify dlp feature and sensor category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
dlp_sensor:
description:
- Configure DLP sensors.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
comment:
description:
- Comment.
type: str
dlp_log:
description:
- Enable/disable DLP logging.
type: str
choices:
- enable
- disable
extended_log:
description:
- Enable/disable extended logging for data leak prevention.
type: str
choices:
- enable
- disable
filter:
description:
- Set up DLP filters for this sensor.
type: list
suboptions:
action:
description:
- Action to take with content that this DLP sensor matches.
type: str
choices:
- allow
- log-only
- block
- quarantine-ip
archive:
description:
- Enable/disable DLP archiving.
type: str
choices:
- disable
- enable
company_identifier:
description:
- Enter a company identifier watermark to match. Only watermarks that your company has placed on the files are matched.
type: str
expiry:
description:
- Quarantine duration in days, hours, minutes format (dddhhmm).
type: str
file_size:
description:
- Match files this size or larger (0 - 4294967295 kbytes).
type: int
file_type:
description:
- Select the number of a DLP file pattern table to match. Source dlp.filepattern.id.
type: int
filter_by:
description:
- Select the type of content to match.
type: str
choices:
- credit-card
- ssn
- regexp
- file-type
- file-size
- fingerprint
- watermark
- encrypted
fp_sensitivity:
description:
- Select a DLP file pattern sensitivity to match.
type: list
suboptions:
name:
description:
- Select a DLP sensitivity. Source dlp.fp-sensitivity.name.
required: true
type: str
id:
description:
- ID.
required: true
type: int
match_percentage:
description:
- Percentage of fingerprints in the fingerprint databases designated with the selected fp-sensitivity to match.
type: int
name:
description:
- Filter name.
type: str
proto:
description:
- Check messages or files over one or more of these protocols.
type: str
choices:
- smtp
- pop3
- imap
- http-get
- http-post
- ftp
- nntp
- mapi
- mm1
- mm3
- mm4
- mm7
regexp:
description:
- Enter a regular expression to match (max. 255 characters).
type: str
severity:
description:
- Select the severity or threat level that matches this filter.
type: str
choices:
- info
- low
- medium
- high
- critical
type:
description:
- Select whether to check the content of messages (an email message) or files (downloaded files or email attachments).
type: str
choices:
- file
- message
flow_based:
description:
- Enable/disable flow-based DLP.
type: str
choices:
- enable
- disable
full_archive_proto:
description:
- Protocols to always content archive.
type: str
choices:
- smtp
- pop3
- imap
- http-get
- http-post
- ftp
- nntp
- mapi
- mm1
- mm3
- mm4
- mm7
nac_quar_log:
description:
- Enable/disable NAC quarantine logging.
type: str
choices:
- enable
- disable
name:
description:
- Name of the DLP sensor.
required: true
type: str
options:
description:
- Configure DLP options.
type: str
replacemsg_group:
description:
- Replacement message group used by this DLP sensor. Source system.replacemsg-group.name.
type: str
summary_proto:
description:
- Protocols to always log summary.
type: str
choices:
- smtp
- pop3
- imap
- http-get
- http-post
- ftp
- nntp
- mapi
- mm1
- mm3
- mm4
- mm7
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure DLP sensors.
fortios_dlp_sensor:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
dlp_sensor:
comment: "Comment."
dlp_log: "enable"
extended_log: "enable"
filter:
-
action: "allow"
archive: "disable"
company_identifier: "myId_9"
expiry: "<your_own_value>"
file_size: "11"
file_type: "12 (source dlp.filepattern.id)"
filter_by: "credit-card"
fp_sensitivity:
-
name: "default_name_15 (source dlp.fp-sensitivity.name)"
id: "16"
match_percentage: "17"
name: "default_name_18"
proto: "smtp"
regexp: "<your_own_value>"
severity: "info"
type: "file"
flow_based: "enable"
full_archive_proto: "smtp"
nac_quar_log: "enable"
name: "default_name_26"
options: "<your_own_value>"
replacemsg_group: "<your_own_value> (source system.replacemsg-group.name)"
summary_proto: "smtp"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_dlp_sensor_data(json):
option_list = ['comment', 'dlp_log', 'extended_log',
'filter', 'flow_based', 'full_archive_proto',
'nac_quar_log', 'name', 'options',
'replacemsg_group', 'summary_proto']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def dlp_sensor(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['dlp_sensor'] and data['dlp_sensor']:
state = data['dlp_sensor']['state']
else:
state = True
dlp_sensor_data = data['dlp_sensor']
filtered_data = underscore_to_hyphen(filter_dlp_sensor_data(dlp_sensor_data))
if state == "present":
return fos.set('dlp',
'sensor',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('dlp',
'sensor',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_dlp(data, fos):
if data['dlp_sensor']:
resp = dlp_sensor(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"dlp_sensor": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"comment": {"required": False, "type": "str"},
"dlp_log": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"extended_log": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"filter": {"required": False, "type": "list",
"options": {
"action": {"required": False, "type": "str",
"choices": ["allow", "log-only", "block",
"quarantine-ip"]},
"archive": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"company_identifier": {"required": False, "type": "str"},
"expiry": {"required": False, "type": "str"},
"file_size": {"required": False, "type": "int"},
"file_type": {"required": False, "type": "int"},
"filter_by": {"required": False, "type": "str",
"choices": ["credit-card", "ssn", "regexp",
"file-type", "file-size", "fingerprint",
"watermark", "encrypted"]},
"fp_sensitivity": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"id": {"required": True, "type": "int"},
"match_percentage": {"required": False, "type": "int"},
"name": {"required": False, "type": "str"},
"proto": {"required": False, "type": "str",
"choices": ["smtp", "pop3", "imap",
"http-get", "http-post", "ftp",
"nntp", "mapi", "mm1",
"mm3", "mm4", "mm7"]},
"regexp": {"required": False, "type": "str"},
"severity": {"required": False, "type": "str",
"choices": ["info", "low", "medium",
"high", "critical"]},
"type": {"required": False, "type": "str",
"choices": ["file", "message"]}
}},
"flow_based": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"full_archive_proto": {"required": False, "type": "str",
"choices": ["smtp", "pop3", "imap",
"http-get", "http-post", "ftp",
"nntp", "mapi", "mm1",
"mm3", "mm4", "mm7"]},
"nac_quar_log": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"name": {"required": True, "type": "str"},
"options": {"required": False, "type": "str"},
"replacemsg_group": {"required": False, "type": "str"},
"summary_proto": {"required": False, "type": "str",
"choices": ["smtp", "pop3", "imap",
"http-get", "http-post", "ftp",
"nntp", "mapi", "mm1",
"mm3", "mm4", "mm7"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_dlp(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_dlp(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,320 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_dlp_settings
short_description: Designate logical storage for DLP fingerprint database in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify dlp feature and settings category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
dlp_settings:
description:
- Designate logical storage for DLP fingerprint database.
default: null
type: dict
suboptions:
cache_mem_percent:
description:
- Maximum percentage of available memory allocated to caching (1 - 15%).
type: int
chunk_size:
description:
- Maximum fingerprint chunk size. **Changing will flush the entire database**.
type: int
db_mode:
description:
- Behaviour when the maximum size is reached.
type: str
choices:
- stop-adding
- remove-modified-then-oldest
- remove-oldest
size:
description:
- Maximum total size of files within the storage (MB).
type: int
storage_device:
description:
- Storage device name. Source system.storage.name.
type: str
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Designate logical storage for DLP fingerprint database.
fortios_dlp_settings:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
dlp_settings:
cache_mem_percent: "3"
chunk_size: "4"
db_mode: "stop-adding"
size: "6"
storage_device: "<your_own_value> (source system.storage.name)"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_dlp_settings_data(json):
option_list = ['cache_mem_percent', 'chunk_size', 'db_mode',
'size', 'storage_device']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def dlp_settings(data, fos):
vdom = data['vdom']
dlp_settings_data = data['dlp_settings']
filtered_data = underscore_to_hyphen(filter_dlp_settings_data(dlp_settings_data))
return fos.set('dlp',
'settings',
data=filtered_data,
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_dlp(data, fos):
if data['dlp_settings']:
resp = dlp_settings(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"dlp_settings": {
"required": False, "type": "dict", "default": None,
"options": {
"cache_mem_percent": {"required": False, "type": "int"},
"chunk_size": {"required": False, "type": "int"},
"db_mode": {"required": False, "type": "str",
"choices": ["stop-adding", "remove-modified-then-oldest", "remove-oldest"]},
"size": {"required": False, "type": "int"},
"storage_device": {"required": False, "type": "str"}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_dlp(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_dlp(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,399 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_dnsfilter_domain_filter
short_description: Configure DNS domain filters in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify dnsfilter feature and domain_filter category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
dnsfilter_domain_filter:
description:
- Configure DNS domain filters.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
comment:
description:
- Optional comments.
type: str
entries:
description:
- DNS domain filter entries.
type: list
suboptions:
action:
description:
- Action to take for domain filter matches.
type: str
choices:
- block
- allow
- monitor
domain:
description:
- Domain entries to be filtered.
type: str
id:
description:
- Id.
required: true
type: int
status:
description:
- Enable/disable this domain filter.
type: str
choices:
- enable
- disable
type:
description:
- DNS domain filter type.
type: str
choices:
- simple
- regex
- wildcard
id:
description:
- ID.
required: true
type: int
name:
description:
- Name of table.
type: str
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure DNS domain filters.
fortios_dnsfilter_domain_filter:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
dnsfilter_domain_filter:
comment: "Optional comments."
entries:
-
action: "block"
domain: "<your_own_value>"
id: "7"
status: "enable"
type: "simple"
id: "10"
name: "default_name_11"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_dnsfilter_domain_filter_data(json):
option_list = ['comment', 'entries', 'id',
'name']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def dnsfilter_domain_filter(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['dnsfilter_domain_filter'] and data['dnsfilter_domain_filter']:
state = data['dnsfilter_domain_filter']['state']
else:
state = True
dnsfilter_domain_filter_data = data['dnsfilter_domain_filter']
filtered_data = underscore_to_hyphen(filter_dnsfilter_domain_filter_data(dnsfilter_domain_filter_data))
if state == "present":
return fos.set('dnsfilter',
'domain-filter',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('dnsfilter',
'domain-filter',
mkey=filtered_data['id'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_dnsfilter(data, fos):
if data['dnsfilter_domain_filter']:
resp = dnsfilter_domain_filter(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"dnsfilter_domain_filter": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"comment": {"required": False, "type": "str"},
"entries": {"required": False, "type": "list",
"options": {
"action": {"required": False, "type": "str",
"choices": ["block", "allow", "monitor"]},
"domain": {"required": False, "type": "str"},
"id": {"required": True, "type": "int"},
"status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"type": {"required": False, "type": "str",
"choices": ["simple", "regex", "wildcard"]}
}},
"id": {"required": True, "type": "int"},
"name": {"required": False, "type": "str"}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_dnsfilter(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_dnsfilter(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,511 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_dnsfilter_profile
short_description: Configure DNS domain filter profiles in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify dnsfilter feature and profile category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
dnsfilter_profile:
description:
- Configure DNS domain filter profiles.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
block_action:
description:
- Action to take for blocked domains.
type: str
choices:
- block
- redirect
block_botnet:
description:
- Enable/disable blocking botnet C&C DNS lookups.
type: str
choices:
- disable
- enable
comment:
description:
- Comment.
type: str
domain_filter:
description:
- Domain filter settings.
type: dict
suboptions:
domain_filter_table:
description:
- DNS domain filter table ID. Source dnsfilter.domain-filter.id.
type: int
external_ip_blocklist:
description:
- One or more external IP block lists.
type: list
suboptions:
name:
description:
- External domain block list name. Source system.external-resource.name.
required: true
type: str
ftgd_dns:
description:
- FortiGuard DNS Filter settings.
type: dict
suboptions:
filters:
description:
- FortiGuard DNS domain filters.
type: list
suboptions:
action:
description:
- Action to take for DNS requests matching the category.
type: str
choices:
- block
- monitor
category:
description:
- Category number.
type: int
id:
description:
- ID number.
required: true
type: int
log:
description:
- Enable/disable DNS filter logging for this DNS profile.
type: str
choices:
- enable
- disable
options:
description:
- FortiGuard DNS filter options.
type: str
choices:
- error-allow
- ftgd-disable
log_all_domain:
description:
- Enable/disable logging of all domains visited (detailed DNS logging).
type: str
choices:
- enable
- disable
name:
description:
- Profile name.
required: true
type: str
redirect_portal:
description:
- IP address of the SDNS redirect portal.
type: str
safe_search:
description:
- Enable/disable Google, Bing, and YouTube safe search.
type: str
choices:
- disable
- enable
sdns_domain_log:
description:
- Enable/disable domain filtering and botnet domain logging.
type: str
choices:
- enable
- disable
sdns_ftgd_err_log:
description:
- Enable/disable FortiGuard SDNS rating error logging.
type: str
choices:
- enable
- disable
youtube_restrict:
description:
- Set safe search for YouTube restriction level.
type: str
choices:
- strict
- moderate
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure DNS domain filter profiles.
fortios_dnsfilter_profile:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
dnsfilter_profile:
block_action: "block"
block_botnet: "disable"
comment: "Comment."
domain_filter:
domain_filter_table: "7 (source dnsfilter.domain-filter.id)"
external_ip_blocklist:
-
name: "default_name_9 (source system.external-resource.name)"
ftgd_dns:
filters:
-
action: "block"
category: "13"
id: "14"
log: "enable"
options: "error-allow"
log_all_domain: "enable"
name: "default_name_18"
redirect_portal: "<your_own_value>"
safe_search: "disable"
sdns_domain_log: "enable"
sdns_ftgd_err_log: "enable"
youtube_restrict: "strict"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_dnsfilter_profile_data(json):
option_list = ['block_action', 'block_botnet', 'comment',
'domain_filter', 'external_ip_blocklist', 'ftgd_dns',
'log_all_domain', 'name', 'redirect_portal',
'safe_search', 'sdns_domain_log', 'sdns_ftgd_err_log',
'youtube_restrict']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def dnsfilter_profile(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['dnsfilter_profile'] and data['dnsfilter_profile']:
state = data['dnsfilter_profile']['state']
else:
state = True
dnsfilter_profile_data = data['dnsfilter_profile']
filtered_data = underscore_to_hyphen(filter_dnsfilter_profile_data(dnsfilter_profile_data))
if state == "present":
return fos.set('dnsfilter',
'profile',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('dnsfilter',
'profile',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_dnsfilter(data, fos):
if data['dnsfilter_profile']:
resp = dnsfilter_profile(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"dnsfilter_profile": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"block_action": {"required": False, "type": "str",
"choices": ["block", "redirect"]},
"block_botnet": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"comment": {"required": False, "type": "str"},
"domain_filter": {"required": False, "type": "dict",
"options": {
"domain_filter_table": {"required": False, "type": "int"}
}},
"external_ip_blocklist": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"ftgd_dns": {"required": False, "type": "dict",
"options": {
"filters": {"required": False, "type": "list",
"options": {
"action": {"required": False, "type": "str",
"choices": ["block", "monitor"]},
"category": {"required": False, "type": "int"},
"id": {"required": True, "type": "int"},
"log": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}},
"options": {"required": False, "type": "str",
"choices": ["error-allow", "ftgd-disable"]}
}},
"log_all_domain": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"name": {"required": True, "type": "str"},
"redirect_portal": {"required": False, "type": "str"},
"safe_search": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"sdns_domain_log": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"sdns_ftgd_err_log": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"youtube_restrict": {"required": False, "type": "str",
"choices": ["strict", "moderate"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_dnsfilter(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_dnsfilter(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,362 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_endpoint_control_client
short_description: Configure endpoint control client lists in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify endpoint_control feature and client category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
endpoint_control_client:
description:
- Configure endpoint control client lists.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
ad_groups:
description:
- Endpoint client AD logon groups.
type: str
ftcl_uid:
description:
- Endpoint FortiClient UID.
type: str
id:
description:
- Endpoint client ID.
required: true
type: int
info:
description:
- Endpoint client information.
type: str
src_ip:
description:
- Endpoint client IP address.
type: str
src_mac:
description:
- Endpoint client MAC address.
type: str
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure endpoint control client lists.
fortios_endpoint_control_client:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
endpoint_control_client:
ad_groups: "<your_own_value>"
ftcl_uid: "<your_own_value>"
id: "5"
info: "<your_own_value>"
src_ip: "<your_own_value>"
src_mac: "<your_own_value>"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_endpoint_control_client_data(json):
option_list = ['ad_groups', 'ftcl_uid', 'id',
'info', 'src_ip', 'src_mac']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def endpoint_control_client(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['endpoint_control_client'] and data['endpoint_control_client']:
state = data['endpoint_control_client']['state']
else:
state = True
endpoint_control_client_data = data['endpoint_control_client']
filtered_data = underscore_to_hyphen(filter_endpoint_control_client_data(endpoint_control_client_data))
if state == "present":
return fos.set('endpoint-control',
'client',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('endpoint-control',
'client',
mkey=filtered_data['id'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_endpoint_control(data, fos):
if data['endpoint_control_client']:
resp = endpoint_control_client(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"endpoint_control_client": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"ad_groups": {"required": False, "type": "str"},
"ftcl_uid": {"required": False, "type": "str"},
"id": {"required": True, "type": "int"},
"info": {"required": False, "type": "str"},
"src_ip": {"required": False, "type": "str"},
"src_mac": {"required": False, "type": "str"}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_endpoint_control(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_endpoint_control(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,396 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_endpoint_control_forticlient_ems
short_description: Configure FortiClient Enterprise Management Server (EMS) entries in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify endpoint_control feature and forticlient_ems category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
endpoint_control_forticlient_ems:
description:
- Configure FortiClient Enterprise Management Server (EMS) entries.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
address:
description:
- Firewall address name. Source firewall.address.name.
type: str
admin_password:
description:
- FortiClient EMS admin password.
type: str
admin_type:
description:
- FortiClient EMS admin type.
type: str
choices:
- Windows
- LDAP
admin_username:
description:
- FortiClient EMS admin username.
type: str
https_port:
description:
- "FortiClient EMS HTTPS access port number. (1 - 65535)."
type: int
listen_port:
description:
- "FortiClient EMS telemetry listen port number. (1 - 65535)."
type: int
name:
description:
- FortiClient Enterprise Management Server (EMS) name.
required: true
type: str
rest_api_auth:
description:
- FortiClient EMS REST API authentication.
type: str
choices:
- disable
- userpass
serial_number:
description:
- FortiClient EMS Serial Number.
type: str
upload_port:
description:
- "FortiClient EMS telemetry upload port number. (1 - 65535)."
type: int
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure FortiClient Enterprise Management Server (EMS) entries.
fortios_endpoint_control_forticlient_ems:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
endpoint_control_forticlient_ems:
address: "<your_own_value> (source firewall.address.name)"
admin_password: "<your_own_value>"
admin_type: "Windows"
admin_username: "<your_own_value>"
https_port: "7"
listen_port: "8"
name: "default_name_9"
rest_api_auth: "disable"
serial_number: "<your_own_value>"
upload_port: "12"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_endpoint_control_forticlient_ems_data(json):
option_list = ['address', 'admin_password', 'admin_type',
'admin_username', 'https_port', 'listen_port',
'name', 'rest_api_auth', 'serial_number',
'upload_port']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def endpoint_control_forticlient_ems(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['endpoint_control_forticlient_ems'] and data['endpoint_control_forticlient_ems']:
state = data['endpoint_control_forticlient_ems']['state']
else:
state = True
endpoint_control_forticlient_ems_data = data['endpoint_control_forticlient_ems']
filtered_data = underscore_to_hyphen(filter_endpoint_control_forticlient_ems_data(endpoint_control_forticlient_ems_data))
if state == "present":
return fos.set('endpoint-control',
'forticlient-ems',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('endpoint-control',
'forticlient-ems',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_endpoint_control(data, fos):
if data['endpoint_control_forticlient_ems']:
resp = endpoint_control_forticlient_ems(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"endpoint_control_forticlient_ems": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"address": {"required": False, "type": "str"},
"admin_password": {"required": False, "type": "str"},
"admin_type": {"required": False, "type": "str",
"choices": ["Windows", "LDAP"]},
"admin_username": {"required": False, "type": "str"},
"https_port": {"required": False, "type": "int"},
"listen_port": {"required": False, "type": "int"},
"name": {"required": True, "type": "str"},
"rest_api_auth": {"required": False, "type": "str",
"choices": ["disable", "userpass"]},
"serial_number": {"required": False, "type": "str"},
"upload_port": {"required": False, "type": "int"}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_endpoint_control(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_endpoint_control(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,336 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_endpoint_control_forticlient_registration_sync
short_description: Configure FortiClient registration synchronization settings in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify endpoint_control feature and forticlient_registration_sync category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
endpoint_control_forticlient_registration_sync:
description:
- Configure FortiClient registration synchronization settings.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
peer_ip:
description:
- IP address of the peer FortiGate for endpoint license synchronization.
type: str
peer_name:
description:
- Peer name.
type: str
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure FortiClient registration synchronization settings.
fortios_endpoint_control_forticlient_registration_sync:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
endpoint_control_forticlient_registration_sync:
peer_ip: "<your_own_value>"
peer_name: "<your_own_value>"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_endpoint_control_forticlient_registration_sync_data(json):
option_list = ['peer_ip', 'peer_name']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def endpoint_control_forticlient_registration_sync(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['endpoint_control_forticlient_registration_sync'] and data['endpoint_control_forticlient_registration_sync']:
state = data['endpoint_control_forticlient_registration_sync']['state']
else:
state = True
endpoint_control_forticlient_registration_sync_data = data['endpoint_control_forticlient_registration_sync']
filtered_data = underscore_to_hyphen(filter_endpoint_control_forticlient_registration_sync_data(endpoint_control_forticlient_registration_sync_data))
if state == "present":
return fos.set('endpoint-control',
'forticlient-registration-sync',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('endpoint-control',
'forticlient-registration-sync',
mkey=filtered_data['peer-name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_endpoint_control(data, fos):
if data['endpoint_control_forticlient_registration_sync']:
resp = endpoint_control_forticlient_registration_sync(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"endpoint_control_forticlient_registration_sync": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"peer_ip": {"required": False, "type": "str"},
"peer_name": {"required": False, "type": "str"}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_endpoint_control(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_endpoint_control(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,392 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_endpoint_control_settings
short_description: Configure endpoint control settings in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify endpoint_control feature and settings category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
endpoint_control_settings:
description:
- Configure endpoint control settings.
default: null
type: dict
suboptions:
download_custom_link:
description:
- Customized URL for downloading FortiClient.
type: str
download_location:
description:
- FortiClient download location (FortiGuard or custom).
type: str
choices:
- fortiguard
- custom
forticlient_avdb_update_interval:
description:
- Period of time between FortiClient AntiVirus database updates (0 - 24 hours).
type: int
forticlient_dereg_unsupported_client:
description:
- Enable/disable deregistering unsupported FortiClient endpoints.
type: str
choices:
- enable
- disable
forticlient_ems_rest_api_call_timeout:
description:
- FortiClient EMS call timeout in milliseconds (500 - 30000 milliseconds).
type: int
forticlient_keepalive_interval:
description:
- Interval between two KeepAlive messages from FortiClient (20 - 300 sec).
type: int
forticlient_offline_grace:
description:
- Enable/disable grace period for offline registered clients.
type: str
choices:
- enable
- disable
forticlient_offline_grace_interval:
description:
- Grace period for offline registered FortiClient (60 - 600 sec).
type: int
forticlient_reg_key:
description:
- FortiClient registration key.
type: str
forticlient_reg_key_enforce:
description:
- Enable/disable requiring or enforcing FortiClient registration keys.
type: str
choices:
- enable
- disable
forticlient_reg_timeout:
description:
- FortiClient registration license timeout (days, min = 1, max = 180, 0 means unlimited).
type: int
forticlient_sys_update_interval:
description:
- Interval between two system update messages from FortiClient (30 - 1440 min).
type: int
forticlient_user_avatar:
description:
- Enable/disable uploading FortiClient user avatars.
type: str
choices:
- enable
- disable
forticlient_warning_interval:
description:
- Period of time between FortiClient portal warnings (0 - 24 hours).
type: int
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure endpoint control settings.
fortios_endpoint_control_settings:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
endpoint_control_settings:
download_custom_link: "<your_own_value>"
download_location: "fortiguard"
forticlient_avdb_update_interval: "5"
forticlient_dereg_unsupported_client: "enable"
forticlient_ems_rest_api_call_timeout: "7"
forticlient_keepalive_interval: "8"
forticlient_offline_grace: "enable"
forticlient_offline_grace_interval: "10"
forticlient_reg_key: "<your_own_value>"
forticlient_reg_key_enforce: "enable"
forticlient_reg_timeout: "13"
forticlient_sys_update_interval: "14"
forticlient_user_avatar: "enable"
forticlient_warning_interval: "16"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_endpoint_control_settings_data(json):
option_list = ['download_custom_link', 'download_location', 'forticlient_avdb_update_interval',
'forticlient_dereg_unsupported_client', 'forticlient_ems_rest_api_call_timeout', 'forticlient_keepalive_interval',
'forticlient_offline_grace', 'forticlient_offline_grace_interval', 'forticlient_reg_key',
'forticlient_reg_key_enforce', 'forticlient_reg_timeout', 'forticlient_sys_update_interval',
'forticlient_user_avatar', 'forticlient_warning_interval']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def endpoint_control_settings(data, fos):
vdom = data['vdom']
endpoint_control_settings_data = data['endpoint_control_settings']
filtered_data = underscore_to_hyphen(filter_endpoint_control_settings_data(endpoint_control_settings_data))
return fos.set('endpoint-control',
'settings',
data=filtered_data,
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_endpoint_control(data, fos):
if data['endpoint_control_settings']:
resp = endpoint_control_settings(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"endpoint_control_settings": {
"required": False, "type": "dict", "default": None,
"options": {
"download_custom_link": {"required": False, "type": "str"},
"download_location": {"required": False, "type": "str",
"choices": ["fortiguard", "custom"]},
"forticlient_avdb_update_interval": {"required": False, "type": "int"},
"forticlient_dereg_unsupported_client": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"forticlient_ems_rest_api_call_timeout": {"required": False, "type": "int"},
"forticlient_keepalive_interval": {"required": False, "type": "int"},
"forticlient_offline_grace": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"forticlient_offline_grace_interval": {"required": False, "type": "int"},
"forticlient_reg_key": {"required": False, "type": "str"},
"forticlient_reg_key_enforce": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"forticlient_reg_timeout": {"required": False, "type": "int"},
"forticlient_sys_update_interval": {"required": False, "type": "int"},
"forticlient_user_avatar": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"forticlient_warning_interval": {"required": False, "type": "int"}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_endpoint_control(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_endpoint_control(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,627 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_extender_controller_extender
short_description: Extender controller configuration in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify extender_controller feature and extender category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
extender_controller_extender:
description:
- Extender controller configuration.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
aaa_shared_secret:
description:
- AAA shared secret.
type: str
access_point_name:
description:
- Access point name(APN).
type: str
admin:
description:
- FortiExtender Administration (enable or disable).
type: str
choices:
- disable
- discovered
- enable
at_dial_script:
description:
- Initialization AT commands specific to the MODEM.
type: str
billing_start_day:
description:
- Billing start day.
type: int
cdma_aaa_spi:
description:
- CDMA AAA SPI.
type: str
cdma_ha_spi:
description:
- CDMA HA SPI.
type: str
cdma_nai:
description:
- NAI for CDMA MODEMS.
type: str
conn_status:
description:
- Connection status.
type: int
description:
description:
- Description.
type: str
dial_mode:
description:
- Dial mode (dial-on-demand or always-connect).
type: str
choices:
- dial-on-demand
- always-connect
dial_status:
description:
- Dial status.
type: int
ext_name:
description:
- FortiExtender name.
type: str
ha_shared_secret:
description:
- HA shared secret.
type: str
id:
description:
- FortiExtender serial number.
required: true
type: str
ifname:
description:
- FortiExtender interface name.
type: str
initiated_update:
description:
- Allow/disallow network initiated updates to the MODEM.
type: str
choices:
- enable
- disable
mode:
description:
- FortiExtender mode.
type: str
choices:
- standalone
- redundant
modem_passwd:
description:
- MODEM password.
type: str
modem_type:
description:
- MODEM type (CDMA, GSM/LTE or WIMAX).
type: str
choices:
- cdma
- gsm/lte
- wimax
multi_mode:
description:
- MODEM mode of operation(3G,LTE,etc).
type: str
choices:
- auto
- auto-3g
- force-lte
- force-3g
- force-2g
ppp_auth_protocol:
description:
- PPP authentication protocol (PAP,CHAP or auto).
type: str
choices:
- auto
- pap
- chap
ppp_echo_request:
description:
- Enable/disable PPP echo request.
type: str
choices:
- enable
- disable
ppp_password:
description:
- PPP password.
type: str
ppp_username:
description:
- PPP username.
type: str
primary_ha:
description:
- Primary HA.
type: str
quota_limit_mb:
description:
- Monthly quota limit (MB).
type: int
redial:
description:
- Number of redials allowed based on failed attempts.
type: str
choices:
- none
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
redundant_intf:
description:
- Redundant interface.
type: str
roaming:
description:
- Enable/disable MODEM roaming.
type: str
choices:
- enable
- disable
role:
description:
- FortiExtender work role(Primary, Secondary, None).
type: str
choices:
- none
- primary
- secondary
secondary_ha:
description:
- Secondary HA.
type: str
sim_pin:
description:
- SIM PIN.
type: str
vdom:
description:
- VDOM
type: int
wimax_auth_protocol:
description:
- WiMax authentication protocol(TLS or TTLS).
type: str
choices:
- tls
- ttls
wimax_carrier:
description:
- WiMax carrier.
type: str
wimax_realm:
description:
- WiMax realm.
type: str
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Extender controller configuration.
fortios_extender_controller_extender:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
extender_controller_extender:
aaa_shared_secret: "<your_own_value>"
access_point_name: "<your_own_value>"
admin: "disable"
at_dial_script: "<your_own_value>"
billing_start_day: "7"
cdma_aaa_spi: "<your_own_value>"
cdma_ha_spi: "<your_own_value>"
cdma_nai: "<your_own_value>"
conn_status: "11"
description: "<your_own_value>"
dial_mode: "dial-on-demand"
dial_status: "14"
ext_name: "<your_own_value>"
ha_shared_secret: "<your_own_value>"
id: "17"
ifname: "<your_own_value>"
initiated_update: "enable"
mode: "standalone"
modem_passwd: "<your_own_value>"
modem_type: "cdma"
multi_mode: "auto"
ppp_auth_protocol: "auto"
ppp_echo_request: "enable"
ppp_password: "<your_own_value>"
ppp_username: "<your_own_value>"
primary_ha: "<your_own_value>"
quota_limit_mb: "29"
redial: "none"
redundant_intf: "<your_own_value>"
roaming: "enable"
role: "none"
secondary_ha: "<your_own_value>"
sim_pin: "<your_own_value>"
vdom: "36"
wimax_auth_protocol: "tls"
wimax_carrier: "<your_own_value>"
wimax_realm: "<your_own_value>"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_extender_controller_extender_data(json):
option_list = ['aaa_shared_secret', 'access_point_name', 'admin',
'at_dial_script', 'billing_start_day', 'cdma_aaa_spi',
'cdma_ha_spi', 'cdma_nai', 'conn_status',
'description', 'dial_mode', 'dial_status',
'ext_name', 'ha_shared_secret', 'id',
'ifname', 'initiated_update', 'mode',
'modem_passwd', 'modem_type', 'multi_mode',
'ppp_auth_protocol', 'ppp_echo_request', 'ppp_password',
'ppp_username', 'primary_ha', 'quota_limit_mb',
'redial', 'redundant_intf', 'roaming',
'role', 'secondary_ha', 'sim_pin',
'vdom', 'wimax_auth_protocol', 'wimax_carrier',
'wimax_realm']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def extender_controller_extender(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['extender_controller_extender'] and data['extender_controller_extender']:
state = data['extender_controller_extender']['state']
else:
state = True
extender_controller_extender_data = data['extender_controller_extender']
filtered_data = underscore_to_hyphen(filter_extender_controller_extender_data(extender_controller_extender_data))
if state == "present":
return fos.set('extender-controller',
'extender',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('extender-controller',
'extender',
mkey=filtered_data['id'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_extender_controller(data, fos):
if data['extender_controller_extender']:
resp = extender_controller_extender(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"extender_controller_extender": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"aaa_shared_secret": {"required": False, "type": "str"},
"access_point_name": {"required": False, "type": "str"},
"admin": {"required": False, "type": "str",
"choices": ["disable", "discovered", "enable"]},
"at_dial_script": {"required": False, "type": "str"},
"billing_start_day": {"required": False, "type": "int"},
"cdma_aaa_spi": {"required": False, "type": "str"},
"cdma_ha_spi": {"required": False, "type": "str"},
"cdma_nai": {"required": False, "type": "str"},
"conn_status": {"required": False, "type": "int"},
"description": {"required": False, "type": "str"},
"dial_mode": {"required": False, "type": "str",
"choices": ["dial-on-demand", "always-connect"]},
"dial_status": {"required": False, "type": "int"},
"ext_name": {"required": False, "type": "str"},
"ha_shared_secret": {"required": False, "type": "str"},
"id": {"required": True, "type": "str"},
"ifname": {"required": False, "type": "str"},
"initiated_update": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"mode": {"required": False, "type": "str",
"choices": ["standalone", "redundant"]},
"modem_passwd": {"required": False, "type": "str"},
"modem_type": {"required": False, "type": "str",
"choices": ["cdma", "gsm/lte", "wimax"]},
"multi_mode": {"required": False, "type": "str",
"choices": ["auto", "auto-3g", "force-lte",
"force-3g", "force-2g"]},
"ppp_auth_protocol": {"required": False, "type": "str",
"choices": ["auto", "pap", "chap"]},
"ppp_echo_request": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"ppp_password": {"required": False, "type": "str"},
"ppp_username": {"required": False, "type": "str"},
"primary_ha": {"required": False, "type": "str"},
"quota_limit_mb": {"required": False, "type": "int"},
"redial": {"required": False, "type": "str",
"choices": ["none", "1", "2",
"3", "4", "5",
"6", "7", "8",
"9", "10"]},
"redundant_intf": {"required": False, "type": "str"},
"roaming": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"role": {"required": False, "type": "str",
"choices": ["none", "primary", "secondary"]},
"secondary_ha": {"required": False, "type": "str"},
"sim_pin": {"required": False, "type": "str"},
"vdom": {"required": False, "type": "int"},
"wimax_auth_protocol": {"required": False, "type": "str",
"choices": ["tls", "ttls"]},
"wimax_carrier": {"required": False, "type": "str"},
"wimax_realm": {"required": False, "type": "str"}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_extender_controller(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_extender_controller(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,282 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_facts
version_added: "2.9"
short_description: Get facts about fortios devices.
description:
- Collects facts from network devices running the fortios operating
system. This module places the facts gathered in the fact tree keyed by the
respective resource name. This facts module will only collect those
facts which user specified in playbook.
author:
- Don Yao (@fortinetps)
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Support both legacy mode (local_action) and httpapi
- Legacy mode run as a local_action in your playbook, requires fortiosapi library developed by Fortinet
- httpapi mode is the new recommend way for network modules
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
required: false
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
required: false
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
required: false
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: false
required: false
gather_subset:
description:
- When supplied, this argument will restrict the facts collected
to a given subset. Possible values for this argument include
system_current-admins_select, system_firmware_select,
system_fortimanager_status, system_ha-checksums_select,
system_interface_select, system_status_select and system_time_select
type: list
elements: dict
required: true
suboptions:
fact:
description:
- Name of the facts to gather
type: str
required: true
filters:
description:
- Filters apply when gathering facts
type: list
elements: dict
required: false
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: gather basic system status facts
fortios_facts:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
gather_subset:
- fact: 'system_status_select'
- name: gather all physical interfaces status facts
fortios_facts:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
gather_subset:
- fact: 'system_interface_select'
- name: gather gather all physical and vlan interfaces status facts
fortios_facts:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
gather_subset:
- fact: 'system_interface_select'
filters:
- include_vlan: true
- name: gather basic system info and physical interface port3 status facts
fortios_facts:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
gather_subset:
- fact: 'system_status_select'
- fact: 'system_interface_select'
filters:
- interface_name: 'port3'
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'GET'
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "firmware"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "system"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
ansible_facts:
description: The list of fact subsets collected from the device
returned: always
type: dict
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
from ansible.module_utils.network.fortios.argspec.facts.facts import FactsArgs
from ansible.module_utils.network.fortios.facts.facts import Facts
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def main():
""" Main entry point for AnsibleModule
"""
argument_spec = FactsArgs.argument_spec
module = AnsibleModule(argument_spec=argument_spec,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
warnings = []
connection = Connection(module._socket_path)
module._connection = connection
fos = FortiOSHandler(connection)
result = Facts(module, fos).get_facts()
ansible_facts, additional_warnings = result
warnings.extend(additional_warnings)
module.exit_json(ansible_facts=ansible_facts, warnings=warnings)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
warnings = []
fos = FortiOSAPI()
login(module.params, fos)
module._connection = fos
result = Facts(module, fos).get_facts()
ansible_facts, additional_warnings = result
warnings.extend(additional_warnings)
module.exit_json(ansible_facts=ansible_facts, warnings=warnings)
if __name__ == '__main__':
main()

@ -1,492 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_DoS_policy
short_description: Configure IPv4 DoS policies in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and DoS_policy category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_DoS_policy:
description:
- Configure IPv4 DoS policies.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
anomaly:
description:
- Anomaly name.
type: list
suboptions:
action:
description:
- Action taken when the threshold is reached.
type: str
choices:
- pass
- block
log:
description:
- Enable/disable anomaly logging.
type: str
choices:
- enable
- disable
name:
description:
- Anomaly name.
required: true
type: str
quarantine:
description:
- Quarantine method.
type: str
choices:
- none
- attacker
quarantine_expiry:
description:
- Duration of quarantine. (Format ###d##h##m, minimum 1m, maximum 364d23h59m). Requires quarantine set to attacker.
type: str
quarantine_log:
description:
- Enable/disable quarantine logging.
type: str
choices:
- disable
- enable
status:
description:
- Enable/disable this anomaly.
type: str
choices:
- disable
- enable
threshold:
description:
- Anomaly threshold. Number of detected instances per minute that triggers the anomaly action.
type: int
threshold(default):
description:
- Number of detected instances per minute which triggers action (1 - 2147483647). Note that each anomaly has a different threshold
value assigned to it.
type: int
comments:
description:
- Comment.
type: str
dstaddr:
description:
- Destination address name from available addresses.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address.name firewall.addrgrp.name.
required: true
type: str
interface:
description:
- Incoming interface name from available interfaces. Source system.zone.name system.interface.name.
type: str
policyid:
description:
- Policy ID.
required: true
type: int
service:
description:
- Service object from available options.
type: list
suboptions:
name:
description:
- Service name. Source firewall.service.custom.name firewall.service.group.name.
required: true
type: str
srcaddr:
description:
- Source address name from available addresses.
type: list
suboptions:
name:
description:
- Service name. Source firewall.address.name firewall.addrgrp.name.
required: true
type: str
status:
description:
- Enable/disable this policy.
type: str
choices:
- enable
- disable
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure IPv4 DoS policies.
fortios_firewall_DoS_policy:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_DoS_policy:
anomaly:
-
action: "pass"
log: "enable"
name: "default_name_6"
quarantine: "none"
quarantine_expiry: "<your_own_value>"
quarantine_log: "disable"
status: "disable"
threshold: "11"
threshold(default): "12"
comments: "<your_own_value>"
dstaddr:
-
name: "default_name_15 (source firewall.address.name firewall.addrgrp.name)"
interface: "<your_own_value> (source system.zone.name system.interface.name)"
policyid: "17"
service:
-
name: "default_name_19 (source firewall.service.custom.name firewall.service.group.name)"
srcaddr:
-
name: "default_name_21 (source firewall.address.name firewall.addrgrp.name)"
status: "enable"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_DoS_policy_data(json):
option_list = ['anomaly', 'comments', 'dstaddr',
'interface', 'policyid', 'service',
'srcaddr', 'status']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_DoS_policy(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_DoS_policy'] and data['firewall_DoS_policy']:
state = data['firewall_DoS_policy']['state']
else:
state = True
firewall_DoS_policy_data = data['firewall_DoS_policy']
filtered_data = underscore_to_hyphen(filter_firewall_DoS_policy_data(firewall_DoS_policy_data))
if state == "present":
return fos.set('firewall',
'DoS-policy',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'DoS-policy',
mkey=filtered_data['policyid'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_DoS_policy']:
resp = firewall_DoS_policy(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_DoS_policy": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"anomaly": {"required": False, "type": "list",
"options": {
"action": {"required": False, "type": "str",
"choices": ["pass", "block"]},
"log": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"name": {"required": True, "type": "str"},
"quarantine": {"required": False, "type": "str",
"choices": ["none", "attacker"]},
"quarantine_expiry": {"required": False, "type": "str"},
"quarantine_log": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"status": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"threshold": {"required": False, "type": "int"},
"threshold(default)": {"required": False, "type": "int"}
}},
"comments": {"required": False, "type": "str"},
"dstaddr": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"interface": {"required": False, "type": "str"},
"policyid": {"required": True, "type": "int"},
"service": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"srcaddr": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"status": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,492 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_DoS_policy6
short_description: Configure IPv6 DoS policies in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and DoS_policy6 category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_DoS_policy6:
description:
- Configure IPv6 DoS policies.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
anomaly:
description:
- Anomaly name.
type: list
suboptions:
action:
description:
- Action taken when the threshold is reached.
type: str
choices:
- pass
- block
log:
description:
- Enable/disable anomaly logging.
type: str
choices:
- enable
- disable
name:
description:
- Anomaly name.
required: true
type: str
quarantine:
description:
- Quarantine method.
type: str
choices:
- none
- attacker
quarantine_expiry:
description:
- Duration of quarantine. (Format ###d##h##m, minimum 1m, maximum 364d23h59m). Requires quarantine set to attacker.
type: str
quarantine_log:
description:
- Enable/disable quarantine logging.
type: str
choices:
- disable
- enable
status:
description:
- Enable/disable this anomaly.
type: str
choices:
- disable
- enable
threshold:
description:
- Anomaly threshold. Number of detected instances per minute that triggers the anomaly action.
type: int
threshold(default):
description:
- Number of detected instances per minute which triggers action (1 - 2147483647). Note that each anomaly has a different threshold
value assigned to it.
type: int
comments:
description:
- Comment.
type: str
dstaddr:
description:
- Destination address name from available addresses.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address6.name firewall.addrgrp6.name.
required: true
type: str
interface:
description:
- Incoming interface name from available interfaces. Source system.zone.name system.interface.name.
type: str
policyid:
description:
- Policy ID.
required: true
type: int
service:
description:
- Service object from available options.
type: list
suboptions:
name:
description:
- Service name. Source firewall.service.custom.name firewall.service.group.name.
required: true
type: str
srcaddr:
description:
- Source address name from available addresses.
type: list
suboptions:
name:
description:
- Service name. Source firewall.address6.name firewall.addrgrp6.name.
required: true
type: str
status:
description:
- Enable/disable this policy.
type: str
choices:
- enable
- disable
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure IPv6 DoS policies.
fortios_firewall_DoS_policy6:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_DoS_policy6:
anomaly:
-
action: "pass"
log: "enable"
name: "default_name_6"
quarantine: "none"
quarantine_expiry: "<your_own_value>"
quarantine_log: "disable"
status: "disable"
threshold: "11"
threshold(default): "12"
comments: "<your_own_value>"
dstaddr:
-
name: "default_name_15 (source firewall.address6.name firewall.addrgrp6.name)"
interface: "<your_own_value> (source system.zone.name system.interface.name)"
policyid: "17"
service:
-
name: "default_name_19 (source firewall.service.custom.name firewall.service.group.name)"
srcaddr:
-
name: "default_name_21 (source firewall.address6.name firewall.addrgrp6.name)"
status: "enable"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_DoS_policy6_data(json):
option_list = ['anomaly', 'comments', 'dstaddr',
'interface', 'policyid', 'service',
'srcaddr', 'status']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_DoS_policy6(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_DoS_policy6'] and data['firewall_DoS_policy6']:
state = data['firewall_DoS_policy6']['state']
else:
state = True
firewall_DoS_policy6_data = data['firewall_DoS_policy6']
filtered_data = underscore_to_hyphen(filter_firewall_DoS_policy6_data(firewall_DoS_policy6_data))
if state == "present":
return fos.set('firewall',
'DoS-policy6',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'DoS-policy6',
mkey=filtered_data['policyid'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_DoS_policy6']:
resp = firewall_DoS_policy6(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_DoS_policy6": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"anomaly": {"required": False, "type": "list",
"options": {
"action": {"required": False, "type": "str",
"choices": ["pass", "block"]},
"log": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"name": {"required": True, "type": "str"},
"quarantine": {"required": False, "type": "str",
"choices": ["none", "attacker"]},
"quarantine_expiry": {"required": False, "type": "str"},
"quarantine_log": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"status": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"threshold": {"required": False, "type": "int"},
"threshold(default)": {"required": False, "type": "int"}
}},
"comments": {"required": False, "type": "str"},
"dstaddr": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"interface": {"required": False, "type": "str"},
"policyid": {"required": True, "type": "int"},
"service": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"srcaddr": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"status": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,571 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_address
short_description: Configure IPv4 addresses in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and address category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_address:
description:
- Configure IPv4 addresses.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
allow_routing:
description:
- Enable/disable use of this address in the static route configuration.
type: str
choices:
- enable
- disable
associated_interface:
description:
- Network interface associated with address. Source system.interface.name system.zone.name.
type: str
cache_ttl:
description:
- Defines the minimal TTL of individual IP addresses in FQDN cache measured in seconds.
type: int
color:
description:
- Color of icon on the GUI.
type: int
comment:
description:
- Comment.
type: str
country:
description:
- IP addresses associated to a specific country.
type: str
end_ip:
description:
- Final IP address (inclusive) in the range for the address.
type: str
epg_name:
description:
- Endpoint group name.
type: str
filter:
description:
- Match criteria filter.
type: str
fqdn:
description:
- Fully Qualified Domain Name address.
type: str
list:
description:
- IP address list.
type: list
suboptions:
ip:
description:
- IP.
required: true
type: str
name:
description:
- Address name.
required: true
type: str
obj_id:
description:
- Object ID for NSX.
type: str
organization:
description:
- "Organization domain name (Syntax: organization/domain)."
type: str
policy_group:
description:
- Policy group name.
type: str
sdn:
description:
- SDN.
type: str
choices:
- aci
- aws
- azure
- gcp
- nsx
- nuage
- oci
- openstack
sdn_tag:
description:
- SDN Tag.
type: str
start_ip:
description:
- First IP address (inclusive) in the range for the address.
type: str
subnet:
description:
- IP address and subnet mask of address.
type: str
subnet_name:
description:
- Subnet name.
type: str
tagging:
description:
- Config object tagging.
type: list
suboptions:
category:
description:
- Tag category. Source system.object-tagging.category.
type: str
name:
description:
- Tagging entry name.
required: true
type: str
tags:
description:
- Tags.
type: list
suboptions:
name:
description:
- Tag name. Source system.object-tagging.tags.name.
required: true
type: str
tenant:
description:
- Tenant.
type: str
type:
description:
- Type of address.
type: str
choices:
- ipmask
- iprange
- fqdn
- geography
- wildcard
- wildcard-fqdn
- dynamic
uuid:
description:
- Universally Unique Identifier (UUID; automatically assigned but can be manually reset).
type: str
visibility:
description:
- Enable/disable address visibility in the GUI.
type: str
choices:
- enable
- disable
wildcard:
description:
- IP address and wildcard netmask.
type: str
wildcard_fqdn:
description:
- Fully Qualified Domain Name with wildcard characters.
type: str
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure IPv4 addresses.
fortios_firewall_address:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_address:
allow_routing: "enable"
associated_interface: "<your_own_value> (source system.interface.name system.zone.name)"
cache_ttl: "5"
color: "6"
comment: "Comment."
country: "<your_own_value>"
end_ip: "<your_own_value>"
epg_name: "<your_own_value>"
filter: "<your_own_value>"
fqdn: "<your_own_value>"
list:
-
ip: "<your_own_value>"
name: "default_name_15"
obj_id: "<your_own_value>"
organization: "<your_own_value>"
policy_group: "<your_own_value>"
sdn: "aci"
sdn_tag: "<your_own_value>"
start_ip: "<your_own_value>"
subnet: "<your_own_value>"
subnet_name: "<your_own_value>"
tagging:
-
category: "<your_own_value> (source system.object-tagging.category)"
name: "default_name_26"
tags:
-
name: "default_name_28 (source system.object-tagging.tags.name)"
tenant: "<your_own_value>"
type: "ipmask"
uuid: "<your_own_value>"
visibility: "enable"
wildcard: "<your_own_value>"
wildcard_fqdn: "<your_own_value>"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_address_data(json):
option_list = ['allow_routing', 'associated_interface', 'cache_ttl',
'color', 'comment', 'country',
'end_ip', 'epg_name', 'filter',
'fqdn', 'list', 'name',
'obj_id', 'organization', 'policy_group',
'sdn', 'sdn_tag', 'start_ip',
'subnet', 'subnet_name', 'tagging',
'tenant', 'type', 'uuid',
'visibility', 'wildcard', 'wildcard_fqdn']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_address(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_address'] and data['firewall_address']:
state = data['firewall_address']['state']
else:
state = True
firewall_address_data = data['firewall_address']
filtered_data = underscore_to_hyphen(filter_firewall_address_data(firewall_address_data))
if state == "present":
return fos.set('firewall',
'address',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'address',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_address']:
resp = firewall_address(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_address": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"allow_routing": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"associated_interface": {"required": False, "type": "str"},
"cache_ttl": {"required": False, "type": "int"},
"color": {"required": False, "type": "int"},
"comment": {"required": False, "type": "str"},
"country": {"required": False, "type": "str"},
"end_ip": {"required": False, "type": "str"},
"epg_name": {"required": False, "type": "str"},
"filter": {"required": False, "type": "str"},
"fqdn": {"required": False, "type": "str"},
"list": {"required": False, "type": "list",
"options": {
"ip": {"required": True, "type": "str"}
}},
"name": {"required": True, "type": "str"},
"obj_id": {"required": False, "type": "str"},
"organization": {"required": False, "type": "str"},
"policy_group": {"required": False, "type": "str"},
"sdn": {"required": False, "type": "str",
"choices": ["aci", "aws", "azure",
"gcp", "nsx", "nuage",
"oci", "openstack"]},
"sdn_tag": {"required": False, "type": "str"},
"start_ip": {"required": False, "type": "str"},
"subnet": {"required": False, "type": "str"},
"subnet_name": {"required": False, "type": "str"},
"tagging": {"required": False, "type": "list",
"options": {
"category": {"required": False, "type": "str"},
"name": {"required": True, "type": "str"},
"tags": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}}
}},
"tenant": {"required": False, "type": "str"},
"type": {"required": False, "type": "str",
"choices": ["ipmask", "iprange", "fqdn",
"geography", "wildcard", "wildcard-fqdn",
"dynamic"]},
"uuid": {"required": False, "type": "str"},
"visibility": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"wildcard": {"required": False, "type": "str"},
"wildcard_fqdn": {"required": False, "type": "str"}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,536 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_address6
short_description: Configure IPv6 firewall addresses in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and address6 category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_address6:
description:
- Configure IPv6 firewall addresses.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
cache_ttl:
description:
- Minimal TTL of individual IPv6 addresses in FQDN cache.
type: int
color:
description:
- Integer value to determine the color of the icon in the GUI (range 1 to 32).
type: int
comment:
description:
- Comment.
type: str
end_ip:
description:
- "Final IP address (inclusive) in the range for the address (format: xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx)."
type: str
fqdn:
description:
- Fully qualified domain name.
type: str
host:
description:
- Host Address.
type: str
host_type:
description:
- Host type.
type: str
choices:
- any
- specific
ip6:
description:
- "IPv6 address prefix (format: xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx/xxx)."
type: str
list:
description:
- IP address list.
type: list
suboptions:
ip:
description:
- IP.
required: true
type: str
name:
description:
- Address name.
required: true
type: str
obj_id:
description:
- Object ID for NSX.
type: str
sdn:
description:
- SDN.
type: str
choices:
- nsx
start_ip:
description:
- "First IP address (inclusive) in the range for the address (format: xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx)."
type: str
subnet_segment:
description:
- IPv6 subnet segments.
type: list
suboptions:
name:
description:
- Name.
required: true
type: str
type:
description:
- Subnet segment type.
type: str
choices:
- any
- specific
value:
description:
- Subnet segment value.
type: str
tagging:
description:
- Config object tagging
type: list
suboptions:
category:
description:
- Tag category. Source system.object-tagging.category.
type: str
name:
description:
- Tagging entry name.
required: true
type: str
tags:
description:
- Tags.
type: list
suboptions:
name:
description:
- Tag name. Source system.object-tagging.tags.name.
required: true
type: str
template:
description:
- IPv6 address template. Source firewall.address6-template.name.
type: str
type:
description:
- Type of IPv6 address object .
type: str
choices:
- ipprefix
- iprange
- fqdn
- dynamic
- template
uuid:
description:
- Universally Unique Identifier (UUID; automatically assigned but can be manually reset).
type: str
visibility:
description:
- Enable/disable the visibility of the object in the GUI.
type: str
choices:
- enable
- disable
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure IPv6 firewall addresses.
fortios_firewall_address6:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_address6:
cache_ttl: "3"
color: "4"
comment: "Comment."
end_ip: "<your_own_value>"
fqdn: "<your_own_value>"
host: "<your_own_value>"
host_type: "any"
ip6: "<your_own_value>"
list:
-
ip: "<your_own_value>"
name: "default_name_13"
obj_id: "<your_own_value>"
sdn: "nsx"
start_ip: "<your_own_value>"
subnet_segment:
-
name: "default_name_18"
type: "any"
value: "<your_own_value>"
tagging:
-
category: "<your_own_value> (source system.object-tagging.category)"
name: "default_name_23"
tags:
-
name: "default_name_25 (source system.object-tagging.tags.name)"
template: "<your_own_value> (source firewall.address6-template.name)"
type: "ipprefix"
uuid: "<your_own_value>"
visibility: "enable"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_address6_data(json):
option_list = ['cache_ttl', 'color', 'comment',
'end_ip', 'fqdn', 'host',
'host_type', 'ip6', 'list',
'name', 'obj_id', 'sdn',
'start_ip', 'subnet_segment', 'tagging',
'template', 'type', 'uuid',
'visibility']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_address6(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_address6'] and data['firewall_address6']:
state = data['firewall_address6']['state']
else:
state = True
firewall_address6_data = data['firewall_address6']
filtered_data = underscore_to_hyphen(filter_firewall_address6_data(firewall_address6_data))
if state == "present":
return fos.set('firewall',
'address6',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'address6',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_address6']:
resp = firewall_address6(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_address6": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"cache_ttl": {"required": False, "type": "int"},
"color": {"required": False, "type": "int"},
"comment": {"required": False, "type": "str"},
"end_ip": {"required": False, "type": "str"},
"fqdn": {"required": False, "type": "str"},
"host": {"required": False, "type": "str"},
"host_type": {"required": False, "type": "str",
"choices": ["any", "specific"]},
"ip6": {"required": False, "type": "str"},
"list": {"required": False, "type": "list",
"options": {
"ip": {"required": True, "type": "str"}
}},
"name": {"required": True, "type": "str"},
"obj_id": {"required": False, "type": "str"},
"sdn": {"required": False, "type": "str",
"choices": ["nsx"]},
"start_ip": {"required": False, "type": "str"},
"subnet_segment": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"},
"type": {"required": False, "type": "str",
"choices": ["any", "specific"]},
"value": {"required": False, "type": "str"}
}},
"tagging": {"required": False, "type": "list",
"options": {
"category": {"required": False, "type": "str"},
"name": {"required": True, "type": "str"},
"tags": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}}
}},
"template": {"required": False, "type": "str"},
"type": {"required": False, "type": "str",
"choices": ["ipprefix", "iprange", "fqdn",
"dynamic", "template"]},
"uuid": {"required": False, "type": "str"},
"visibility": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,406 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_address6_template
short_description: Configure IPv6 address templates in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and address6_template category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_address6_template:
description:
- Configure IPv6 address templates.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
ip6:
description:
- IPv6 address prefix.
type: str
name:
description:
- IPv6 address template name.
required: true
type: str
subnet_segment:
description:
- IPv6 subnet segments.
type: list
suboptions:
bits:
description:
- Number of bits.
type: int
exclusive:
description:
- Enable/disable exclusive value.
type: str
choices:
- enable
- disable
id:
description:
- Subnet segment ID.
required: true
type: int
name:
description:
- Subnet segment name.
type: str
values:
description:
- Subnet segment values.
type: list
suboptions:
name:
description:
- Subnet segment value name.
required: true
type: str
value:
description:
- Subnet segment value.
type: str
subnet_segment_count:
description:
- Number of IPv6 subnet segments.
type: int
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure IPv6 address templates.
fortios_firewall_address6_template:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_address6_template:
ip6: "<your_own_value>"
name: "default_name_4"
subnet_segment:
-
bits: "6"
exclusive: "enable"
id: "8"
name: "default_name_9"
values:
-
name: "default_name_11"
value: "<your_own_value>"
subnet_segment_count: "13"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_address6_template_data(json):
option_list = ['ip6', 'name', 'subnet_segment',
'subnet_segment_count']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_address6_template(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_address6_template'] and data['firewall_address6_template']:
state = data['firewall_address6_template']['state']
else:
state = True
firewall_address6_template_data = data['firewall_address6_template']
filtered_data = underscore_to_hyphen(filter_firewall_address6_template_data(firewall_address6_template_data))
if state == "present":
return fos.set('firewall',
'address6-template',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'address6-template',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_address6_template']:
resp = firewall_address6_template(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_address6_template": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"ip6": {"required": False, "type": "str"},
"name": {"required": True, "type": "str"},
"subnet_segment": {"required": False, "type": "list",
"options": {
"bits": {"required": False, "type": "int"},
"exclusive": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"id": {"required": True, "type": "int"},
"name": {"required": False, "type": "str"},
"values": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"},
"value": {"required": False, "type": "str"}
}}
}},
"subnet_segment_count": {"required": False, "type": "int"}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,428 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_addrgrp
short_description: Configure IPv4 address groups in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and addrgrp category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_addrgrp:
description:
- Configure IPv4 address groups.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
allow_routing:
description:
- Enable/disable use of this group in the static route configuration.
type: str
choices:
- enable
- disable
color:
description:
- Color of icon on the GUI.
type: int
comment:
description:
- Comment.
type: str
member:
description:
- Address objects contained within the group.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address.name firewall.addrgrp.name.
required: true
type: str
name:
description:
- Address group name.
required: true
type: str
tagging:
description:
- Config object tagging.
type: list
suboptions:
category:
description:
- Tag category. Source system.object-tagging.category.
type: str
name:
description:
- Tagging entry name.
required: true
type: str
tags:
description:
- Tags.
type: list
suboptions:
name:
description:
- Tag name. Source system.object-tagging.tags.name.
required: true
type: str
uuid:
description:
- Universally Unique Identifier (UUID; automatically assigned but can be manually reset).
type: str
visibility:
description:
- Enable/disable address visibility in the GUI.
type: str
choices:
- enable
- disable
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure IPv4 address groups.
fortios_firewall_addrgrp:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_addrgrp:
allow_routing: "enable"
color: "4"
comment: "Comment."
member:
-
name: "default_name_7 (source firewall.address.name firewall.addrgrp.name)"
name: "default_name_8"
tagging:
-
category: "<your_own_value> (source system.object-tagging.category)"
name: "default_name_11"
tags:
-
name: "default_name_13 (source system.object-tagging.tags.name)"
uuid: "<your_own_value>"
visibility: "enable"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_addrgrp_data(json):
option_list = ['allow_routing', 'color', 'comment',
'member', 'name', 'tagging',
'uuid', 'visibility']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_addrgrp(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_addrgrp'] and data['firewall_addrgrp']:
state = data['firewall_addrgrp']['state']
else:
state = True
firewall_addrgrp_data = data['firewall_addrgrp']
filtered_data = underscore_to_hyphen(filter_firewall_addrgrp_data(firewall_addrgrp_data))
if state == "present":
return fos.set('firewall',
'addrgrp',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'addrgrp',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_addrgrp']:
resp = firewall_addrgrp(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_addrgrp": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"allow_routing": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"color": {"required": False, "type": "int"},
"comment": {"required": False, "type": "str"},
"member": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"name": {"required": True, "type": "str"},
"tagging": {"required": False, "type": "list",
"options": {
"category": {"required": False, "type": "str"},
"name": {"required": True, "type": "str"},
"tags": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}}
}},
"uuid": {"required": False, "type": "str"},
"visibility": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,418 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_addrgrp6
short_description: Configure IPv6 address groups in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and addrgrp6 category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_addrgrp6:
description:
- Configure IPv6 address groups.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
color:
description:
- Integer value to determine the color of the icon in the GUI (1 - 32).
type: int
comment:
description:
- Comment.
type: str
member:
description:
- Address objects contained within the group.
type: list
suboptions:
name:
description:
- Address6/addrgrp6 name. Source firewall.address6.name firewall.addrgrp6.name.
required: true
type: str
name:
description:
- IPv6 address group name.
required: true
type: str
tagging:
description:
- Config object tagging.
type: list
suboptions:
category:
description:
- Tag category. Source system.object-tagging.category.
type: str
name:
description:
- Tagging entry name.
required: true
type: str
tags:
description:
- Tags.
type: list
suboptions:
name:
description:
- Tag name. Source system.object-tagging.tags.name.
required: true
type: str
uuid:
description:
- Universally Unique Identifier (UUID; automatically assigned but can be manually reset).
type: str
visibility:
description:
- Enable/disable address group6 visibility in the GUI.
type: str
choices:
- enable
- disable
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure IPv6 address groups.
fortios_firewall_addrgrp6:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_addrgrp6:
color: "3"
comment: "Comment."
member:
-
name: "default_name_6 (source firewall.address6.name firewall.addrgrp6.name)"
name: "default_name_7"
tagging:
-
category: "<your_own_value> (source system.object-tagging.category)"
name: "default_name_10"
tags:
-
name: "default_name_12 (source system.object-tagging.tags.name)"
uuid: "<your_own_value>"
visibility: "enable"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_addrgrp6_data(json):
option_list = ['color', 'comment', 'member',
'name', 'tagging', 'uuid',
'visibility']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_addrgrp6(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_addrgrp6'] and data['firewall_addrgrp6']:
state = data['firewall_addrgrp6']['state']
else:
state = True
firewall_addrgrp6_data = data['firewall_addrgrp6']
filtered_data = underscore_to_hyphen(filter_firewall_addrgrp6_data(firewall_addrgrp6_data))
if state == "present":
return fos.set('firewall',
'addrgrp6',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'addrgrp6',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_addrgrp6']:
resp = firewall_addrgrp6(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_addrgrp6": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"color": {"required": False, "type": "int"},
"comment": {"required": False, "type": "str"},
"member": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"name": {"required": True, "type": "str"},
"tagging": {"required": False, "type": "list",
"options": {
"category": {"required": False, "type": "str"},
"name": {"required": True, "type": "str"},
"tags": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}}
}},
"uuid": {"required": False, "type": "str"},
"visibility": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,320 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_auth_portal
short_description: Configure firewall authentication portals in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and auth_portal category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
firewall_auth_portal:
description:
- Configure firewall authentication portals.
default: null
type: dict
suboptions:
groups:
description:
- Firewall user groups permitted to authenticate through this portal. Separate group names with spaces.
type: list
suboptions:
name:
description:
- Group name. Source user.group.name.
required: true
type: str
identity_based_route:
description:
- Name of the identity-based route that applies to this portal. Source firewall.identity-based-route.name.
type: str
portal_addr:
description:
- Address (or FQDN) of the authentication portal.
type: str
portal_addr6:
description:
- IPv6 address (or FQDN) of authentication portal.
type: str
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure firewall authentication portals.
fortios_firewall_auth_portal:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
firewall_auth_portal:
groups:
-
name: "default_name_4 (source user.group.name)"
identity_based_route: "<your_own_value> (source firewall.identity-based-route.name)"
portal_addr: "<your_own_value>"
portal_addr6: "<your_own_value>"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_auth_portal_data(json):
option_list = ['groups', 'identity_based_route', 'portal_addr',
'portal_addr6']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_auth_portal(data, fos):
vdom = data['vdom']
firewall_auth_portal_data = data['firewall_auth_portal']
filtered_data = underscore_to_hyphen(filter_firewall_auth_portal_data(firewall_auth_portal_data))
return fos.set('firewall',
'auth-portal',
data=filtered_data,
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_auth_portal']:
resp = firewall_auth_portal(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"firewall_auth_portal": {
"required": False, "type": "dict", "default": None,
"options": {
"groups": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"identity_based_route": {"required": False, "type": "str"},
"portal_addr": {"required": False, "type": "str"},
"portal_addr6": {"required": False, "type": "str"}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,463 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_central_snat_map
short_description: Configure central SNAT policies in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and central_snat_map category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_central_snat_map:
description:
- Configure central SNAT policies.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
comments:
description:
- Comment.
type: str
dst_addr:
description:
- Destination address name from available addresses.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address.name firewall.addrgrp.name.
required: true
type: str
dstintf:
description:
- Destination interface name from available interfaces.
type: list
suboptions:
name:
description:
- Interface name. Source system.interface.name system.zone.name.
required: true
type: str
nat:
description:
- Enable/disable source NAT.
type: str
choices:
- disable
- enable
nat_ippool:
description:
- Name of the IP pools to be used to translate addresses from available IP Pools.
type: list
suboptions:
name:
description:
- IP pool name. Source firewall.ippool.name.
required: true
type: str
nat_port:
description:
- Translated port or port range (0 to 65535).
type: str
orig_addr:
description:
- Original address.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address.name firewall.addrgrp.name.
required: true
type: str
orig_port:
description:
- Original TCP port (0 to 65535).
type: str
policyid:
description:
- Policy ID.
required: true
type: int
protocol:
description:
- Integer value for the protocol type (0 - 255).
type: int
srcintf:
description:
- Source interface name from available interfaces.
type: list
suboptions:
name:
description:
- Interface name. Source system.interface.name system.zone.name.
required: true
type: str
status:
description:
- Enable/disable the active status of this policy.
type: str
choices:
- enable
- disable
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure central SNAT policies.
fortios_firewall_central_snat_map:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_central_snat_map:
comments: "<your_own_value>"
dst_addr:
-
name: "default_name_5 (source firewall.address.name firewall.addrgrp.name)"
dstintf:
-
name: "default_name_7 (source system.interface.name system.zone.name)"
nat: "disable"
nat_ippool:
-
name: "default_name_10 (source firewall.ippool.name)"
nat_port: "<your_own_value>"
orig_addr:
-
name: "default_name_13 (source firewall.address.name firewall.addrgrp.name)"
orig_port: "<your_own_value>"
policyid: "15"
protocol: "16"
srcintf:
-
name: "default_name_18 (source system.interface.name system.zone.name)"
status: "enable"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_central_snat_map_data(json):
option_list = ['comments', 'dst_addr', 'dstintf',
'nat', 'nat_ippool', 'nat_port',
'orig_addr', 'orig_port', 'policyid',
'protocol', 'srcintf', 'status']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_central_snat_map(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_central_snat_map'] and data['firewall_central_snat_map']:
state = data['firewall_central_snat_map']['state']
else:
state = True
firewall_central_snat_map_data = data['firewall_central_snat_map']
filtered_data = underscore_to_hyphen(filter_firewall_central_snat_map_data(firewall_central_snat_map_data))
if state == "present":
return fos.set('firewall',
'central-snat-map',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'central-snat-map',
mkey=filtered_data['policyid'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_central_snat_map']:
resp = firewall_central_snat_map(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_central_snat_map": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"comments": {"required": False, "type": "str"},
"dst_addr": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"dstintf": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"nat": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"nat_ippool": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"nat_port": {"required": False, "type": "str"},
"orig_addr": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"orig_port": {"required": False, "type": "str"},
"policyid": {"required": True, "type": "int"},
"protocol": {"required": False, "type": "int"},
"srcintf": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"status": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,352 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_dnstranslation
short_description: Configure DNS translation in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and dnstranslation category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_dnstranslation:
description:
- Configure DNS translation.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
dst:
description:
- IPv4 address or subnet on the external network to substitute for the resolved address in DNS query replies. Can be single IP address or
subnet on the external network, but number of addresses must equal number of mapped IP addresses in src.
type: str
id:
description:
- ID.
required: true
type: int
netmask:
description:
- If src and dst are subnets rather than single IP addresses, enter the netmask for both src and dst.
type: str
src:
description:
- IPv4 address or subnet on the internal network to compare with the resolved address in DNS query replies. If the resolved address
matches, the resolved address is substituted with dst.
type: str
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure DNS translation.
fortios_firewall_dnstranslation:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_dnstranslation:
dst: "<your_own_value>"
id: "4"
netmask: "<your_own_value>"
src: "<your_own_value>"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_dnstranslation_data(json):
option_list = ['dst', 'id', 'netmask',
'src']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_dnstranslation(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_dnstranslation'] and data['firewall_dnstranslation']:
state = data['firewall_dnstranslation']['state']
else:
state = True
firewall_dnstranslation_data = data['firewall_dnstranslation']
filtered_data = underscore_to_hyphen(filter_firewall_dnstranslation_data(firewall_dnstranslation_data))
if state == "present":
return fos.set('firewall',
'dnstranslation',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'dnstranslation',
mkey=filtered_data['id'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_dnstranslation']:
resp = firewall_dnstranslation(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_dnstranslation": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"dst": {"required": False, "type": "str"},
"id": {"required": True, "type": "int"},
"netmask": {"required": False, "type": "str"},
"src": {"required": False, "type": "str"}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,383 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_identity_based_route
short_description: Configure identity based routing in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and identity_based_route category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_identity_based_route:
description:
- Configure identity based routing.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
comments:
description:
- Comments.
type: str
name:
description:
- Name.
required: true
type: str
rule:
description:
- Rule.
type: list
suboptions:
device:
description:
- Outgoing interface for the rule. Source system.interface.name.
type: str
gateway:
description:
- "IPv4 address of the gateway (Format: xxx.xxx.xxx.xxx )."
type: str
groups:
description:
- Select one or more group(s) from available groups that are allowed to use this route. Separate group names with a space.
type: list
suboptions:
name:
description:
- Group name. Source user.group.name.
required: true
type: str
id:
description:
- Rule ID.
required: true
type: int
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure identity based routing.
fortios_firewall_identity_based_route:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_identity_based_route:
comments: "<your_own_value>"
name: "default_name_4"
rule:
-
device: "<your_own_value> (source system.interface.name)"
gateway: "<your_own_value>"
groups:
-
name: "default_name_9 (source user.group.name)"
id: "10"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_identity_based_route_data(json):
option_list = ['comments', 'name', 'rule']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_identity_based_route(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_identity_based_route'] and data['firewall_identity_based_route']:
state = data['firewall_identity_based_route']['state']
else:
state = True
firewall_identity_based_route_data = data['firewall_identity_based_route']
filtered_data = underscore_to_hyphen(filter_firewall_identity_based_route_data(firewall_identity_based_route_data))
if state == "present":
return fos.set('firewall',
'identity-based-route',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'identity-based-route',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_identity_based_route']:
resp = firewall_identity_based_route(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_identity_based_route": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"comments": {"required": False, "type": "str"},
"name": {"required": True, "type": "str"},
"rule": {"required": False, "type": "list",
"options": {
"device": {"required": False, "type": "str"},
"gateway": {"required": False, "type": "str"},
"groups": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"id": {"required": True, "type": "int"}
}}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,555 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_interface_policy
short_description: Configure IPv4 interface policies in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and interface_policy category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_interface_policy:
description:
- Configure IPv4 interface policies.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
address_type:
description:
- Policy address type (IPv4 or IPv6).
type: str
choices:
- ipv4
- ipv6
application_list:
description:
- Application list name. Source application.list.name.
type: str
application_list_status:
description:
- Enable/disable application control.
type: str
choices:
- enable
- disable
av_profile:
description:
- Antivirus profile. Source antivirus.profile.name.
type: str
av_profile_status:
description:
- Enable/disable antivirus.
type: str
choices:
- enable
- disable
comments:
description:
- Comments.
type: str
dlp_sensor:
description:
- DLP sensor name. Source dlp.sensor.name.
type: str
dlp_sensor_status:
description:
- Enable/disable DLP.
type: str
choices:
- enable
- disable
dsri:
description:
- Enable/disable DSRI.
type: str
choices:
- enable
- disable
dstaddr:
description:
- Address object to limit traffic monitoring to network traffic sent to the specified address or range.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address.name firewall.addrgrp.name.
required: true
type: str
interface:
description:
- Monitored interface name from available interfaces. Source system.zone.name system.interface.name.
type: str
ips_sensor:
description:
- IPS sensor name. Source ips.sensor.name.
type: str
ips_sensor_status:
description:
- Enable/disable IPS.
type: str
choices:
- enable
- disable
label:
description:
- Label.
type: str
logtraffic:
description:
- "Logging type to be used in this policy (Options: all | utm | disable)."
type: str
choices:
- all
- utm
- disable
policyid:
description:
- Policy ID.
required: true
type: int
scan_botnet_connections:
description:
- Enable/disable scanning for connections to Botnet servers.
type: str
choices:
- disable
- block
- monitor
service:
description:
- Service object from available options.
type: list
suboptions:
name:
description:
- Service name. Source firewall.service.custom.name firewall.service.group.name.
required: true
type: str
spamfilter_profile:
description:
- Antispam profile. Source spamfilter.profile.name.
type: str
spamfilter_profile_status:
description:
- Enable/disable antispam.
type: str
choices:
- enable
- disable
srcaddr:
description:
- Address object to limit traffic monitoring to network traffic sent from the specified address or range.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address.name firewall.addrgrp.name.
required: true
type: str
status:
description:
- Enable/disable this policy.
type: str
choices:
- enable
- disable
webfilter_profile:
description:
- Web filter profile. Source webfilter.profile.name.
type: str
webfilter_profile_status:
description:
- Enable/disable web filtering.
type: str
choices:
- enable
- disable
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure IPv4 interface policies.
fortios_firewall_interface_policy:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_interface_policy:
address_type: "ipv4"
application_list: "<your_own_value> (source application.list.name)"
application_list_status: "enable"
av_profile: "<your_own_value> (source antivirus.profile.name)"
av_profile_status: "enable"
comments: "<your_own_value>"
dlp_sensor: "<your_own_value> (source dlp.sensor.name)"
dlp_sensor_status: "enable"
dsri: "enable"
dstaddr:
-
name: "default_name_13 (source firewall.address.name firewall.addrgrp.name)"
interface: "<your_own_value> (source system.zone.name system.interface.name)"
ips_sensor: "<your_own_value> (source ips.sensor.name)"
ips_sensor_status: "enable"
label: "<your_own_value>"
logtraffic: "all"
policyid: "19"
scan_botnet_connections: "disable"
service:
-
name: "default_name_22 (source firewall.service.custom.name firewall.service.group.name)"
spamfilter_profile: "<your_own_value> (source spamfilter.profile.name)"
spamfilter_profile_status: "enable"
srcaddr:
-
name: "default_name_26 (source firewall.address.name firewall.addrgrp.name)"
status: "enable"
webfilter_profile: "<your_own_value> (source webfilter.profile.name)"
webfilter_profile_status: "enable"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_interface_policy_data(json):
option_list = ['address_type', 'application_list', 'application_list_status',
'av_profile', 'av_profile_status', 'comments',
'dlp_sensor', 'dlp_sensor_status', 'dsri',
'dstaddr', 'interface', 'ips_sensor',
'ips_sensor_status', 'label', 'logtraffic',
'policyid', 'scan_botnet_connections', 'service',
'spamfilter_profile', 'spamfilter_profile_status', 'srcaddr',
'status', 'webfilter_profile', 'webfilter_profile_status']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_interface_policy(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_interface_policy'] and data['firewall_interface_policy']:
state = data['firewall_interface_policy']['state']
else:
state = True
firewall_interface_policy_data = data['firewall_interface_policy']
filtered_data = underscore_to_hyphen(filter_firewall_interface_policy_data(firewall_interface_policy_data))
if state == "present":
return fos.set('firewall',
'interface-policy',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'interface-policy',
mkey=filtered_data['policyid'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_interface_policy']:
resp = firewall_interface_policy(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_interface_policy": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"address_type": {"required": False, "type": "str",
"choices": ["ipv4", "ipv6"]},
"application_list": {"required": False, "type": "str"},
"application_list_status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"av_profile": {"required": False, "type": "str"},
"av_profile_status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"comments": {"required": False, "type": "str"},
"dlp_sensor": {"required": False, "type": "str"},
"dlp_sensor_status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"dsri": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"dstaddr": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"interface": {"required": False, "type": "str"},
"ips_sensor": {"required": False, "type": "str"},
"ips_sensor_status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"label": {"required": False, "type": "str"},
"logtraffic": {"required": False, "type": "str",
"choices": ["all", "utm", "disable"]},
"policyid": {"required": True, "type": "int"},
"scan_botnet_connections": {"required": False, "type": "str",
"choices": ["disable", "block", "monitor"]},
"service": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"spamfilter_profile": {"required": False, "type": "str"},
"spamfilter_profile_status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"srcaddr": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"webfilter_profile": {"required": False, "type": "str"},
"webfilter_profile_status": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,555 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_interface_policy6
short_description: Configure IPv6 interface policies in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and interface_policy6 category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_interface_policy6:
description:
- Configure IPv6 interface policies.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
address_type:
description:
- Policy address type (IPv4 or IPv6).
type: str
choices:
- ipv4
- ipv6
application_list:
description:
- Application list name. Source application.list.name.
type: str
application_list_status:
description:
- Enable/disable application control.
type: str
choices:
- enable
- disable
av_profile:
description:
- Antivirus profile. Source antivirus.profile.name.
type: str
av_profile_status:
description:
- Enable/disable antivirus.
type: str
choices:
- enable
- disable
comments:
description:
- Comments.
type: str
dlp_sensor:
description:
- DLP sensor name. Source dlp.sensor.name.
type: str
dlp_sensor_status:
description:
- Enable/disable DLP.
type: str
choices:
- enable
- disable
dsri:
description:
- Enable/disable DSRI.
type: str
choices:
- enable
- disable
dstaddr6:
description:
- IPv6 address object to limit traffic monitoring to network traffic sent to the specified address or range.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address6.name firewall.addrgrp6.name.
required: true
type: str
interface:
description:
- Monitored interface name from available interfaces. Source system.zone.name system.interface.name.
type: str
ips_sensor:
description:
- IPS sensor name. Source ips.sensor.name.
type: str
ips_sensor_status:
description:
- Enable/disable IPS.
type: str
choices:
- enable
- disable
label:
description:
- Label.
type: str
logtraffic:
description:
- "Logging type to be used in this policy (Options: all | utm | disable)."
type: str
choices:
- all
- utm
- disable
policyid:
description:
- Policy ID.
required: true
type: int
scan_botnet_connections:
description:
- Enable/disable scanning for connections to Botnet servers.
type: str
choices:
- disable
- block
- monitor
service6:
description:
- Service name.
type: list
suboptions:
name:
description:
- Address name. Source firewall.service.custom.name firewall.service.group.name.
required: true
type: str
spamfilter_profile:
description:
- Antispam profile. Source spamfilter.profile.name.
type: str
spamfilter_profile_status:
description:
- Enable/disable antispam.
type: str
choices:
- enable
- disable
srcaddr6:
description:
- IPv6 address object to limit traffic monitoring to network traffic sent from the specified address or range.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address6.name firewall.addrgrp6.name.
required: true
type: str
status:
description:
- Enable/disable this policy.
type: str
choices:
- enable
- disable
webfilter_profile:
description:
- Web filter profile. Source webfilter.profile.name.
type: str
webfilter_profile_status:
description:
- Enable/disable web filtering.
type: str
choices:
- enable
- disable
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure IPv6 interface policies.
fortios_firewall_interface_policy6:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_interface_policy6:
address_type: "ipv4"
application_list: "<your_own_value> (source application.list.name)"
application_list_status: "enable"
av_profile: "<your_own_value> (source antivirus.profile.name)"
av_profile_status: "enable"
comments: "<your_own_value>"
dlp_sensor: "<your_own_value> (source dlp.sensor.name)"
dlp_sensor_status: "enable"
dsri: "enable"
dstaddr6:
-
name: "default_name_13 (source firewall.address6.name firewall.addrgrp6.name)"
interface: "<your_own_value> (source system.zone.name system.interface.name)"
ips_sensor: "<your_own_value> (source ips.sensor.name)"
ips_sensor_status: "enable"
label: "<your_own_value>"
logtraffic: "all"
policyid: "19"
scan_botnet_connections: "disable"
service6:
-
name: "default_name_22 (source firewall.service.custom.name firewall.service.group.name)"
spamfilter_profile: "<your_own_value> (source spamfilter.profile.name)"
spamfilter_profile_status: "enable"
srcaddr6:
-
name: "default_name_26 (source firewall.address6.name firewall.addrgrp6.name)"
status: "enable"
webfilter_profile: "<your_own_value> (source webfilter.profile.name)"
webfilter_profile_status: "enable"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_interface_policy6_data(json):
option_list = ['address_type', 'application_list', 'application_list_status',
'av_profile', 'av_profile_status', 'comments',
'dlp_sensor', 'dlp_sensor_status', 'dsri',
'dstaddr6', 'interface', 'ips_sensor',
'ips_sensor_status', 'label', 'logtraffic',
'policyid', 'scan_botnet_connections', 'service6',
'spamfilter_profile', 'spamfilter_profile_status', 'srcaddr6',
'status', 'webfilter_profile', 'webfilter_profile_status']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_interface_policy6(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_interface_policy6'] and data['firewall_interface_policy6']:
state = data['firewall_interface_policy6']['state']
else:
state = True
firewall_interface_policy6_data = data['firewall_interface_policy6']
filtered_data = underscore_to_hyphen(filter_firewall_interface_policy6_data(firewall_interface_policy6_data))
if state == "present":
return fos.set('firewall',
'interface-policy6',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'interface-policy6',
mkey=filtered_data['policyid'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_interface_policy6']:
resp = firewall_interface_policy6(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_interface_policy6": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"address_type": {"required": False, "type": "str",
"choices": ["ipv4", "ipv6"]},
"application_list": {"required": False, "type": "str"},
"application_list_status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"av_profile": {"required": False, "type": "str"},
"av_profile_status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"comments": {"required": False, "type": "str"},
"dlp_sensor": {"required": False, "type": "str"},
"dlp_sensor_status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"dsri": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"dstaddr6": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"interface": {"required": False, "type": "str"},
"ips_sensor": {"required": False, "type": "str"},
"ips_sensor_status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"label": {"required": False, "type": "str"},
"logtraffic": {"required": False, "type": "str",
"choices": ["all", "utm", "disable"]},
"policyid": {"required": True, "type": "int"},
"scan_botnet_connections": {"required": False, "type": "str",
"choices": ["disable", "block", "monitor"]},
"service6": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"spamfilter_profile": {"required": False, "type": "str"},
"spamfilter_profile_status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"srcaddr6": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"webfilter_profile": {"required": False, "type": "str"},
"webfilter_profile_status": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,425 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_internet_service
short_description: Show Internet Service application in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and internet_service category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_internet_service:
description:
- Show Internet Service application.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
database:
description:
- Database name this Internet Service belongs to.
type: str
choices:
- isdb
- irdb
direction:
description:
- How this service may be used in a firewall policy (source, destination or both).
type: str
choices:
- src
- dst
- both
entry:
description:
- Entries in the Internet Service database.
type: list
suboptions:
id:
description:
- Entry ID.
required: true
type: int
ip_number:
description:
- Total number of IP addresses.
type: int
ip_range_number:
description:
- Total number of IP ranges.
type: int
port:
description:
- Integer value for the TCP/IP port (0 - 65535).
type: int
protocol:
description:
- Integer value for the protocol type as defined by IANA (0 - 255).
type: int
icon_id:
description:
- Icon ID of Internet Service.
type: int
id:
description:
- Internet Service ID.
required: true
type: int
name:
description:
- Internet Service name.
type: str
offset:
description:
- Offset of Internet Service ID.
type: int
reputation:
description:
- Reputation level of the Internet Service.
type: int
sld_id:
description:
- Second Level Domain.
type: int
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Show Internet Service application.
fortios_firewall_internet_service:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_internet_service:
database: "isdb"
direction: "src"
entry:
-
id: "6"
ip_number: "7"
ip_range_number: "8"
port: "9"
protocol: "10"
icon_id: "11"
id: "12"
name: "default_name_13"
offset: "14"
reputation: "15"
sld_id: "16"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_internet_service_data(json):
option_list = ['database', 'direction', 'entry',
'icon_id', 'id', 'name',
'offset', 'reputation', 'sld_id']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_internet_service(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_internet_service'] and data['firewall_internet_service']:
state = data['firewall_internet_service']['state']
else:
state = True
firewall_internet_service_data = data['firewall_internet_service']
filtered_data = underscore_to_hyphen(filter_firewall_internet_service_data(firewall_internet_service_data))
if state == "present":
return fos.set('firewall',
'internet-service',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'internet-service',
mkey=filtered_data['id'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_internet_service']:
resp = firewall_internet_service(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_internet_service": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"database": {"required": False, "type": "str",
"choices": ["isdb", "irdb"]},
"direction": {"required": False, "type": "str",
"choices": ["src", "dst", "both"]},
"entry": {"required": False, "type": "list",
"options": {
"id": {"required": True, "type": "int"},
"ip_number": {"required": False, "type": "int"},
"ip_range_number": {"required": False, "type": "int"},
"port": {"required": False, "type": "int"},
"protocol": {"required": False, "type": "int"}
}},
"icon_id": {"required": False, "type": "int"},
"id": {"required": True, "type": "int"},
"name": {"required": False, "type": "str"},
"offset": {"required": False, "type": "int"},
"reputation": {"required": False, "type": "int"},
"sld_id": {"required": False, "type": "int"}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,472 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_internet_service_custom
short_description: Configure custom Internet Services in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and internet_service_custom category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_internet_service_custom:
description:
- Configure custom Internet Services.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
comment:
description:
- Comment.
type: str
disable_entry:
description:
- Disable entries in the Internet Service database.
type: list
suboptions:
id:
description:
- Disable entry ID.
required: true
type: int
ip_range:
description:
- IP ranges in the disable entry.
type: list
suboptions:
end_ip:
description:
- End IP address.
type: str
id:
description:
- Disable entry range ID.
required: true
type: int
start_ip:
description:
- Start IP address.
type: str
port:
description:
- Integer value for the TCP/IP port (0 - 65535).
type: int
protocol:
description:
- Integer value for the protocol type as defined by IANA (0 - 255).
type: int
entry:
description:
- Entries added to the Internet Service database and custom database.
type: list
suboptions:
dst:
description:
- Destination address or address group name.
type: list
suboptions:
name:
description:
- Select the destination address or address group object from available options. Source firewall.address.name firewall
.addrgrp.name.
required: true
type: str
id:
description:
- Entry ID(1-255).
required: true
type: int
port_range:
description:
- Port ranges in the custom entry.
type: list
suboptions:
end_port:
description:
- Integer value for ending TCP/UDP/SCTP destination port in range (1 to 65535).
type: int
id:
description:
- Custom entry port range ID.
required: true
type: int
start_port:
description:
- Integer value for starting TCP/UDP/SCTP destination port in range (1 to 65535).
type: int
protocol:
description:
- Integer value for the protocol type as defined by IANA (0 - 255).
type: int
master_service_id:
description:
- Internet Service ID in the Internet Service database. Source firewall.internet-service.id.
type: int
name:
description:
- Internet Service name.
required: true
type: str
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure custom Internet Services.
fortios_firewall_internet_service_custom:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_internet_service_custom:
comment: "Comment."
disable_entry:
-
id: "5"
ip_range:
-
end_ip: "<your_own_value>"
id: "8"
start_ip: "<your_own_value>"
port: "10"
protocol: "11"
entry:
-
dst:
-
name: "default_name_14 (source firewall.address.name firewall.addrgrp.name)"
id: "15"
port_range:
-
end_port: "17"
id: "18"
start_port: "19"
protocol: "20"
master_service_id: "21 (source firewall.internet-service.id)"
name: "default_name_22"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_internet_service_custom_data(json):
option_list = ['comment', 'disable_entry', 'entry',
'master_service_id', 'name']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_internet_service_custom(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_internet_service_custom'] and data['firewall_internet_service_custom']:
state = data['firewall_internet_service_custom']['state']
else:
state = True
firewall_internet_service_custom_data = data['firewall_internet_service_custom']
filtered_data = underscore_to_hyphen(filter_firewall_internet_service_custom_data(firewall_internet_service_custom_data))
if state == "present":
return fos.set('firewall',
'internet-service-custom',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'internet-service-custom',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_internet_service_custom']:
resp = firewall_internet_service_custom(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_internet_service_custom": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"comment": {"required": False, "type": "str"},
"disable_entry": {"required": False, "type": "list",
"options": {
"id": {"required": True, "type": "int"},
"ip_range": {"required": False, "type": "list",
"options": {
"end_ip": {"required": False, "type": "str"},
"id": {"required": True, "type": "int"},
"start_ip": {"required": False, "type": "str"}
}},
"port": {"required": False, "type": "int"},
"protocol": {"required": False, "type": "int"}
}},
"entry": {"required": False, "type": "list",
"options": {
"dst": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"id": {"required": True, "type": "int"},
"port_range": {"required": False, "type": "list",
"options": {
"end_port": {"required": False, "type": "int"},
"id": {"required": True, "type": "int"},
"start_port": {"required": False, "type": "int"}
}},
"protocol": {"required": False, "type": "int"}
}},
"master_service_id": {"required": False, "type": "int"},
"name": {"required": True, "type": "str"}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,354 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_internet_service_group
short_description: Configure group of Internet Service in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and internet_service_group category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_internet_service_group:
description:
- Configure group of Internet Service.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
comment:
description:
- Comment.
type: str
member:
description:
- Internet Service group member.
type: list
suboptions:
id:
description:
- Internet Service ID. Source firewall.internet-service.id.
required: true
type: int
name:
description:
- Internet Service group name.
required: true
type: str
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure group of Internet Service.
fortios_firewall_internet_service_group:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_internet_service_group:
comment: "Comment."
member:
-
id: "5 (source firewall.internet-service.id)"
name: "default_name_6"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_internet_service_group_data(json):
option_list = ['comment', 'member', 'name']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_internet_service_group(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_internet_service_group'] and data['firewall_internet_service_group']:
state = data['firewall_internet_service_group']['state']
else:
state = True
firewall_internet_service_group_data = data['firewall_internet_service_group']
filtered_data = underscore_to_hyphen(filter_firewall_internet_service_group_data(firewall_internet_service_group_data))
if state == "present":
return fos.set('firewall',
'internet-service-group',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'internet-service-group',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_internet_service_group']:
resp = firewall_internet_service_group(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_internet_service_group": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"comment": {"required": False, "type": "str"},
"member": {"required": False, "type": "list",
"options": {
"id": {"required": True, "type": "int"}
}},
"name": {"required": True, "type": "str"}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,359 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_ip_translation
short_description: Configure firewall IP-translation in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and ip_translation category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_ip_translation:
description:
- Configure firewall IP-translation.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
endip:
description:
- "Final IPv4 address (inclusive) in the range of the addresses to be translated (format xxx.xxx.xxx.xxx)."
type: str
map_startip:
description:
- "Address to be used as the starting point for translation in the range (format xxx.xxx.xxx.xxx)."
type: str
startip:
description:
- "First IPv4 address (inclusive) in the range of the addresses to be translated (format xxx.xxx.xxx.xxx)."
type: str
transid:
description:
- IP translation ID.
required: true
type: int
type:
description:
- "IP translation type (option: SCTP)."
type: str
choices:
- SCTP
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure firewall IP-translation.
fortios_firewall_ip_translation:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_ip_translation:
endip: "<your_own_value>"
map_startip: "<your_own_value>"
startip: "<your_own_value>"
transid: "6"
type: "SCTP"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_ip_translation_data(json):
option_list = ['endip', 'map_startip', 'startip',
'transid', 'type']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_ip_translation(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_ip_translation'] and data['firewall_ip_translation']:
state = data['firewall_ip_translation']['state']
else:
state = True
firewall_ip_translation_data = data['firewall_ip_translation']
filtered_data = underscore_to_hyphen(filter_firewall_ip_translation_data(firewall_ip_translation_data))
if state == "present":
return fos.set('firewall',
'ip-translation',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'ip-translation',
mkey=filtered_data['transid'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_ip_translation']:
resp = firewall_ip_translation(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_ip_translation": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"endip": {"required": False, "type": "str"},
"map_startip": {"required": False, "type": "str"},
"startip": {"required": False, "type": "str"},
"transid": {"required": True, "type": "int"},
"type": {"required": False, "type": "str",
"choices": ["SCTP"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,314 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_ipmacbinding_setting
short_description: Configure IP to MAC binding settings in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall_ipmacbinding feature and setting category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
firewall_ipmacbinding_setting:
description:
- Configure IP to MAC binding settings.
default: null
type: dict
suboptions:
bindthroughfw:
description:
- Enable/disable use of IP/MAC binding to filter packets that would normally go through the firewall.
type: str
choices:
- enable
- disable
bindtofw:
description:
- Enable/disable use of IP/MAC binding to filter packets that would normally go to the firewall.
type: str
choices:
- enable
- disable
undefinedhost:
description:
- Select action to take on packets with IP/MAC addresses not in the binding list .
type: str
choices:
- allow
- block
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure IP to MAC binding settings.
fortios_firewall_ipmacbinding_setting:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
firewall_ipmacbinding_setting:
bindthroughfw: "enable"
bindtofw: "enable"
undefinedhost: "allow"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_ipmacbinding_setting_data(json):
option_list = ['bindthroughfw', 'bindtofw', 'undefinedhost']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_ipmacbinding_setting(data, fos):
vdom = data['vdom']
firewall_ipmacbinding_setting_data = data['firewall_ipmacbinding_setting']
filtered_data = underscore_to_hyphen(filter_firewall_ipmacbinding_setting_data(firewall_ipmacbinding_setting_data))
return fos.set('firewall.ipmacbinding',
'setting',
data=filtered_data,
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall_ipmacbinding(data, fos):
if data['firewall_ipmacbinding_setting']:
resp = firewall_ipmacbinding_setting(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"firewall_ipmacbinding_setting": {
"required": False, "type": "dict", "default": None,
"options": {
"bindthroughfw": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"bindtofw": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"undefinedhost": {"required": False, "type": "str",
"choices": ["allow", "block"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall_ipmacbinding(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall_ipmacbinding(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,359 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_ipmacbinding_table
short_description: Configure IP to MAC address pairs in the IP/MAC binding table in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall_ipmacbinding feature and table category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_ipmacbinding_table:
description:
- Configure IP to MAC address pairs in the IP/MAC binding table.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
ip:
description:
- "IPv4 address portion of the pair (format: xxx.xxx.xxx.xxx)."
type: str
mac:
description:
- "MAC address portion of the pair (format: xx:xx:xx:xx:xx:xx in hexidecimal)."
type: str
name:
description:
- Name of the pair (optional).
type: str
seq_num:
description:
- Entry number.
type: int
status:
description:
- Enable/disable this IP-mac binding pair.
type: str
choices:
- enable
- disable
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure IP to MAC address pairs in the IP/MAC binding table.
fortios_firewall_ipmacbinding_table:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_ipmacbinding_table:
ip: "<your_own_value>"
mac: "<your_own_value>"
name: "default_name_5"
seq_num: "6"
status: "enable"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_ipmacbinding_table_data(json):
option_list = ['ip', 'mac', 'name',
'seq_num', 'status']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_ipmacbinding_table(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_ipmacbinding_table'] and data['firewall_ipmacbinding_table']:
state = data['firewall_ipmacbinding_table']['state']
else:
state = True
firewall_ipmacbinding_table_data = data['firewall_ipmacbinding_table']
filtered_data = underscore_to_hyphen(filter_firewall_ipmacbinding_table_data(firewall_ipmacbinding_table_data))
if state == "present":
return fos.set('firewall.ipmacbinding',
'table',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall.ipmacbinding',
'table',
mkey=filtered_data['seq-num'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall_ipmacbinding(data, fos):
if data['firewall_ipmacbinding_table']:
resp = firewall_ipmacbinding_table(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_ipmacbinding_table": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"ip": {"required": False, "type": "str"},
"mac": {"required": False, "type": "str"},
"name": {"required": False, "type": "str"},
"seq_num": {"required": False, "type": "int"},
"status": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall_ipmacbinding(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall_ipmacbinding(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,428 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_ippool
short_description: Configure IPv4 IP pools in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and ippool category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_ippool:
description:
- Configure IPv4 IP pools.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
arp_intf:
description:
- Select an interface from available options that will reply to ARP requests. (If blank, any is selected). Source system.interface.name.
type: str
arp_reply:
description:
- Enable/disable replying to ARP requests when an IP Pool is added to a policy .
type: str
choices:
- disable
- enable
associated_interface:
description:
- Associated interface name. Source system.interface.name.
type: str
block_size:
description:
- Number of addresses in a block (64 to 4096).
type: int
comments:
description:
- Comment.
type: str
endip:
description:
- "Final IPv4 address (inclusive) in the range for the address pool (format xxx.xxx.xxx.xxx)."
type: str
name:
description:
- IP pool name.
required: true
type: str
num_blocks_per_user:
description:
- Number of addresses blocks that can be used by a user (1 to 128).
type: int
pba_timeout:
description:
- Port block allocation timeout (seconds).
type: int
permit_any_host:
description:
- Enable/disable full cone NAT.
type: str
choices:
- disable
- enable
source_endip:
description:
- "Final IPv4 address (inclusive) in the range of the source addresses to be translated (format xxx.xxx.xxx.xxx)."
type: str
source_startip:
description:
- " First IPv4 address (inclusive) in the range of the source addresses to be translated (format xxx.xxx.xxx.xxx)."
type: str
startip:
description:
- "First IPv4 address (inclusive) in the range for the address pool (format xxx.xxx.xxx.xxx)."
type: str
type:
description:
- IP pool type (overload, one-to-one, fixed port range, or port block allocation).
type: str
choices:
- overload
- one-to-one
- fixed-port-range
- port-block-allocation
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure IPv4 IP pools.
fortios_firewall_ippool:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_ippool:
arp_intf: "<your_own_value> (source system.interface.name)"
arp_reply: "disable"
associated_interface: "<your_own_value> (source system.interface.name)"
block_size: "6"
comments: "<your_own_value>"
endip: "<your_own_value>"
name: "default_name_9"
num_blocks_per_user: "10"
pba_timeout: "11"
permit_any_host: "disable"
source_endip: "<your_own_value>"
source_startip: "<your_own_value>"
startip: "<your_own_value>"
type: "overload"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_ippool_data(json):
option_list = ['arp_intf', 'arp_reply', 'associated_interface',
'block_size', 'comments', 'endip',
'name', 'num_blocks_per_user', 'pba_timeout',
'permit_any_host', 'source_endip', 'source_startip',
'startip', 'type']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_ippool(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_ippool'] and data['firewall_ippool']:
state = data['firewall_ippool']['state']
else:
state = True
firewall_ippool_data = data['firewall_ippool']
filtered_data = underscore_to_hyphen(filter_firewall_ippool_data(firewall_ippool_data))
if state == "present":
return fos.set('firewall',
'ippool',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'ippool',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_ippool']:
resp = firewall_ippool(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_ippool": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"arp_intf": {"required": False, "type": "str"},
"arp_reply": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"associated_interface": {"required": False, "type": "str"},
"block_size": {"required": False, "type": "int"},
"comments": {"required": False, "type": "str"},
"endip": {"required": False, "type": "str"},
"name": {"required": True, "type": "str"},
"num_blocks_per_user": {"required": False, "type": "int"},
"pba_timeout": {"required": False, "type": "int"},
"permit_any_host": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"source_endip": {"required": False, "type": "str"},
"source_startip": {"required": False, "type": "str"},
"startip": {"required": False, "type": "str"},
"type": {"required": False, "type": "str",
"choices": ["overload", "one-to-one", "fixed-port-range",
"port-block-allocation"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,350 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_ippool6
short_description: Configure IPv6 IP pools in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and ippool6 category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_ippool6:
description:
- Configure IPv6 IP pools.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
comments:
description:
- Comment.
type: str
endip:
description:
- "Final IPv6 address (inclusive) in the range for the address pool (format xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx)."
type: str
name:
description:
- IPv6 IP pool name.
required: true
type: str
startip:
description:
- "First IPv6 address (inclusive) in the range for the address pool (format xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx)."
type: str
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure IPv6 IP pools.
fortios_firewall_ippool6:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_ippool6:
comments: "<your_own_value>"
endip: "<your_own_value>"
name: "default_name_5"
startip: "<your_own_value>"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_ippool6_data(json):
option_list = ['comments', 'endip', 'name',
'startip']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_ippool6(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_ippool6'] and data['firewall_ippool6']:
state = data['firewall_ippool6']['state']
else:
state = True
firewall_ippool6_data = data['firewall_ippool6']
filtered_data = underscore_to_hyphen(filter_firewall_ippool6_data(firewall_ippool6_data))
if state == "present":
return fos.set('firewall',
'ippool6',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'ippool6',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_ippool6']:
resp = firewall_ippool6(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_ippool6": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"comments": {"required": False, "type": "str"},
"endip": {"required": False, "type": "str"},
"name": {"required": True, "type": "str"},
"startip": {"required": False, "type": "str"}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,358 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_ipv6_eh_filter
short_description: Configure IPv6 extension header filter in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and ipv6_eh_filter category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
firewall_ipv6_eh_filter:
description:
- Configure IPv6 extension header filter.
default: null
type: dict
suboptions:
auth:
description:
- Enable/disable blocking packets with the Authentication header .
type: str
choices:
- enable
- disable
dest_opt:
description:
- Enable/disable blocking packets with Destination Options headers .
type: str
choices:
- enable
- disable
fragment:
description:
- Enable/disable blocking packets with the Fragment header .
type: str
choices:
- enable
- disable
hdopt_type:
description:
- Block specific Hop-by-Hop and/or Destination Option types (max. 7 types, each between 0 and 255).
type: int
hop_opt:
description:
- Enable/disable blocking packets with the Hop-by-Hop Options header .
type: str
choices:
- enable
- disable
no_next:
description:
- Enable/disable blocking packets with the No Next header
type: str
choices:
- enable
- disable
routing:
description:
- Enable/disable blocking packets with Routing headers .
type: str
choices:
- enable
- disable
routing_type:
description:
- Block specific Routing header types (max. 7 types, each between 0 and 255).
type: int
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure IPv6 extension header filter.
fortios_firewall_ipv6_eh_filter:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
firewall_ipv6_eh_filter:
auth: "enable"
dest_opt: "enable"
fragment: "enable"
hdopt_type: "6"
hop_opt: "enable"
no_next: "enable"
routing: "enable"
routing_type: "10"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_ipv6_eh_filter_data(json):
option_list = ['auth', 'dest_opt', 'fragment',
'hdopt_type', 'hop_opt', 'no_next',
'routing', 'routing_type']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_ipv6_eh_filter(data, fos):
vdom = data['vdom']
firewall_ipv6_eh_filter_data = data['firewall_ipv6_eh_filter']
filtered_data = underscore_to_hyphen(filter_firewall_ipv6_eh_filter_data(firewall_ipv6_eh_filter_data))
return fos.set('firewall',
'ipv6-eh-filter',
data=filtered_data,
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_ipv6_eh_filter']:
resp = firewall_ipv6_eh_filter(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"firewall_ipv6_eh_filter": {
"required": False, "type": "dict", "default": None,
"options": {
"auth": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"dest_opt": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"fragment": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"hdopt_type": {"required": False, "type": "int"},
"hop_opt": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"no_next": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"routing": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"routing_type": {"required": False, "type": "int"}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,388 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_ldb_monitor
short_description: Configure server load balancing health monitors in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and ldb_monitor category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_ldb_monitor:
description:
- Configure server load balancing health monitors.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
http_get:
description:
- URL used to send a GET request to check the health of an HTTP server.
type: str
http_match:
description:
- String to match the value expected in response to an HTTP-GET request.
type: str
http_max_redirects:
description:
- The maximum number of HTTP redirects to be allowed (0 - 5).
type: int
interval:
description:
- Time between health checks (5 - 65635 sec).
type: int
name:
description:
- Monitor name.
required: true
type: str
port:
description:
- Service port used to perform the health check. If 0, health check monitor inherits port configured for the server (0 - 65635).
type: int
retry:
description:
- Number health check attempts before the server is considered down (1 - 255).
type: int
timeout:
description:
- Time to wait to receive response to a health check from a server. Reaching the timeout means the health check failed (1 - 255 sec).
type: int
type:
description:
- Select the Monitor type used by the health check monitor to check the health of the server (PING | TCP | HTTP).
type: str
choices:
- ping
- tcp
- http
- passive-sip
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure server load balancing health monitors.
fortios_firewall_ldb_monitor:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_ldb_monitor:
http_get: "<your_own_value>"
http_match: "<your_own_value>"
http_max_redirects: "5"
interval: "6"
name: "default_name_7"
port: "8"
retry: "9"
timeout: "10"
type: "ping"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_ldb_monitor_data(json):
option_list = ['http_get', 'http_match', 'http_max_redirects',
'interval', 'name', 'port',
'retry', 'timeout', 'type']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_ldb_monitor(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_ldb_monitor'] and data['firewall_ldb_monitor']:
state = data['firewall_ldb_monitor']['state']
else:
state = True
firewall_ldb_monitor_data = data['firewall_ldb_monitor']
filtered_data = underscore_to_hyphen(filter_firewall_ldb_monitor_data(firewall_ldb_monitor_data))
if state == "present":
return fos.set('firewall',
'ldb-monitor',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'ldb-monitor',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_ldb_monitor']:
resp = firewall_ldb_monitor(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_ldb_monitor": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"http_get": {"required": False, "type": "str"},
"http_match": {"required": False, "type": "str"},
"http_max_redirects": {"required": False, "type": "int"},
"interval": {"required": False, "type": "int"},
"name": {"required": True, "type": "str"},
"port": {"required": False, "type": "int"},
"retry": {"required": False, "type": "int"},
"timeout": {"required": False, "type": "int"},
"type": {"required": False, "type": "str",
"choices": ["ping", "tcp", "http",
"passive-sip"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,434 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_local_in_policy
short_description: Configure user defined IPv4 local-in policies in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and local_in_policy category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_local_in_policy:
description:
- Configure user defined IPv4 local-in policies.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
action:
description:
- Action performed on traffic matching the policy .
type: str
choices:
- accept
- deny
comments:
description:
- Comment.
type: str
dstaddr:
description:
- Destination address object from available options.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address.name firewall.addrgrp.name.
required: true
type: str
ha_mgmt_intf_only:
description:
- Enable/disable dedicating the HA management interface only for local-in policy.
type: str
choices:
- enable
- disable
intf:
description:
- Incoming interface name from available options. Source system.zone.name system.interface.name.
type: str
policyid:
description:
- User defined local in policy ID.
required: true
type: int
schedule:
description:
- Schedule object from available options. Source firewall.schedule.onetime.name firewall.schedule.recurring.name firewall.schedule.group
.name.
type: str
service:
description:
- Service object from available options.
type: list
suboptions:
name:
description:
- Service name. Source firewall.service.custom.name firewall.service.group.name.
required: true
type: str
srcaddr:
description:
- Source address object from available options.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address.name firewall.addrgrp.name.
required: true
type: str
status:
description:
- Enable/disable this local-in policy.
type: str
choices:
- enable
- disable
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure user defined IPv4 local-in policies.
fortios_firewall_local_in_policy:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_local_in_policy:
action: "accept"
comments: "<your_own_value>"
dstaddr:
-
name: "default_name_6 (source firewall.address.name firewall.addrgrp.name)"
ha_mgmt_intf_only: "enable"
intf: "<your_own_value> (source system.zone.name system.interface.name)"
policyid: "9"
schedule: "<your_own_value> (source firewall.schedule.onetime.name firewall.schedule.recurring.name firewall.schedule.group.name)"
service:
-
name: "default_name_12 (source firewall.service.custom.name firewall.service.group.name)"
srcaddr:
-
name: "default_name_14 (source firewall.address.name firewall.addrgrp.name)"
status: "enable"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_local_in_policy_data(json):
option_list = ['action', 'comments', 'dstaddr',
'ha_mgmt_intf_only', 'intf', 'policyid',
'schedule', 'service', 'srcaddr',
'status']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_local_in_policy(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_local_in_policy'] and data['firewall_local_in_policy']:
state = data['firewall_local_in_policy']['state']
else:
state = True
firewall_local_in_policy_data = data['firewall_local_in_policy']
filtered_data = underscore_to_hyphen(filter_firewall_local_in_policy_data(firewall_local_in_policy_data))
if state == "present":
return fos.set('firewall',
'local-in-policy',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'local-in-policy',
mkey=filtered_data['policyid'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_local_in_policy']:
resp = firewall_local_in_policy(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_local_in_policy": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"action": {"required": False, "type": "str",
"choices": ["accept", "deny"]},
"comments": {"required": False, "type": "str"},
"dstaddr": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"ha_mgmt_intf_only": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"intf": {"required": False, "type": "str"},
"policyid": {"required": True, "type": "int"},
"schedule": {"required": False, "type": "str"},
"service": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"srcaddr": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"status": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,423 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_local_in_policy6
short_description: Configure user defined IPv6 local-in policies in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and local_in_policy6 category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_local_in_policy6:
description:
- Configure user defined IPv6 local-in policies.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
action:
description:
- Action performed on traffic matching the policy .
type: str
choices:
- accept
- deny
comments:
description:
- Comment.
type: str
dstaddr:
description:
- Destination address object from available options.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address6.name firewall.addrgrp6.name.
required: true
type: str
intf:
description:
- Incoming interface name from available options. Source system.zone.name system.interface.name.
type: str
policyid:
description:
- User defined local in policy ID.
required: true
type: int
schedule:
description:
- Schedule object from available options. Source firewall.schedule.onetime.name firewall.schedule.recurring.name firewall.schedule.group
.name.
type: str
service:
description:
- Service object from available options. Separate names with a space.
type: list
suboptions:
name:
description:
- Service name. Source firewall.service.custom.name firewall.service.group.name.
required: true
type: str
srcaddr:
description:
- Source address object from available options.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address6.name firewall.addrgrp6.name.
required: true
type: str
status:
description:
- Enable/disable this local-in policy.
type: str
choices:
- enable
- disable
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure user defined IPv6 local-in policies.
fortios_firewall_local_in_policy6:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_local_in_policy6:
action: "accept"
comments: "<your_own_value>"
dstaddr:
-
name: "default_name_6 (source firewall.address6.name firewall.addrgrp6.name)"
intf: "<your_own_value> (source system.zone.name system.interface.name)"
policyid: "8"
schedule: "<your_own_value> (source firewall.schedule.onetime.name firewall.schedule.recurring.name firewall.schedule.group.name)"
service:
-
name: "default_name_11 (source firewall.service.custom.name firewall.service.group.name)"
srcaddr:
-
name: "default_name_13 (source firewall.address6.name firewall.addrgrp6.name)"
status: "enable"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_local_in_policy6_data(json):
option_list = ['action', 'comments', 'dstaddr',
'intf', 'policyid', 'schedule',
'service', 'srcaddr', 'status']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_local_in_policy6(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_local_in_policy6'] and data['firewall_local_in_policy6']:
state = data['firewall_local_in_policy6']['state']
else:
state = True
firewall_local_in_policy6_data = data['firewall_local_in_policy6']
filtered_data = underscore_to_hyphen(filter_firewall_local_in_policy6_data(firewall_local_in_policy6_data))
if state == "present":
return fos.set('firewall',
'local-in-policy6',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'local-in-policy6',
mkey=filtered_data['policyid'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_local_in_policy6']:
resp = firewall_local_in_policy6(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_local_in_policy6": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"action": {"required": False, "type": "str",
"choices": ["accept", "deny"]},
"comments": {"required": False, "type": "str"},
"dstaddr": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"intf": {"required": False, "type": "str"},
"policyid": {"required": True, "type": "int"},
"schedule": {"required": False, "type": "str"},
"service": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"srcaddr": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"status": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,431 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_multicast_address
short_description: Configure multicast addresses in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and multicast_address category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_multicast_address:
description:
- Configure multicast addresses.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
associated_interface:
description:
- Interface associated with the address object. When setting up a policy, only addresses associated with this interface are available.
Source system.interface.name.
type: str
color:
description:
- Integer value to determine the color of the icon in the GUI (1 - 32).
type: int
comment:
description:
- Comment.
type: str
end_ip:
description:
- Final IPv4 address (inclusive) in the range for the address.
type: str
name:
description:
- Multicast address name.
required: true
type: str
start_ip:
description:
- First IPv4 address (inclusive) in the range for the address.
type: str
subnet:
description:
- Broadcast address and subnet.
type: str
tagging:
description:
- Config object tagging.
type: list
suboptions:
category:
description:
- Tag category. Source system.object-tagging.category.
type: str
name:
description:
- Tagging entry name.
required: true
type: str
tags:
description:
- Tags.
type: list
suboptions:
name:
description:
- Tag name. Source system.object-tagging.tags.name.
required: true
type: str
type:
description:
- "Type of address object: multicast IP address range or broadcast IP/mask to be treated as a multicast address."
type: str
choices:
- multicastrange
- broadcastmask
visibility:
description:
- Enable/disable visibility of the multicast address on the GUI.
type: str
choices:
- enable
- disable
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure multicast addresses.
fortios_firewall_multicast_address:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_multicast_address:
associated_interface: "<your_own_value> (source system.interface.name)"
color: "4"
comment: "Comment."
end_ip: "<your_own_value>"
name: "default_name_7"
start_ip: "<your_own_value>"
subnet: "<your_own_value>"
tagging:
-
category: "<your_own_value> (source system.object-tagging.category)"
name: "default_name_12"
tags:
-
name: "default_name_14 (source system.object-tagging.tags.name)"
type: "multicastrange"
visibility: "enable"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_multicast_address_data(json):
option_list = ['associated_interface', 'color', 'comment',
'end_ip', 'name', 'start_ip',
'subnet', 'tagging', 'type',
'visibility']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_multicast_address(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_multicast_address'] and data['firewall_multicast_address']:
state = data['firewall_multicast_address']['state']
else:
state = True
firewall_multicast_address_data = data['firewall_multicast_address']
filtered_data = underscore_to_hyphen(filter_firewall_multicast_address_data(firewall_multicast_address_data))
if state == "present":
return fos.set('firewall',
'multicast-address',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'multicast-address',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_multicast_address']:
resp = firewall_multicast_address(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_multicast_address": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"associated_interface": {"required": False, "type": "str"},
"color": {"required": False, "type": "int"},
"comment": {"required": False, "type": "str"},
"end_ip": {"required": False, "type": "str"},
"name": {"required": True, "type": "str"},
"start_ip": {"required": False, "type": "str"},
"subnet": {"required": False, "type": "str"},
"tagging": {"required": False, "type": "list",
"options": {
"category": {"required": False, "type": "str"},
"name": {"required": True, "type": "str"},
"tags": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}}
}},
"type": {"required": False, "type": "str",
"choices": ["multicastrange", "broadcastmask"]},
"visibility": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,400 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_multicast_address6
short_description: Configure IPv6 multicast address in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and multicast_address6 category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_multicast_address6:
description:
- Configure IPv6 multicast address.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
color:
description:
- Color of icon on the GUI.
type: int
comment:
description:
- Comment.
type: str
ip6:
description:
- "IPv6 address prefix (format: xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx/xxx)."
type: str
name:
description:
- IPv6 multicast address name.
required: true
type: str
tagging:
description:
- Config object tagging.
type: list
suboptions:
category:
description:
- Tag category. Source system.object-tagging.category.
type: str
name:
description:
- Tagging entry name.
required: true
type: str
tags:
description:
- Tags.
type: list
suboptions:
name:
description:
- Tag name. Source system.object-tagging.tags.name.
required: true
type: str
visibility:
description:
- Enable/disable visibility of the IPv6 multicast address on the GUI.
type: str
choices:
- enable
- disable
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure IPv6 multicast address.
fortios_firewall_multicast_address6:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_multicast_address6:
color: "3"
comment: "Comment."
ip6: "<your_own_value>"
name: "default_name_6"
tagging:
-
category: "<your_own_value> (source system.object-tagging.category)"
name: "default_name_9"
tags:
-
name: "default_name_11 (source system.object-tagging.tags.name)"
visibility: "enable"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_multicast_address6_data(json):
option_list = ['color', 'comment', 'ip6',
'name', 'tagging', 'visibility']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_multicast_address6(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_multicast_address6'] and data['firewall_multicast_address6']:
state = data['firewall_multicast_address6']['state']
else:
state = True
firewall_multicast_address6_data = data['firewall_multicast_address6']
filtered_data = underscore_to_hyphen(filter_firewall_multicast_address6_data(firewall_multicast_address6_data))
if state == "present":
return fos.set('firewall',
'multicast-address6',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'multicast-address6',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_multicast_address6']:
resp = firewall_multicast_address6(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_multicast_address6": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"color": {"required": False, "type": "int"},
"comment": {"required": False, "type": "str"},
"ip6": {"required": False, "type": "str"},
"name": {"required": True, "type": "str"},
"tagging": {"required": False, "type": "list",
"options": {
"category": {"required": False, "type": "str"},
"name": {"required": True, "type": "str"},
"tags": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}}
}},
"visibility": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,451 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_multicast_policy
short_description: Configure multicast NAT policies in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and multicast_policy category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_multicast_policy:
description:
- Configure multicast NAT policies.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
action:
description:
- Accept or deny traffic matching the policy.
type: str
choices:
- accept
- deny
dnat:
description:
- IPv4 DNAT address used for multicast destination addresses.
type: str
dstaddr:
description:
- Destination address objects.
type: list
suboptions:
name:
description:
- Destination address objects. Source firewall.multicast-address.name.
required: true
type: str
dstintf:
description:
- Destination interface name. Source system.interface.name system.zone.name.
type: str
end_port:
description:
- Integer value for ending TCP/UDP/SCTP destination port in range (1 - 65535).
type: int
id:
description:
- Policy ID.
required: true
type: int
logtraffic:
description:
- Enable/disable logging traffic accepted by this policy.
type: str
choices:
- enable
- disable
protocol:
description:
- Integer value for the protocol type as defined by IANA (0 - 255).
type: int
snat:
description:
- Enable/disable substitution of the outgoing interface IP address for the original source IP address (called source NAT or SNAT).
type: str
choices:
- enable
- disable
snat_ip:
description:
- IPv4 address to be used as the source address for NATed traffic.
type: str
srcaddr:
description:
- Source address objects.
type: list
suboptions:
name:
description:
- Source address objects. Source firewall.address.name firewall.addrgrp.name.
required: true
type: str
srcintf:
description:
- Source interface name. Source system.interface.name system.zone.name.
type: str
start_port:
description:
- Integer value for starting TCP/UDP/SCTP destination port in range (1 - 65535).
type: int
status:
description:
- Enable/disable this policy.
type: str
choices:
- enable
- disable
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure multicast NAT policies.
fortios_firewall_multicast_policy:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_multicast_policy:
action: "accept"
dnat: "<your_own_value>"
dstaddr:
-
name: "default_name_6 (source firewall.multicast-address.name)"
dstintf: "<your_own_value> (source system.interface.name system.zone.name)"
end_port: "8"
id: "9"
logtraffic: "enable"
protocol: "11"
snat: "enable"
snat_ip: "<your_own_value>"
srcaddr:
-
name: "default_name_15 (source firewall.address.name firewall.addrgrp.name)"
srcintf: "<your_own_value> (source system.interface.name system.zone.name)"
start_port: "17"
status: "enable"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_multicast_policy_data(json):
option_list = ['action', 'dnat', 'dstaddr',
'dstintf', 'end_port', 'id',
'logtraffic', 'protocol', 'snat',
'snat_ip', 'srcaddr', 'srcintf',
'start_port', 'status']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_multicast_policy(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_multicast_policy'] and data['firewall_multicast_policy']:
state = data['firewall_multicast_policy']['state']
else:
state = True
firewall_multicast_policy_data = data['firewall_multicast_policy']
filtered_data = underscore_to_hyphen(filter_firewall_multicast_policy_data(firewall_multicast_policy_data))
if state == "present":
return fos.set('firewall',
'multicast-policy',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'multicast-policy',
mkey=filtered_data['id'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_multicast_policy']:
resp = firewall_multicast_policy(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_multicast_policy": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"action": {"required": False, "type": "str",
"choices": ["accept", "deny"]},
"dnat": {"required": False, "type": "str"},
"dstaddr": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"dstintf": {"required": False, "type": "str"},
"end_port": {"required": False, "type": "int"},
"id": {"required": True, "type": "int"},
"logtraffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"protocol": {"required": False, "type": "int"},
"snat": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"snat_ip": {"required": False, "type": "str"},
"srcaddr": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"srcintf": {"required": False, "type": "str"},
"start_port": {"required": False, "type": "int"},
"status": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,428 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_multicast_policy6
short_description: Configure IPv6 multicast NAT policies in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and multicast_policy6 category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_multicast_policy6:
description:
- Configure IPv6 multicast NAT policies.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
action:
description:
- Accept or deny traffic matching the policy.
type: str
choices:
- accept
- deny
dstaddr:
description:
- IPv6 destination address name.
type: list
suboptions:
name:
description:
- Address name. Source firewall.multicast-address6.name.
required: true
type: str
dstintf:
description:
- IPv6 destination interface name. Source system.interface.name system.zone.name.
type: str
end_port:
description:
- Integer value for ending TCP/UDP/SCTP destination port in range (1 - 65535).
type: int
id:
description:
- Policy ID.
required: true
type: int
logtraffic:
description:
- Enable/disable logging traffic accepted by this policy.
type: str
choices:
- enable
- disable
protocol:
description:
- Integer value for the protocol type as defined by IANA (0 - 255).
type: int
srcaddr:
description:
- IPv6 source address name.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address6.name firewall.addrgrp6.name.
required: true
type: str
srcintf:
description:
- IPv6 source interface name. Source system.interface.name system.zone.name.
type: str
start_port:
description:
- Integer value for starting TCP/UDP/SCTP destination port in range (1 - 65535).
type: int
status:
description:
- Enable/disable this policy.
type: str
choices:
- enable
- disable
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure IPv6 multicast NAT policies.
fortios_firewall_multicast_policy6:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_multicast_policy6:
action: "accept"
dstaddr:
-
name: "default_name_5 (source firewall.multicast-address6.name)"
dstintf: "<your_own_value> (source system.interface.name system.zone.name)"
end_port: "7"
id: "8"
logtraffic: "enable"
protocol: "10"
srcaddr:
-
name: "default_name_12 (source firewall.address6.name firewall.addrgrp6.name)"
srcintf: "<your_own_value> (source system.interface.name system.zone.name)"
start_port: "14"
status: "enable"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_multicast_policy6_data(json):
option_list = ['action', 'dstaddr', 'dstintf',
'end_port', 'id', 'logtraffic',
'protocol', 'srcaddr', 'srcintf',
'start_port', 'status']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_multicast_policy6(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_multicast_policy6'] and data['firewall_multicast_policy6']:
state = data['firewall_multicast_policy6']['state']
else:
state = True
firewall_multicast_policy6_data = data['firewall_multicast_policy6']
filtered_data = underscore_to_hyphen(filter_firewall_multicast_policy6_data(firewall_multicast_policy6_data))
if state == "present":
return fos.set('firewall',
'multicast-policy6',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'multicast-policy6',
mkey=filtered_data['id'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_multicast_policy6']:
resp = firewall_multicast_policy6(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_multicast_policy6": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"action": {"required": False, "type": "str",
"choices": ["accept", "deny"]},
"dstaddr": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"dstintf": {"required": False, "type": "str"},
"end_port": {"required": False, "type": "int"},
"id": {"required": True, "type": "int"},
"logtraffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"protocol": {"required": False, "type": "int"},
"srcaddr": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"srcintf": {"required": False, "type": "str"},
"start_port": {"required": False, "type": "int"},
"status": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,525 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_policy46
short_description: Configure IPv4 to IPv6 policies in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and policy46 category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_policy46:
description:
- Configure IPv4 to IPv6 policies.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
action:
description:
- Accept or deny traffic matching the policy.
type: str
choices:
- accept
- deny
comments:
description:
- Comment.
type: str
dstaddr:
description:
- Destination address objects.
type: list
suboptions:
name:
description:
- Address name. Source firewall.vip46.name firewall.vipgrp46.name.
required: true
type: str
dstintf:
description:
- Destination interface name. Source system.interface.name system.zone.name.
type: str
fixedport:
description:
- Enable/disable fixed port for this policy.
type: str
choices:
- enable
- disable
ippool:
description:
- Enable/disable use of IP Pools for source NAT.
type: str
choices:
- enable
- disable
logtraffic:
description:
- Enable/disable traffic logging for this policy.
type: str
choices:
- enable
- disable
per_ip_shaper:
description:
- Per IP traffic shaper. Source firewall.shaper.per-ip-shaper.name.
type: str
permit_any_host:
description:
- Enable/disable allowing any host.
type: str
choices:
- enable
- disable
policyid:
description:
- Policy ID.
required: true
type: int
poolname:
description:
- IP Pool names.
type: list
suboptions:
name:
description:
- IP pool name. Source firewall.ippool6.name.
required: true
type: str
schedule:
description:
- Schedule name. Source firewall.schedule.onetime.name firewall.schedule.recurring.name firewall.schedule.group.name.
type: str
service:
description:
- Service name.
type: list
suboptions:
name:
description:
- Service name. Source firewall.service.custom.name firewall.service.group.name.
required: true
type: str
srcaddr:
description:
- Source address objects.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address.name firewall.addrgrp.name.
required: true
type: str
srcintf:
description:
- Source interface name. Source system.zone.name system.interface.name.
type: str
status:
description:
- Enable/disable this policy.
type: str
choices:
- enable
- disable
tcp_mss_receiver:
description:
- TCP Maximum Segment Size value of receiver (0 - 65535)
type: int
tcp_mss_sender:
description:
- TCP Maximum Segment Size value of sender (0 - 65535).
type: int
traffic_shaper:
description:
- Traffic shaper. Source firewall.shaper.traffic-shaper.name.
type: str
traffic_shaper_reverse:
description:
- Reverse traffic shaper. Source firewall.shaper.traffic-shaper.name.
type: str
uuid:
description:
- Universally Unique Identifier (UUID; automatically assigned but can be manually reset).
type: str
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure IPv4 to IPv6 policies.
fortios_firewall_policy46:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_policy46:
action: "accept"
comments: "<your_own_value>"
dstaddr:
-
name: "default_name_6 (source firewall.vip46.name firewall.vipgrp46.name)"
dstintf: "<your_own_value> (source system.interface.name system.zone.name)"
fixedport: "enable"
ippool: "enable"
logtraffic: "enable"
per_ip_shaper: "<your_own_value> (source firewall.shaper.per-ip-shaper.name)"
permit_any_host: "enable"
policyid: "13"
poolname:
-
name: "default_name_15 (source firewall.ippool6.name)"
schedule: "<your_own_value> (source firewall.schedule.onetime.name firewall.schedule.recurring.name firewall.schedule.group.name)"
service:
-
name: "default_name_18 (source firewall.service.custom.name firewall.service.group.name)"
srcaddr:
-
name: "default_name_20 (source firewall.address.name firewall.addrgrp.name)"
srcintf: "<your_own_value> (source system.zone.name system.interface.name)"
status: "enable"
tcp_mss_receiver: "23"
tcp_mss_sender: "24"
traffic_shaper: "<your_own_value> (source firewall.shaper.traffic-shaper.name)"
traffic_shaper_reverse: "<your_own_value> (source firewall.shaper.traffic-shaper.name)"
uuid: "<your_own_value>"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_policy46_data(json):
option_list = ['action', 'comments', 'dstaddr',
'dstintf', 'fixedport', 'ippool',
'logtraffic', 'per_ip_shaper', 'permit_any_host',
'policyid', 'poolname', 'schedule',
'service', 'srcaddr', 'srcintf',
'status', 'tcp_mss_receiver', 'tcp_mss_sender',
'traffic_shaper', 'traffic_shaper_reverse', 'uuid']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_policy46(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_policy46'] and data['firewall_policy46']:
state = data['firewall_policy46']['state']
else:
state = True
firewall_policy46_data = data['firewall_policy46']
filtered_data = underscore_to_hyphen(filter_firewall_policy46_data(firewall_policy46_data))
if state == "present":
return fos.set('firewall',
'policy46',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'policy46',
mkey=filtered_data['policyid'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_policy46']:
resp = firewall_policy46(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_policy46": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"action": {"required": False, "type": "str",
"choices": ["accept", "deny"]},
"comments": {"required": False, "type": "str"},
"dstaddr": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"dstintf": {"required": False, "type": "str"},
"fixedport": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"ippool": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"logtraffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"per_ip_shaper": {"required": False, "type": "str"},
"permit_any_host": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"policyid": {"required": True, "type": "int"},
"poolname": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"schedule": {"required": False, "type": "str"},
"service": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"srcaddr": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"srcintf": {"required": False, "type": "str"},
"status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"tcp_mss_receiver": {"required": False, "type": "int"},
"tcp_mss_sender": {"required": False, "type": "int"},
"traffic_shaper": {"required": False, "type": "str"},
"traffic_shaper_reverse": {"required": False, "type": "str"},
"uuid": {"required": False, "type": "str"}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,525 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_policy64
short_description: Configure IPv6 to IPv4 policies in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and policy64 category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_policy64:
description:
- Configure IPv6 to IPv4 policies.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
action:
description:
- Policy action.
type: str
choices:
- accept
- deny
comments:
description:
- Comment.
type: str
dstaddr:
description:
- Destination address name.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address.name firewall.addrgrp.name firewall.vip64.name firewall.vipgrp64.name.
required: true
type: str
dstintf:
description:
- Destination interface name. Source system.interface.name system.zone.name.
type: str
fixedport:
description:
- Enable/disable policy fixed port.
type: str
choices:
- enable
- disable
ippool:
description:
- Enable/disable policy64 IP pool.
type: str
choices:
- enable
- disable
logtraffic:
description:
- Enable/disable policy log traffic.
type: str
choices:
- enable
- disable
per_ip_shaper:
description:
- Per-IP traffic shaper. Source firewall.shaper.per-ip-shaper.name.
type: str
permit_any_host:
description:
- Enable/disable permit any host in.
type: str
choices:
- enable
- disable
policyid:
description:
- Policy ID.
required: true
type: int
poolname:
description:
- Policy IP pool names.
type: list
suboptions:
name:
description:
- IP pool name. Source firewall.ippool.name.
required: true
type: str
schedule:
description:
- Schedule name. Source firewall.schedule.onetime.name firewall.schedule.recurring.name firewall.schedule.group.name.
type: str
service:
description:
- Service name.
type: list
suboptions:
name:
description:
- Address name. Source firewall.service.custom.name firewall.service.group.name.
required: true
type: str
srcaddr:
description:
- Source address name.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address6.name firewall.addrgrp6.name.
required: true
type: str
srcintf:
description:
- Source interface name. Source system.zone.name system.interface.name.
type: str
status:
description:
- Enable/disable policy status.
type: str
choices:
- enable
- disable
tcp_mss_receiver:
description:
- TCP MSS value of receiver.
type: int
tcp_mss_sender:
description:
- TCP MSS value of sender.
type: int
traffic_shaper:
description:
- Traffic shaper. Source firewall.shaper.traffic-shaper.name.
type: str
traffic_shaper_reverse:
description:
- Reverse traffic shaper. Source firewall.shaper.traffic-shaper.name.
type: str
uuid:
description:
- Universally Unique Identifier (UUID; automatically assigned but can be manually reset).
type: str
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure IPv6 to IPv4 policies.
fortios_firewall_policy64:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_policy64:
action: "accept"
comments: "<your_own_value>"
dstaddr:
-
name: "default_name_6 (source firewall.address.name firewall.addrgrp.name firewall.vip64.name firewall.vipgrp64.name)"
dstintf: "<your_own_value> (source system.interface.name system.zone.name)"
fixedport: "enable"
ippool: "enable"
logtraffic: "enable"
per_ip_shaper: "<your_own_value> (source firewall.shaper.per-ip-shaper.name)"
permit_any_host: "enable"
policyid: "13"
poolname:
-
name: "default_name_15 (source firewall.ippool.name)"
schedule: "<your_own_value> (source firewall.schedule.onetime.name firewall.schedule.recurring.name firewall.schedule.group.name)"
service:
-
name: "default_name_18 (source firewall.service.custom.name firewall.service.group.name)"
srcaddr:
-
name: "default_name_20 (source firewall.address6.name firewall.addrgrp6.name)"
srcintf: "<your_own_value> (source system.zone.name system.interface.name)"
status: "enable"
tcp_mss_receiver: "23"
tcp_mss_sender: "24"
traffic_shaper: "<your_own_value> (source firewall.shaper.traffic-shaper.name)"
traffic_shaper_reverse: "<your_own_value> (source firewall.shaper.traffic-shaper.name)"
uuid: "<your_own_value>"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_policy64_data(json):
option_list = ['action', 'comments', 'dstaddr',
'dstintf', 'fixedport', 'ippool',
'logtraffic', 'per_ip_shaper', 'permit_any_host',
'policyid', 'poolname', 'schedule',
'service', 'srcaddr', 'srcintf',
'status', 'tcp_mss_receiver', 'tcp_mss_sender',
'traffic_shaper', 'traffic_shaper_reverse', 'uuid']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_policy64(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_policy64'] and data['firewall_policy64']:
state = data['firewall_policy64']['state']
else:
state = True
firewall_policy64_data = data['firewall_policy64']
filtered_data = underscore_to_hyphen(filter_firewall_policy64_data(firewall_policy64_data))
if state == "present":
return fos.set('firewall',
'policy64',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'policy64',
mkey=filtered_data['policyid'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_policy64']:
resp = firewall_policy64(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_policy64": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"action": {"required": False, "type": "str",
"choices": ["accept", "deny"]},
"comments": {"required": False, "type": "str"},
"dstaddr": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"dstintf": {"required": False, "type": "str"},
"fixedport": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"ippool": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"logtraffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"per_ip_shaper": {"required": False, "type": "str"},
"permit_any_host": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"policyid": {"required": True, "type": "int"},
"poolname": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"schedule": {"required": False, "type": "str"},
"service": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"srcaddr": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"srcintf": {"required": False, "type": "str"},
"status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"tcp_mss_receiver": {"required": False, "type": "int"},
"tcp_mss_sender": {"required": False, "type": "int"},
"traffic_shaper": {"required": False, "type": "str"},
"traffic_shaper_reverse": {"required": False, "type": "str"},
"uuid": {"required": False, "type": "str"}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,413 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_profile_group
short_description: Configure profile groups in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and profile_group category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_profile_group:
description:
- Configure profile groups.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
application_list:
description:
- Name of an existing Application list. Source application.list.name.
type: str
av_profile:
description:
- Name of an existing Antivirus profile. Source antivirus.profile.name.
type: str
dlp_sensor:
description:
- Name of an existing DLP sensor. Source dlp.sensor.name.
type: str
dnsfilter_profile:
description:
- Name of an existing DNS filter profile. Source dnsfilter.profile.name.
type: str
icap_profile:
description:
- Name of an existing ICAP profile. Source icap.profile.name.
type: str
ips_sensor:
description:
- Name of an existing IPS sensor. Source ips.sensor.name.
type: str
name:
description:
- Profile group name.
required: true
type: str
profile_protocol_options:
description:
- Name of an existing Protocol options profile. Source firewall.profile-protocol-options.name.
type: str
spamfilter_profile:
description:
- Name of an existing Spam filter profile. Source spamfilter.profile.name.
type: str
ssh_filter_profile:
description:
- Name of an existing SSH filter profile. Source ssh-filter.profile.name.
type: str
ssl_ssh_profile:
description:
- Name of an existing SSL SSH profile. Source firewall.ssl-ssh-profile.name.
type: str
voip_profile:
description:
- Name of an existing VoIP profile. Source voip.profile.name.
type: str
waf_profile:
description:
- Name of an existing Web application firewall profile. Source waf.profile.name.
type: str
webfilter_profile:
description:
- Name of an existing Web filter profile. Source webfilter.profile.name.
type: str
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure profile groups.
fortios_firewall_profile_group:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_profile_group:
application_list: "<your_own_value> (source application.list.name)"
av_profile: "<your_own_value> (source antivirus.profile.name)"
dlp_sensor: "<your_own_value> (source dlp.sensor.name)"
dnsfilter_profile: "<your_own_value> (source dnsfilter.profile.name)"
icap_profile: "<your_own_value> (source icap.profile.name)"
ips_sensor: "<your_own_value> (source ips.sensor.name)"
name: "default_name_9"
profile_protocol_options: "<your_own_value> (source firewall.profile-protocol-options.name)"
spamfilter_profile: "<your_own_value> (source spamfilter.profile.name)"
ssh_filter_profile: "<your_own_value> (source ssh-filter.profile.name)"
ssl_ssh_profile: "<your_own_value> (source firewall.ssl-ssh-profile.name)"
voip_profile: "<your_own_value> (source voip.profile.name)"
waf_profile: "<your_own_value> (source waf.profile.name)"
webfilter_profile: "<your_own_value> (source webfilter.profile.name)"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_profile_group_data(json):
option_list = ['application_list', 'av_profile', 'dlp_sensor',
'dnsfilter_profile', 'icap_profile', 'ips_sensor',
'name', 'profile_protocol_options', 'spamfilter_profile',
'ssh_filter_profile', 'ssl_ssh_profile', 'voip_profile',
'waf_profile', 'webfilter_profile']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_profile_group(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_profile_group'] and data['firewall_profile_group']:
state = data['firewall_profile_group']['state']
else:
state = True
firewall_profile_group_data = data['firewall_profile_group']
filtered_data = underscore_to_hyphen(filter_firewall_profile_group_data(firewall_profile_group_data))
if state == "present":
return fos.set('firewall',
'profile-group',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'profile-group',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_profile_group']:
resp = firewall_profile_group(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_profile_group": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"application_list": {"required": False, "type": "str"},
"av_profile": {"required": False, "type": "str"},
"dlp_sensor": {"required": False, "type": "str"},
"dnsfilter_profile": {"required": False, "type": "str"},
"icap_profile": {"required": False, "type": "str"},
"ips_sensor": {"required": False, "type": "str"},
"name": {"required": True, "type": "str"},
"profile_protocol_options": {"required": False, "type": "str"},
"spamfilter_profile": {"required": False, "type": "str"},
"ssh_filter_profile": {"required": False, "type": "str"},
"ssl_ssh_profile": {"required": False, "type": "str"},
"voip_profile": {"required": False, "type": "str"},
"waf_profile": {"required": False, "type": "str"},
"webfilter_profile": {"required": False, "type": "str"}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,567 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_proxy_address
short_description: Web proxy address configuration in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and proxy_address category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_proxy_address:
description:
- Web proxy address configuration.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
case_sensitivity:
description:
- Enable to make the pattern case sensitive.
type: str
choices:
- disable
- enable
category:
description:
- FortiGuard category ID.
type: list
suboptions:
id:
description:
- Fortiguard category id.
required: true
type: int
color:
description:
- Integer value to determine the color of the icon in the GUI (1 - 32).
type: int
comment:
description:
- Optional comments.
type: str
header:
description:
- HTTP header name as a regular expression.
type: str
header_group:
description:
- HTTP header group.
type: list
suboptions:
case_sensitivity:
description:
- Case sensitivity in pattern.
type: str
choices:
- disable
- enable
header:
description:
- HTTP header regular expression.
type: str
header_name:
description:
- HTTP header.
type: str
id:
description:
- ID.
required: true
type: int
header_name:
description:
- Name of HTTP header.
type: str
host:
description:
- Address object for the host. Source firewall.address.name firewall.addrgrp.name firewall.proxy-address.name.
type: str
host_regex:
description:
- Host name as a regular expression.
type: str
method:
description:
- HTTP request methods to be used.
type: str
choices:
- get
- post
- put
- head
- connect
- trace
- options
- delete
name:
description:
- Address name.
required: true
type: str
path:
description:
- URL path as a regular expression.
type: str
query:
description:
- Match the query part of the URL as a regular expression.
type: str
referrer:
description:
- Enable/disable use of referrer field in the HTTP header to match the address.
type: str
choices:
- enable
- disable
tagging:
description:
- Config object tagging.
type: list
suboptions:
category:
description:
- Tag category. Source system.object-tagging.category.
type: str
name:
description:
- Tagging entry name.
required: true
type: str
tags:
description:
- Tags.
type: list
suboptions:
name:
description:
- Tag name. Source system.object-tagging.tags.name.
required: true
type: str
type:
description:
- Proxy address type.
type: str
choices:
- host-regex
- url
- category
- method
- ua
- header
- src-advanced
- dst-advanced
ua:
description:
- Names of browsers to be used as user agent.
type: str
choices:
- chrome
- ms
- firefox
- safari
- other
uuid:
description:
- Universally Unique Identifier (UUID; automatically assigned but can be manually reset).
type: str
visibility:
description:
- Enable/disable visibility of the object in the GUI.
type: str
choices:
- enable
- disable
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Web proxy address configuration.
fortios_firewall_proxy_address:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_proxy_address:
case_sensitivity: "disable"
category:
-
id: "5"
color: "6"
comment: "Optional comments."
header: "<your_own_value>"
header_group:
-
case_sensitivity: "disable"
header: "<your_own_value>"
header_name: "<your_own_value>"
id: "13"
header_name: "<your_own_value>"
host: "myhostname (source firewall.address.name firewall.addrgrp.name firewall.proxy-address.name)"
host_regex: "myhostname"
method: "get"
name: "default_name_18"
path: "<your_own_value>"
query: "<your_own_value>"
referrer: "enable"
tagging:
-
category: "<your_own_value> (source system.object-tagging.category)"
name: "default_name_24"
tags:
-
name: "default_name_26 (source system.object-tagging.tags.name)"
type: "host-regex"
ua: "chrome"
uuid: "<your_own_value>"
visibility: "enable"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_proxy_address_data(json):
option_list = ['case_sensitivity', 'category', 'color',
'comment', 'header', 'header_group',
'header_name', 'host', 'host_regex',
'method', 'name', 'path',
'query', 'referrer', 'tagging',
'type', 'ua', 'uuid',
'visibility']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_proxy_address(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_proxy_address'] and data['firewall_proxy_address']:
state = data['firewall_proxy_address']['state']
else:
state = True
firewall_proxy_address_data = data['firewall_proxy_address']
filtered_data = underscore_to_hyphen(filter_firewall_proxy_address_data(firewall_proxy_address_data))
if state == "present":
return fos.set('firewall',
'proxy-address',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'proxy-address',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_proxy_address']:
resp = firewall_proxy_address(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_proxy_address": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"case_sensitivity": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"category": {"required": False, "type": "list",
"options": {
"id": {"required": True, "type": "int"}
}},
"color": {"required": False, "type": "int"},
"comment": {"required": False, "type": "str"},
"header": {"required": False, "type": "str"},
"header_group": {"required": False, "type": "list",
"options": {
"case_sensitivity": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"header": {"required": False, "type": "str"},
"header_name": {"required": False, "type": "str"},
"id": {"required": True, "type": "int"}
}},
"header_name": {"required": False, "type": "str"},
"host": {"required": False, "type": "str"},
"host_regex": {"required": False, "type": "str"},
"method": {"required": False, "type": "str",
"choices": ["get", "post", "put",
"head", "connect", "trace",
"options", "delete"]},
"name": {"required": True, "type": "str"},
"path": {"required": False, "type": "str"},
"query": {"required": False, "type": "str"},
"referrer": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"tagging": {"required": False, "type": "list",
"options": {
"category": {"required": False, "type": "str"},
"name": {"required": True, "type": "str"},
"tags": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}}
}},
"type": {"required": False, "type": "str",
"choices": ["host-regex", "url", "category",
"method", "ua", "header",
"src-advanced", "dst-advanced"]},
"ua": {"required": False, "type": "str",
"choices": ["chrome", "ms", "firefox",
"safari", "other"]},
"uuid": {"required": False, "type": "str"},
"visibility": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,428 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_proxy_addrgrp
short_description: Web proxy address group configuration in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and proxy_addrgrp category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_proxy_addrgrp:
description:
- Web proxy address group configuration.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
color:
description:
- Integer value to determine the color of the icon in the GUI (1 - 32).
type: int
comment:
description:
- Optional comments.
type: str
member:
description:
- Members of address group.
type: list
suboptions:
name:
description:
- Address name. Source firewall.proxy-address.name firewall.proxy-addrgrp.name.
required: true
type: str
name:
description:
- Address group name.
required: true
type: str
tagging:
description:
- Config object tagging.
type: list
suboptions:
category:
description:
- Tag category. Source system.object-tagging.category.
type: str
name:
description:
- Tagging entry name.
required: true
type: str
tags:
description:
- Tags.
type: list
suboptions:
name:
description:
- Tag name. Source system.object-tagging.tags.name.
required: true
type: str
type:
description:
- Source or destination address group type.
type: str
choices:
- src
- dst
uuid:
description:
- Universally Unique Identifier (UUID; automatically assigned but can be manually reset).
type: str
visibility:
description:
- Enable/disable visibility of the object in the GUI.
type: str
choices:
- enable
- disable
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Web proxy address group configuration.
fortios_firewall_proxy_addrgrp:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_proxy_addrgrp:
color: "3"
comment: "Optional comments."
member:
-
name: "default_name_6 (source firewall.proxy-address.name firewall.proxy-addrgrp.name)"
name: "default_name_7"
tagging:
-
category: "<your_own_value> (source system.object-tagging.category)"
name: "default_name_10"
tags:
-
name: "default_name_12 (source system.object-tagging.tags.name)"
type: "src"
uuid: "<your_own_value>"
visibility: "enable"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_proxy_addrgrp_data(json):
option_list = ['color', 'comment', 'member',
'name', 'tagging', 'type',
'uuid', 'visibility']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_proxy_addrgrp(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_proxy_addrgrp'] and data['firewall_proxy_addrgrp']:
state = data['firewall_proxy_addrgrp']['state']
else:
state = True
firewall_proxy_addrgrp_data = data['firewall_proxy_addrgrp']
filtered_data = underscore_to_hyphen(filter_firewall_proxy_addrgrp_data(firewall_proxy_addrgrp_data))
if state == "present":
return fos.set('firewall',
'proxy-addrgrp',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'proxy-addrgrp',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_proxy_addrgrp']:
resp = firewall_proxy_addrgrp(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_proxy_addrgrp": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"color": {"required": False, "type": "int"},
"comment": {"required": False, "type": "str"},
"member": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"name": {"required": True, "type": "str"},
"tagging": {"required": False, "type": "list",
"options": {
"category": {"required": False, "type": "str"},
"name": {"required": True, "type": "str"},
"tags": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}}
}},
"type": {"required": False, "type": "str",
"choices": ["src", "dst"]},
"uuid": {"required": False, "type": "str"},
"visibility": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,881 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_proxy_policy
short_description: Configure proxy policies in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and proxy_policy category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_proxy_policy:
description:
- Configure proxy policies.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
action:
description:
- Accept or deny traffic matching the policy parameters.
type: str
choices:
- accept
- deny
- redirect
application_list:
description:
- Name of an existing Application list. Source application.list.name.
type: str
av_profile:
description:
- Name of an existing Antivirus profile. Source antivirus.profile.name.
type: str
comments:
description:
- Optional comments.
type: str
disclaimer:
description:
- "Web proxy disclaimer setting: by domain, policy, or user."
type: str
choices:
- disable
- domain
- policy
- user
dlp_sensor:
description:
- Name of an existing DLP sensor. Source dlp.sensor.name.
type: str
dstaddr:
description:
- Destination address objects.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address.name firewall.addrgrp.name firewall.proxy-address.name firewall.proxy-addrgrp.name
firewall.vip.name firewall.vipgrp.name firewall.vip46.name firewall.vipgrp46.name system.external-resource.name.
required: true
type: str
dstaddr_negate:
description:
- When enabled, destination addresses match against any address EXCEPT the specified destination addresses.
type: str
choices:
- enable
- disable
dstaddr6:
description:
- IPv6 destination address objects.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address6.name firewall.addrgrp6.name firewall.vip6.name firewall.vipgrp6.name firewall.vip64.name
firewall.vipgrp64.name system.external-resource.name.
required: true
type: str
dstintf:
description:
- Destination interface names.
type: list
suboptions:
name:
description:
- Interface name. Source system.interface.name system.zone.name.
required: true
type: str
global_label:
description:
- Global web-based manager visible label.
type: str
groups:
description:
- Names of group objects.
type: list
suboptions:
name:
description:
- Group name. Source user.group.name.
required: true
type: str
http_tunnel_auth:
description:
- Enable/disable HTTP tunnel authentication.
type: str
choices:
- enable
- disable
icap_profile:
description:
- Name of an existing ICAP profile. Source icap.profile.name.
type: str
internet_service:
description:
- Enable/disable use of Internet Services for this policy. If enabled, destination address and service are not used.
type: str
choices:
- enable
- disable
internet_service_custom:
description:
- Custom Internet Service name.
type: list
suboptions:
name:
description:
- Custom name. Source firewall.internet-service-custom.name.
required: true
type: str
internet_service_id:
description:
- Internet Service ID.
type: list
suboptions:
id:
description:
- Internet Service ID. Source firewall.internet-service.id.
required: true
type: int
internet_service_negate:
description:
- When enabled, Internet Services match against any internet service EXCEPT the selected Internet Service.
type: str
choices:
- enable
- disable
ips_sensor:
description:
- Name of an existing IPS sensor. Source ips.sensor.name.
type: str
label:
description:
- VDOM-specific GUI visible label.
type: str
logtraffic:
description:
- Enable/disable logging traffic through the policy.
type: str
choices:
- all
- utm
- disable
logtraffic_start:
description:
- Enable/disable policy log traffic start.
type: str
choices:
- enable
- disable
policyid:
description:
- Policy ID.
required: true
type: int
poolname:
description:
- Name of IP pool object.
type: list
suboptions:
name:
description:
- IP pool name. Source firewall.ippool.name.
required: true
type: str
profile_group:
description:
- Name of profile group. Source firewall.profile-group.name.
type: str
profile_protocol_options:
description:
- Name of an existing Protocol options profile. Source firewall.profile-protocol-options.name.
type: str
profile_type:
description:
- Determine whether the firewall policy allows security profile groups or single profiles only.
type: str
choices:
- single
- group
proxy:
description:
- Type of explicit proxy.
type: str
choices:
- explicit-web
- transparent-web
- ftp
- ssh
- ssh-tunnel
- wanopt
redirect_url:
description:
- Redirect URL for further explicit web proxy processing.
type: str
replacemsg_override_group:
description:
- Authentication replacement message override group. Source system.replacemsg-group.name.
type: str
scan_botnet_connections:
description:
- Enable/disable scanning of connections to Botnet servers.
type: str
choices:
- disable
- block
- monitor
schedule:
description:
- Name of schedule object. Source firewall.schedule.onetime.name firewall.schedule.recurring.name firewall.schedule.group.name.
type: str
service:
description:
- Name of service objects.
type: list
suboptions:
name:
description:
- Service name. Source firewall.service.custom.name firewall.service.group.name.
required: true
type: str
service_negate:
description:
- When enabled, services match against any service EXCEPT the specified destination services.
type: str
choices:
- enable
- disable
session_ttl:
description:
- TTL in seconds for sessions accepted by this policy (0 means use the system ).
type: int
spamfilter_profile:
description:
- Name of an existing Spam filter profile. Source spamfilter.profile.name.
type: str
srcaddr:
description:
- Source address objects.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address.name firewall.addrgrp.name firewall.proxy-address.name firewall.proxy-addrgrp.name system
.external-resource.name.
required: true
type: str
srcaddr_negate:
description:
- When enabled, source addresses match against any address EXCEPT the specified source addresses.
type: str
choices:
- enable
- disable
srcaddr6:
description:
- IPv6 source address objects.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address6.name firewall.addrgrp6.name system.external-resource.name.
required: true
type: str
srcintf:
description:
- Source interface names.
type: list
suboptions:
name:
description:
- Interface name. Source system.interface.name system.zone.name.
required: true
type: str
ssh_filter_profile:
description:
- Name of an existing SSH filter profile. Source ssh-filter.profile.name.
type: str
ssl_ssh_profile:
description:
- Name of an existing SSL SSH profile. Source firewall.ssl-ssh-profile.name.
type: str
status:
description:
- Enable/disable the active status of the policy.
type: str
choices:
- enable
- disable
transparent:
description:
- Enable to use the IP address of the client to connect to the server.
type: str
choices:
- enable
- disable
users:
description:
- Names of user objects.
type: list
suboptions:
name:
description:
- Group name. Source user.local.name.
required: true
type: str
utm_status:
description:
- Enable the use of UTM profiles/sensors/lists.
type: str
choices:
- enable
- disable
uuid:
description:
- Universally Unique Identifier (UUID; automatically assigned but can be manually reset).
type: str
waf_profile:
description:
- Name of an existing Web application firewall profile. Source waf.profile.name.
type: str
webcache:
description:
- Enable/disable web caching.
type: str
choices:
- enable
- disable
webcache_https:
description:
- Enable/disable web caching for HTTPS (Requires deep-inspection enabled in ssl-ssh-profile).
type: str
choices:
- disable
- enable
webfilter_profile:
description:
- Name of an existing Web filter profile. Source webfilter.profile.name.
type: str
webproxy_forward_server:
description:
- Name of web proxy forward server. Source web-proxy.forward-server.name web-proxy.forward-server-group.name.
type: str
webproxy_profile:
description:
- Name of web proxy profile. Source web-proxy.profile.name.
type: str
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure proxy policies.
fortios_firewall_proxy_policy:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_proxy_policy:
action: "accept"
application_list: "<your_own_value> (source application.list.name)"
av_profile: "<your_own_value> (source antivirus.profile.name)"
comments: "<your_own_value>"
disclaimer: "disable"
dlp_sensor: "<your_own_value> (source dlp.sensor.name)"
dstaddr:
-
name: "default_name_10 (source firewall.address.name firewall.addrgrp.name firewall.proxy-address.name firewall.proxy-addrgrp.name firewall.vip
.name firewall.vipgrp.name firewall.vip46.name firewall.vipgrp46.name system.external-resource.name)"
dstaddr_negate: "enable"
dstaddr6:
-
name: "default_name_13 (source firewall.address6.name firewall.addrgrp6.name firewall.vip6.name firewall.vipgrp6.name firewall.vip64.name firewall
.vipgrp64.name system.external-resource.name)"
dstintf:
-
name: "default_name_15 (source system.interface.name system.zone.name)"
global_label: "<your_own_value>"
groups:
-
name: "default_name_18 (source user.group.name)"
http_tunnel_auth: "enable"
icap_profile: "<your_own_value> (source icap.profile.name)"
internet_service: "enable"
internet_service_custom:
-
name: "default_name_23 (source firewall.internet-service-custom.name)"
internet_service_id:
-
id: "25 (source firewall.internet-service.id)"
internet_service_negate: "enable"
ips_sensor: "<your_own_value> (source ips.sensor.name)"
label: "<your_own_value>"
logtraffic: "all"
logtraffic_start: "enable"
policyid: "31"
poolname:
-
name: "default_name_33 (source firewall.ippool.name)"
profile_group: "<your_own_value> (source firewall.profile-group.name)"
profile_protocol_options: "<your_own_value> (source firewall.profile-protocol-options.name)"
profile_type: "single"
proxy: "explicit-web"
redirect_url: "<your_own_value>"
replacemsg_override_group: "<your_own_value> (source system.replacemsg-group.name)"
scan_botnet_connections: "disable"
schedule: "<your_own_value> (source firewall.schedule.onetime.name firewall.schedule.recurring.name firewall.schedule.group.name)"
service:
-
name: "default_name_43 (source firewall.service.custom.name firewall.service.group.name)"
service_negate: "enable"
session_ttl: "45"
spamfilter_profile: "<your_own_value> (source spamfilter.profile.name)"
srcaddr:
-
name: "default_name_48 (source firewall.address.name firewall.addrgrp.name firewall.proxy-address.name firewall.proxy-addrgrp.name system
.external-resource.name)"
srcaddr_negate: "enable"
srcaddr6:
-
name: "default_name_51 (source firewall.address6.name firewall.addrgrp6.name system.external-resource.name)"
srcintf:
-
name: "default_name_53 (source system.interface.name system.zone.name)"
ssh_filter_profile: "<your_own_value> (source ssh-filter.profile.name)"
ssl_ssh_profile: "<your_own_value> (source firewall.ssl-ssh-profile.name)"
status: "enable"
transparent: "enable"
users:
-
name: "default_name_59 (source user.local.name)"
utm_status: "enable"
uuid: "<your_own_value>"
waf_profile: "<your_own_value> (source waf.profile.name)"
webcache: "enable"
webcache_https: "disable"
webfilter_profile: "<your_own_value> (source webfilter.profile.name)"
webproxy_forward_server: "<your_own_value> (source web-proxy.forward-server.name web-proxy.forward-server-group.name)"
webproxy_profile: "<your_own_value> (source web-proxy.profile.name)"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_proxy_policy_data(json):
option_list = ['action', 'application_list', 'av_profile',
'comments', 'disclaimer', 'dlp_sensor',
'dstaddr', 'dstaddr_negate', 'dstaddr6',
'dstintf', 'global_label', 'groups',
'http_tunnel_auth', 'icap_profile', 'internet_service',
'internet_service_custom', 'internet_service_id', 'internet_service_negate',
'ips_sensor', 'label', 'logtraffic',
'logtraffic_start', 'policyid', 'poolname',
'profile_group', 'profile_protocol_options', 'profile_type',
'proxy', 'redirect_url', 'replacemsg_override_group',
'scan_botnet_connections', 'schedule', 'service',
'service_negate', 'session_ttl', 'spamfilter_profile',
'srcaddr', 'srcaddr_negate', 'srcaddr6',
'srcintf', 'ssh_filter_profile', 'ssl_ssh_profile',
'status', 'transparent', 'users',
'utm_status', 'uuid', 'waf_profile',
'webcache', 'webcache_https', 'webfilter_profile',
'webproxy_forward_server', 'webproxy_profile']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_proxy_policy(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_proxy_policy'] and data['firewall_proxy_policy']:
state = data['firewall_proxy_policy']['state']
else:
state = True
firewall_proxy_policy_data = data['firewall_proxy_policy']
filtered_data = underscore_to_hyphen(filter_firewall_proxy_policy_data(firewall_proxy_policy_data))
if state == "present":
return fos.set('firewall',
'proxy-policy',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'proxy-policy',
mkey=filtered_data['policyid'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_proxy_policy']:
resp = firewall_proxy_policy(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_proxy_policy": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"action": {"required": False, "type": "str",
"choices": ["accept", "deny", "redirect"]},
"application_list": {"required": False, "type": "str"},
"av_profile": {"required": False, "type": "str"},
"comments": {"required": False, "type": "str"},
"disclaimer": {"required": False, "type": "str",
"choices": ["disable", "domain", "policy",
"user"]},
"dlp_sensor": {"required": False, "type": "str"},
"dstaddr": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"dstaddr_negate": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"dstaddr6": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"dstintf": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"global_label": {"required": False, "type": "str"},
"groups": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"http_tunnel_auth": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"icap_profile": {"required": False, "type": "str"},
"internet_service": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"internet_service_custom": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"internet_service_id": {"required": False, "type": "list",
"options": {
"id": {"required": True, "type": "int"}
}},
"internet_service_negate": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"ips_sensor": {"required": False, "type": "str"},
"label": {"required": False, "type": "str"},
"logtraffic": {"required": False, "type": "str",
"choices": ["all", "utm", "disable"]},
"logtraffic_start": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"policyid": {"required": True, "type": "int"},
"poolname": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"profile_group": {"required": False, "type": "str"},
"profile_protocol_options": {"required": False, "type": "str"},
"profile_type": {"required": False, "type": "str",
"choices": ["single", "group"]},
"proxy": {"required": False, "type": "str",
"choices": ["explicit-web", "transparent-web", "ftp",
"ssh", "ssh-tunnel", "wanopt"]},
"redirect_url": {"required": False, "type": "str"},
"replacemsg_override_group": {"required": False, "type": "str"},
"scan_botnet_connections": {"required": False, "type": "str",
"choices": ["disable", "block", "monitor"]},
"schedule": {"required": False, "type": "str"},
"service": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"service_negate": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"session_ttl": {"required": False, "type": "int"},
"spamfilter_profile": {"required": False, "type": "str"},
"srcaddr": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"srcaddr_negate": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"srcaddr6": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"srcintf": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"ssh_filter_profile": {"required": False, "type": "str"},
"ssl_ssh_profile": {"required": False, "type": "str"},
"status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"transparent": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"users": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"utm_status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"uuid": {"required": False, "type": "str"},
"waf_profile": {"required": False, "type": "str"},
"webcache": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"webcache_https": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"webfilter_profile": {"required": False, "type": "str"},
"webproxy_forward_server": {"required": False, "type": "str"},
"webproxy_profile": {"required": False, "type": "str"}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,354 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_schedule_group
short_description: Schedule group configuration in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall_schedule feature and group category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_schedule_group:
description:
- Schedule group configuration.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
color:
description:
- Color of icon on the GUI.
type: int
member:
description:
- Schedules added to the schedule group.
type: list
suboptions:
name:
description:
- Schedule name. Source firewall.schedule.onetime.name firewall.schedule.recurring.name.
required: true
type: str
name:
description:
- Schedule group name.
required: true
type: str
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Schedule group configuration.
fortios_firewall_schedule_group:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_schedule_group:
color: "3"
member:
-
name: "default_name_5 (source firewall.schedule.onetime.name firewall.schedule.recurring.name)"
name: "default_name_6"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_schedule_group_data(json):
option_list = ['color', 'member', 'name']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_schedule_group(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_schedule_group'] and data['firewall_schedule_group']:
state = data['firewall_schedule_group']['state']
else:
state = True
firewall_schedule_group_data = data['firewall_schedule_group']
filtered_data = underscore_to_hyphen(filter_firewall_schedule_group_data(firewall_schedule_group_data))
if state == "present":
return fos.set('firewall.schedule',
'group',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall.schedule',
'group',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall_schedule(data, fos):
if data['firewall_schedule_group']:
resp = firewall_schedule_group(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_schedule_group": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"color": {"required": False, "type": "int"},
"member": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"name": {"required": True, "type": "str"}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall_schedule(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall_schedule(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,356 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_schedule_onetime
short_description: Onetime schedule configuration in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall_schedule feature and onetime category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_schedule_onetime:
description:
- Onetime schedule configuration.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
color:
description:
- Color of icon on the GUI.
type: int
end:
description:
- "Schedule end date and time, format hh:mm yyyy/mm/dd."
type: str
expiration_days:
description:
- Write an event log message this many days before the schedule expires.
type: int
name:
description:
- Onetime schedule name.
required: true
type: str
start:
description:
- "Schedule start date and time, format hh:mm yyyy/mm/dd."
type: str
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Onetime schedule configuration.
fortios_firewall_schedule_onetime:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_schedule_onetime:
color: "3"
end: "<your_own_value>"
expiration_days: "5"
name: "default_name_6"
start: "<your_own_value>"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_schedule_onetime_data(json):
option_list = ['color', 'end', 'expiration_days',
'name', 'start']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_schedule_onetime(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_schedule_onetime'] and data['firewall_schedule_onetime']:
state = data['firewall_schedule_onetime']['state']
else:
state = True
firewall_schedule_onetime_data = data['firewall_schedule_onetime']
filtered_data = underscore_to_hyphen(filter_firewall_schedule_onetime_data(firewall_schedule_onetime_data))
if state == "present":
return fos.set('firewall.schedule',
'onetime',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall.schedule',
'onetime',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall_schedule(data, fos):
if data['firewall_schedule_onetime']:
resp = firewall_schedule_onetime(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_schedule_onetime": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"color": {"required": False, "type": "int"},
"end": {"required": False, "type": "str"},
"expiration_days": {"required": False, "type": "int"},
"name": {"required": True, "type": "str"},
"start": {"required": False, "type": "str"}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall_schedule(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall_schedule(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,368 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_schedule_recurring
short_description: Recurring schedule configuration in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall_schedule feature and recurring category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_schedule_recurring:
description:
- Recurring schedule configuration.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
color:
description:
- Color of icon on the GUI.
type: int
day:
description:
- One or more days of the week on which the schedule is valid. Separate the names of the days with a space.
type: str
choices:
- sunday
- monday
- tuesday
- wednesday
- thursday
- friday
- saturday
- none
end:
description:
- "Time of day to end the schedule, format hh:mm."
type: str
name:
description:
- Recurring schedule name.
required: true
type: str
start:
description:
- "Time of day to start the schedule, format hh:mm."
type: str
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Recurring schedule configuration.
fortios_firewall_schedule_recurring:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_schedule_recurring:
color: "3"
day: "sunday"
end: "<your_own_value>"
name: "default_name_6"
start: "<your_own_value>"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_schedule_recurring_data(json):
option_list = ['color', 'day', 'end',
'name', 'start']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_schedule_recurring(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_schedule_recurring'] and data['firewall_schedule_recurring']:
state = data['firewall_schedule_recurring']['state']
else:
state = True
firewall_schedule_recurring_data = data['firewall_schedule_recurring']
filtered_data = underscore_to_hyphen(filter_firewall_schedule_recurring_data(firewall_schedule_recurring_data))
if state == "present":
return fos.set('firewall.schedule',
'recurring',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall.schedule',
'recurring',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall_schedule(data, fos):
if data['firewall_schedule_recurring']:
resp = firewall_schedule_recurring(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_schedule_recurring": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"color": {"required": False, "type": "int"},
"day": {"required": False, "type": "str",
"choices": ["sunday", "monday", "tuesday",
"wednesday", "thursday", "friday",
"saturday", "none"]},
"end": {"required": False, "type": "str"},
"name": {"required": True, "type": "str"},
"start": {"required": False, "type": "str"}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall_schedule(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall_schedule(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,337 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_service_category
short_description: Configure service categories in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall_service feature and category category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_service_category:
description:
- Configure service categories.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
comment:
description:
- Comment.
type: str
name:
description:
- Service category name.
required: true
type: str
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure service categories.
fortios_firewall_service_category:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_service_category:
comment: "Comment."
name: "default_name_4"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_service_category_data(json):
option_list = ['comment', 'name']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_service_category(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_service_category'] and data['firewall_service_category']:
state = data['firewall_service_category']['state']
else:
state = True
firewall_service_category_data = data['firewall_service_category']
filtered_data = underscore_to_hyphen(filter_firewall_service_category_data(firewall_service_category_data))
if state == "present":
return fos.set('firewall.service',
'category',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall.service',
'category',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall_service(data, fos):
if data['firewall_service_category']:
resp = firewall_service_category(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_service_category": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"comment": {"required": False, "type": "str"},
"name": {"required": True, "type": "str"}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall_service(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall_service(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,566 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_service_custom
short_description: Configure custom services in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall_service feature and custom category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_service_custom:
description:
- Configure custom services.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
app_category:
description:
- Application category ID.
type: list
suboptions:
id:
description:
- Application category id.
required: true
type: int
app_service_type:
description:
- Application service type.
type: str
choices:
- disable
- app-id
- app-category
application:
description:
- Application ID.
type: list
suboptions:
id:
description:
- Application id.
required: true
type: int
category:
description:
- Service category. Source firewall.service.category.name.
type: str
check_reset_range:
description:
- Configure the type of ICMP error message verification.
type: str
choices:
- disable
- strict
- default
color:
description:
- Color of icon on the GUI.
type: int
comment:
description:
- Comment.
type: str
fqdn:
description:
- Fully qualified domain name.
type: str
helper:
description:
- Helper name.
type: str
choices:
- auto
- disable
- ftp
- tftp
- ras
- h323
- tns
- mms
- sip
- pptp
- rtsp
- dns-udp
- dns-tcp
- pmap
- rsh
- dcerpc
- mgcp
- gtp-c
- gtp-u
- gtp-b
icmpcode:
description:
- ICMP code.
type: int
icmptype:
description:
- ICMP type.
type: int
iprange:
description:
- Start and end of the IP range associated with service.
type: str
name:
description:
- Custom service name.
required: true
type: str
protocol:
description:
- Protocol type based on IANA numbers.
type: str
choices:
- TCP/UDP/SCTP
- ICMP
- ICMP6
- IP
- HTTP
- FTP
- CONNECT
- SOCKS-TCP
- SOCKS-UDP
- ALL
protocol_number:
description:
- IP protocol number.
type: int
proxy:
description:
- Enable/disable web proxy service.
type: str
choices:
- enable
- disable
sctp_portrange:
description:
- Multiple SCTP port ranges.
type: str
session_ttl:
description:
- Session TTL (300 - 604800, 0 = default).
type: int
tcp_halfclose_timer:
description:
- Wait time to close a TCP session waiting for an unanswered FIN packet (1 - 86400 sec, 0 = default).
type: int
tcp_halfopen_timer:
description:
- Wait time to close a TCP session waiting for an unanswered open session packet (1 - 86400 sec, 0 = default).
type: int
tcp_portrange:
description:
- Multiple TCP port ranges.
type: str
tcp_timewait_timer:
description:
- Set the length of the TCP TIME-WAIT state in seconds (1 - 300 sec, 0 = default).
type: int
udp_idle_timer:
description:
- UDP half close timeout (0 - 86400 sec, 0 = default).
type: int
udp_portrange:
description:
- Multiple UDP port ranges.
type: str
visibility:
description:
- Enable/disable the visibility of the service on the GUI.
type: str
choices:
- enable
- disable
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure custom services.
fortios_firewall_service_custom:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_service_custom:
app_category:
-
id: "4"
app_service_type: "disable"
application:
-
id: "7"
category: "<your_own_value> (source firewall.service.category.name)"
check_reset_range: "disable"
color: "10"
comment: "Comment."
fqdn: "<your_own_value>"
helper: "auto"
icmpcode: "14"
icmptype: "15"
iprange: "<your_own_value>"
name: "default_name_17"
protocol: "TCP/UDP/SCTP"
protocol_number: "19"
proxy: "enable"
sctp_portrange: "<your_own_value>"
session_ttl: "22"
tcp_halfclose_timer: "23"
tcp_halfopen_timer: "24"
tcp_portrange: "<your_own_value>"
tcp_timewait_timer: "26"
udp_idle_timer: "27"
udp_portrange: "<your_own_value>"
visibility: "enable"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_service_custom_data(json):
option_list = ['app_category', 'app_service_type', 'application',
'category', 'check_reset_range', 'color',
'comment', 'fqdn', 'helper',
'icmpcode', 'icmptype', 'iprange',
'name', 'protocol', 'protocol_number',
'proxy', 'sctp_portrange', 'session_ttl',
'tcp_halfclose_timer', 'tcp_halfopen_timer', 'tcp_portrange',
'tcp_timewait_timer', 'udp_idle_timer', 'udp_portrange',
'visibility']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_service_custom(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_service_custom'] and data['firewall_service_custom']:
state = data['firewall_service_custom']['state']
else:
state = True
firewall_service_custom_data = data['firewall_service_custom']
filtered_data = underscore_to_hyphen(filter_firewall_service_custom_data(firewall_service_custom_data))
if state == "present":
return fos.set('firewall.service',
'custom',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall.service',
'custom',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall_service(data, fos):
if data['firewall_service_custom']:
resp = firewall_service_custom(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_service_custom": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"app_category": {"required": False, "type": "list",
"options": {
"id": {"required": True, "type": "int"}
}},
"app_service_type": {"required": False, "type": "str",
"choices": ["disable", "app-id", "app-category"]},
"application": {"required": False, "type": "list",
"options": {
"id": {"required": True, "type": "int"}
}},
"category": {"required": False, "type": "str"},
"check_reset_range": {"required": False, "type": "str",
"choices": ["disable", "strict", "default"]},
"color": {"required": False, "type": "int"},
"comment": {"required": False, "type": "str"},
"fqdn": {"required": False, "type": "str"},
"helper": {"required": False, "type": "str",
"choices": ["auto", "disable", "ftp",
"tftp", "ras", "h323",
"tns", "mms", "sip",
"pptp", "rtsp", "dns-udp",
"dns-tcp", "pmap", "rsh",
"dcerpc", "mgcp", "gtp-c",
"gtp-u", "gtp-b"]},
"icmpcode": {"required": False, "type": "int"},
"icmptype": {"required": False, "type": "int"},
"iprange": {"required": False, "type": "str"},
"name": {"required": True, "type": "str"},
"protocol": {"required": False, "type": "str",
"choices": ["TCP/UDP/SCTP", "ICMP", "ICMP6",
"IP", "HTTP", "FTP",
"CONNECT", "SOCKS-TCP", "SOCKS-UDP",
"ALL"]},
"protocol_number": {"required": False, "type": "int"},
"proxy": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"sctp_portrange": {"required": False, "type": "str"},
"session_ttl": {"required": False, "type": "int"},
"tcp_halfclose_timer": {"required": False, "type": "int"},
"tcp_halfopen_timer": {"required": False, "type": "int"},
"tcp_portrange": {"required": False, "type": "str"},
"tcp_timewait_timer": {"required": False, "type": "int"},
"udp_idle_timer": {"required": False, "type": "int"},
"udp_portrange": {"required": False, "type": "str"},
"visibility": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall_service(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall_service(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,371 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_service_group
short_description: Configure service groups in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall_service feature and group category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_service_group:
description:
- Configure service groups.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
color:
description:
- Color of icon on the GUI.
type: int
comment:
description:
- Comment.
type: str
member:
description:
- Service objects contained within the group.
type: list
suboptions:
name:
description:
- Address name. Source firewall.service.custom.name firewall.service.group.name.
required: true
type: str
name:
description:
- Address group name.
required: true
type: str
proxy:
description:
- Enable/disable web proxy service group.
type: str
choices:
- enable
- disable
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure service groups.
fortios_firewall_service_group:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_service_group:
color: "3"
comment: "Comment."
member:
-
name: "default_name_6 (source firewall.service.custom.name firewall.service.group.name)"
name: "default_name_7"
proxy: "enable"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_service_group_data(json):
option_list = ['color', 'comment', 'member',
'name', 'proxy']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_service_group(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_service_group'] and data['firewall_service_group']:
state = data['firewall_service_group']['state']
else:
state = True
firewall_service_group_data = data['firewall_service_group']
filtered_data = underscore_to_hyphen(filter_firewall_service_group_data(firewall_service_group_data))
if state == "present":
return fos.set('firewall.service',
'group',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall.service',
'group',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall_service(data, fos):
if data['firewall_service_group']:
resp = firewall_service_group(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_service_group": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"color": {"required": False, "type": "int"},
"comment": {"required": False, "type": "str"},
"member": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"name": {"required": True, "type": "str"},
"proxy": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall_service(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall_service(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,388 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_shaper_per_ip_shaper
short_description: Configure per-IP traffic shaper in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall_shaper feature and per_ip_shaper category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_shaper_per_ip_shaper:
description:
- Configure per-IP traffic shaper.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
bandwidth_unit:
description:
- Unit of measurement for maximum bandwidth for this shaper (Kbps, Mbps or Gbps).
type: str
choices:
- kbps
- mbps
- gbps
diffserv_forward:
description:
- Enable/disable changing the Forward (original) DiffServ setting applied to traffic accepted by this shaper.
type: str
choices:
- enable
- disable
diffserv_reverse:
description:
- Enable/disable changing the Reverse (reply) DiffServ setting applied to traffic accepted by this shaper.
type: str
choices:
- enable
- disable
diffservcode_forward:
description:
- Forward (original) DiffServ setting to be applied to traffic accepted by this shaper.
type: str
diffservcode_rev:
description:
- Reverse (reply) DiffServ setting to be applied to traffic accepted by this shaper.
type: str
max_bandwidth:
description:
- Upper bandwidth limit enforced by this shaper (0 - 16776000). 0 means no limit. Units depend on the bandwidth-unit setting.
type: int
max_concurrent_session:
description:
- Maximum number of concurrent sessions allowed by this shaper (0 - 2097000). 0 means no limit.
type: int
name:
description:
- Traffic shaper name.
required: true
type: str
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure per-IP traffic shaper.
fortios_firewall_shaper_per_ip_shaper:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_shaper_per_ip_shaper:
bandwidth_unit: "kbps"
diffserv_forward: "enable"
diffserv_reverse: "enable"
diffservcode_forward: "<your_own_value>"
diffservcode_rev: "<your_own_value>"
max_bandwidth: "8"
max_concurrent_session: "9"
name: "default_name_10"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_shaper_per_ip_shaper_data(json):
option_list = ['bandwidth_unit', 'diffserv_forward', 'diffserv_reverse',
'diffservcode_forward', 'diffservcode_rev', 'max_bandwidth',
'max_concurrent_session', 'name']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_shaper_per_ip_shaper(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_shaper_per_ip_shaper'] and data['firewall_shaper_per_ip_shaper']:
state = data['firewall_shaper_per_ip_shaper']['state']
else:
state = True
firewall_shaper_per_ip_shaper_data = data['firewall_shaper_per_ip_shaper']
filtered_data = underscore_to_hyphen(filter_firewall_shaper_per_ip_shaper_data(firewall_shaper_per_ip_shaper_data))
if state == "present":
return fos.set('firewall.shaper',
'per-ip-shaper',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall.shaper',
'per-ip-shaper',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall_shaper(data, fos):
if data['firewall_shaper_per_ip_shaper']:
resp = firewall_shaper_per_ip_shaper(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_shaper_per_ip_shaper": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"bandwidth_unit": {"required": False, "type": "str",
"choices": ["kbps", "mbps", "gbps"]},
"diffserv_forward": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"diffserv_reverse": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"diffservcode_forward": {"required": False, "type": "str"},
"diffservcode_rev": {"required": False, "type": "str"},
"max_bandwidth": {"required": False, "type": "int"},
"max_concurrent_session": {"required": False, "type": "int"},
"name": {"required": True, "type": "str"}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall_shaper(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall_shaper(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,394 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_shaper_traffic_shaper
short_description: Configure shared traffic shaper in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall_shaper feature and traffic_shaper category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_shaper_traffic_shaper:
description:
- Configure shared traffic shaper.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
bandwidth_unit:
description:
- Unit of measurement for guaranteed and maximum bandwidth for this shaper (Kbps, Mbps or Gbps).
type: str
choices:
- kbps
- mbps
- gbps
diffserv:
description:
- Enable/disable changing the DiffServ setting applied to traffic accepted by this shaper.
type: str
choices:
- enable
- disable
diffservcode:
description:
- DiffServ setting to be applied to traffic accepted by this shaper.
type: str
guaranteed_bandwidth:
description:
- Amount of bandwidth guaranteed for this shaper (0 - 16776000). Units depend on the bandwidth-unit setting.
type: int
maximum_bandwidth:
description:
- Upper bandwidth limit enforced by this shaper (0 - 16776000). 0 means no limit. Units depend on the bandwidth-unit setting.
type: int
name:
description:
- Traffic shaper name.
required: true
type: str
per_policy:
description:
- Enable/disable applying a separate shaper for each policy. For example, if enabled the guaranteed bandwidth is applied separately for
each policy.
type: str
choices:
- disable
- enable
priority:
description:
- Higher priority traffic is more likely to be forwarded without delays and without compromising the guaranteed bandwidth.
type: str
choices:
- low
- medium
- high
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure shared traffic shaper.
fortios_firewall_shaper_traffic_shaper:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_shaper_traffic_shaper:
bandwidth_unit: "kbps"
diffserv: "enable"
diffservcode: "<your_own_value>"
guaranteed_bandwidth: "6"
maximum_bandwidth: "7"
name: "default_name_8"
per_policy: "disable"
priority: "low"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_shaper_traffic_shaper_data(json):
option_list = ['bandwidth_unit', 'diffserv', 'diffservcode',
'guaranteed_bandwidth', 'maximum_bandwidth', 'name',
'per_policy', 'priority']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_shaper_traffic_shaper(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_shaper_traffic_shaper'] and data['firewall_shaper_traffic_shaper']:
state = data['firewall_shaper_traffic_shaper']['state']
else:
state = True
firewall_shaper_traffic_shaper_data = data['firewall_shaper_traffic_shaper']
filtered_data = underscore_to_hyphen(filter_firewall_shaper_traffic_shaper_data(firewall_shaper_traffic_shaper_data))
if state == "present":
return fos.set('firewall.shaper',
'traffic-shaper',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall.shaper',
'traffic-shaper',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall_shaper(data, fos):
if data['firewall_shaper_traffic_shaper']:
resp = firewall_shaper_traffic_shaper(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_shaper_traffic_shaper": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"bandwidth_unit": {"required": False, "type": "str",
"choices": ["kbps", "mbps", "gbps"]},
"diffserv": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"diffservcode": {"required": False, "type": "str"},
"guaranteed_bandwidth": {"required": False, "type": "int"},
"maximum_bandwidth": {"required": False, "type": "int"},
"name": {"required": True, "type": "str"},
"per_policy": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"priority": {"required": False, "type": "str",
"choices": ["low", "medium", "high"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall_shaper(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall_shaper(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,670 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_shaping_policy
short_description: Configure shaping policies in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and shaping_policy category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_shaping_policy:
description:
- Configure shaping policies.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
app_category:
description:
- IDs of one or more application categories that this shaper applies application control traffic shaping to.
type: list
suboptions:
id:
description:
- Category IDs.
required: true
type: int
application:
description:
- IDs of one or more applications that this shaper applies application control traffic shaping to.
type: list
suboptions:
id:
description:
- Application IDs.
required: true
type: int
class_id:
description:
- Traffic class ID.
type: int
comment:
description:
- Comments.
type: str
dstaddr:
description:
- IPv4 destination address and address group names.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address.name firewall.addrgrp.name.
required: true
type: str
dstaddr6:
description:
- IPv6 destination address and address group names.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address6.name firewall.addrgrp6.name.
required: true
type: str
dstintf:
description:
- One or more outgoing (egress) interfaces.
type: list
suboptions:
name:
description:
- Interface name. Source system.interface.name system.zone.name.
required: true
type: str
groups:
description:
- Apply this traffic shaping policy to user groups that have authenticated with the FortiGate.
type: list
suboptions:
name:
description:
- Group name. Source user.group.name.
required: true
type: str
id:
description:
- Shaping policy ID.
required: true
type: int
internet_service:
description:
- Enable/disable use of Internet Services for this policy. If enabled, destination address and service are not used.
type: str
choices:
- enable
- disable
internet_service_custom:
description:
- Custom Internet Service name.
type: list
suboptions:
name:
description:
- Custom Internet Service name. Source firewall.internet-service-custom.name.
required: true
type: str
internet_service_id:
description:
- Internet Service ID.
type: list
suboptions:
id:
description:
- Internet Service ID. Source firewall.internet-service.id.
required: true
type: int
internet_service_src:
description:
- Enable/disable use of Internet Services in source for this policy. If enabled, source address is not used.
type: str
choices:
- enable
- disable
internet_service_src_custom:
description:
- Custom Internet Service source name.
type: list
suboptions:
name:
description:
- Custom Internet Service name. Source firewall.internet-service-custom.name.
required: true
type: str
internet_service_src_id:
description:
- Internet Service source ID.
type: list
suboptions:
id:
description:
- Internet Service ID. Source firewall.internet-service.id.
required: true
type: int
ip_version:
description:
- Apply this traffic shaping policy to IPv4 or IPv6 traffic.
type: str
choices:
- 4
- 6
per_ip_shaper:
description:
- Per-IP traffic shaper to apply with this policy. Source firewall.shaper.per-ip-shaper.name.
type: str
schedule:
description:
- Schedule name. Source firewall.schedule.onetime.name firewall.schedule.recurring.name firewall.schedule.group.name.
type: str
service:
description:
- Service and service group names.
type: list
suboptions:
name:
description:
- Service name. Source firewall.service.custom.name firewall.service.group.name.
required: true
type: str
srcaddr:
description:
- IPv4 source address and address group names.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address.name firewall.addrgrp.name.
required: true
type: str
srcaddr6:
description:
- IPv6 source address and address group names.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address6.name firewall.addrgrp6.name.
required: true
type: str
status:
description:
- Enable/disable this traffic shaping policy.
type: str
choices:
- enable
- disable
traffic_shaper:
description:
- Traffic shaper to apply to traffic forwarded by the firewall policy. Source firewall.shaper.traffic-shaper.name.
type: str
traffic_shaper_reverse:
description:
- Traffic shaper to apply to response traffic received by the firewall policy. Source firewall.shaper.traffic-shaper.name.
type: str
url_category:
description:
- IDs of one or more FortiGuard Web Filtering categories that this shaper applies traffic shaping to.
type: list
suboptions:
id:
description:
- URL category ID.
required: true
type: int
users:
description:
- Apply this traffic shaping policy to individual users that have authenticated with the FortiGate.
type: list
suboptions:
name:
description:
- User name. Source user.local.name.
required: true
type: str
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure shaping policies.
fortios_firewall_shaping_policy:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_shaping_policy:
app_category:
-
id: "4"
application:
-
id: "6"
class_id: "7"
comment: "Comments."
dstaddr:
-
name: "default_name_10 (source firewall.address.name firewall.addrgrp.name)"
dstaddr6:
-
name: "default_name_12 (source firewall.address6.name firewall.addrgrp6.name)"
dstintf:
-
name: "default_name_14 (source system.interface.name system.zone.name)"
groups:
-
name: "default_name_16 (source user.group.name)"
id: "17"
internet_service: "enable"
internet_service_custom:
-
name: "default_name_20 (source firewall.internet-service-custom.name)"
internet_service_id:
-
id: "22 (source firewall.internet-service.id)"
internet_service_src: "enable"
internet_service_src_custom:
-
name: "default_name_25 (source firewall.internet-service-custom.name)"
internet_service_src_id:
-
id: "27 (source firewall.internet-service.id)"
ip_version: "4"
per_ip_shaper: "<your_own_value> (source firewall.shaper.per-ip-shaper.name)"
schedule: "<your_own_value> (source firewall.schedule.onetime.name firewall.schedule.recurring.name firewall.schedule.group.name)"
service:
-
name: "default_name_32 (source firewall.service.custom.name firewall.service.group.name)"
srcaddr:
-
name: "default_name_34 (source firewall.address.name firewall.addrgrp.name)"
srcaddr6:
-
name: "default_name_36 (source firewall.address6.name firewall.addrgrp6.name)"
status: "enable"
traffic_shaper: "<your_own_value> (source firewall.shaper.traffic-shaper.name)"
traffic_shaper_reverse: "<your_own_value> (source firewall.shaper.traffic-shaper.name)"
url_category:
-
id: "41"
users:
-
name: "default_name_43 (source user.local.name)"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_shaping_policy_data(json):
option_list = ['app_category', 'application', 'class_id',
'comment', 'dstaddr', 'dstaddr6',
'dstintf', 'groups', 'id',
'internet_service', 'internet_service_custom', 'internet_service_id',
'internet_service_src', 'internet_service_src_custom', 'internet_service_src_id',
'ip_version', 'per_ip_shaper', 'schedule',
'service', 'srcaddr', 'srcaddr6',
'status', 'traffic_shaper', 'traffic_shaper_reverse',
'url_category', 'users']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_shaping_policy(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_shaping_policy'] and data['firewall_shaping_policy']:
state = data['firewall_shaping_policy']['state']
else:
state = True
firewall_shaping_policy_data = data['firewall_shaping_policy']
filtered_data = underscore_to_hyphen(filter_firewall_shaping_policy_data(firewall_shaping_policy_data))
if state == "present":
return fos.set('firewall',
'shaping-policy',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'shaping-policy',
mkey=filtered_data['id'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_shaping_policy']:
resp = firewall_shaping_policy(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_shaping_policy": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"app_category": {"required": False, "type": "list",
"options": {
"id": {"required": True, "type": "int"}
}},
"application": {"required": False, "type": "list",
"options": {
"id": {"required": True, "type": "int"}
}},
"class_id": {"required": False, "type": "int"},
"comment": {"required": False, "type": "str"},
"dstaddr": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"dstaddr6": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"dstintf": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"groups": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"id": {"required": True, "type": "int"},
"internet_service": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"internet_service_custom": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"internet_service_id": {"required": False, "type": "list",
"options": {
"id": {"required": True, "type": "int"}
}},
"internet_service_src": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"internet_service_src_custom": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"internet_service_src_id": {"required": False, "type": "list",
"options": {
"id": {"required": True, "type": "int"}
}},
"ip_version": {"required": False, "type": "str",
"choices": ["4", "6"]},
"per_ip_shaper": {"required": False, "type": "str"},
"schedule": {"required": False, "type": "str"},
"service": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"srcaddr": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"srcaddr6": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"traffic_shaper": {"required": False, "type": "str"},
"traffic_shaper_reverse": {"required": False, "type": "str"},
"url_category": {"required": False, "type": "list",
"options": {
"id": {"required": True, "type": "int"}
}},
"users": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,389 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_shaping_profile
short_description: Configure shaping profiles in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and shaping_profile category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_shaping_profile:
description:
- Configure shaping profiles.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
comment:
description:
- Comment.
type: str
default_class_id:
description:
- Default class ID to handle unclassified packets (including all local traffic).
type: int
profile_name:
description:
- Shaping profile name.
type: str
shaping_entries:
description:
- Define shaping entries of this shaping profile.
type: list
suboptions:
class_id:
description:
- Class ID.
type: int
guaranteed_bandwidth_percentage:
description:
- Guaranteed bandwith in percentage.
type: int
id:
description:
- ID number.
required: true
type: int
maximum_bandwidth_percentage:
description:
- Maximum bandwith in percentage.
type: int
priority:
description:
- Priority.
type: str
choices:
- high
- medium
- low
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure shaping profiles.
fortios_firewall_shaping_profile:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_shaping_profile:
comment: "Comment."
default_class_id: "4"
profile_name: "<your_own_value>"
shaping_entries:
-
class_id: "7"
guaranteed_bandwidth_percentage: "8"
id: "9"
maximum_bandwidth_percentage: "10"
priority: "high"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_shaping_profile_data(json):
option_list = ['comment', 'default_class_id', 'profile_name',
'shaping_entries']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_shaping_profile(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_shaping_profile'] and data['firewall_shaping_profile']:
state = data['firewall_shaping_profile']['state']
else:
state = True
firewall_shaping_profile_data = data['firewall_shaping_profile']
filtered_data = underscore_to_hyphen(filter_firewall_shaping_profile_data(firewall_shaping_profile_data))
if state == "present":
return fos.set('firewall',
'shaping-profile',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'shaping-profile',
mkey=filtered_data['profile-name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_shaping_profile']:
resp = firewall_shaping_profile(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_shaping_profile": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"comment": {"required": False, "type": "str"},
"default_class_id": {"required": False, "type": "int"},
"profile_name": {"required": False, "type": "str"},
"shaping_entries": {"required": False, "type": "list",
"options": {
"class_id": {"required": False, "type": "int"},
"guaranteed_bandwidth_percentage": {"required": False, "type": "int"},
"id": {"required": True, "type": "int"},
"maximum_bandwidth_percentage": {"required": False, "type": "int"},
"priority": {"required": False, "type": "str",
"choices": ["high", "medium", "low"]}
}}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,629 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_sniffer
short_description: Configure sniffer in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and sniffer category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_sniffer:
description:
- Configure sniffer.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
anomaly:
description:
- Configuration method to edit Denial of Service (DoS) anomaly settings.
type: list
suboptions:
action:
description:
- Action taken when the threshold is reached.
type: str
choices:
- pass
- block
log:
description:
- Enable/disable anomaly logging.
type: str
choices:
- enable
- disable
name:
description:
- Anomaly name.
required: true
type: str
quarantine:
description:
- Quarantine method.
type: str
choices:
- none
- attacker
quarantine_expiry:
description:
- Duration of quarantine. (Format ###d##h##m, minimum 1m, maximum 364d23h59m). Requires quarantine set to attacker.
type: str
quarantine_log:
description:
- Enable/disable quarantine logging.
type: str
choices:
- disable
- enable
status:
description:
- Enable/disable this anomaly.
type: str
choices:
- disable
- enable
threshold:
description:
- Anomaly threshold. Number of detected instances per minute that triggers the anomaly action.
type: int
threshold(default):
description:
- Number of detected instances per minute which triggers action (1 - 2147483647). Note that each anomaly has a different threshold
value assigned to it.
type: int
application_list:
description:
- Name of an existing application list. Source application.list.name.
type: str
application_list_status:
description:
- Enable/disable application control profile.
type: str
choices:
- enable
- disable
av_profile:
description:
- Name of an existing antivirus profile. Source antivirus.profile.name.
type: str
av_profile_status:
description:
- Enable/disable antivirus profile.
type: str
choices:
- enable
- disable
dlp_sensor:
description:
- Name of an existing DLP sensor. Source dlp.sensor.name.
type: str
dlp_sensor_status:
description:
- Enable/disable DLP sensor.
type: str
choices:
- enable
- disable
dsri:
description:
- Enable/disable DSRI.
type: str
choices:
- enable
- disable
host:
description:
- "Hosts to filter for in sniffer traffic (Format examples: 1.1.1.1, 2.2.2.0/24, 3.3.3.3/255.255.255.0, 4.4.4.0-4.4.4.240)."
type: str
id:
description:
- Sniffer ID.
required: true
type: int
interface:
description:
- Interface name that traffic sniffing will take place on. Source system.interface.name.
type: str
ips_dos_status:
description:
- Enable/disable IPS DoS anomaly detection.
type: str
choices:
- enable
- disable
ips_sensor:
description:
- Name of an existing IPS sensor. Source ips.sensor.name.
type: str
ips_sensor_status:
description:
- Enable/disable IPS sensor.
type: str
choices:
- enable
- disable
ipv6:
description:
- Enable/disable sniffing IPv6 packets.
type: str
choices:
- enable
- disable
logtraffic:
description:
- Either log all sessions, only sessions that have a security profile applied, or disable all logging for this policy.
type: str
choices:
- all
- utm
- disable
max_packet_count:
description:
- Maximum packet count (1 - 1000000).
type: int
non_ip:
description:
- Enable/disable sniffing non-IP packets.
type: str
choices:
- enable
- disable
port:
description:
- "Ports to sniff (Format examples: 10, :20, 30:40, 50-, 100-200)."
type: str
protocol:
description:
- Integer value for the protocol type as defined by IANA (0 - 255).
type: str
scan_botnet_connections:
description:
- Enable/disable scanning of connections to Botnet servers.
type: str
choices:
- disable
- block
- monitor
spamfilter_profile:
description:
- Name of an existing spam filter profile. Source spamfilter.profile.name.
type: str
spamfilter_profile_status:
description:
- Enable/disable spam filter.
type: str
choices:
- enable
- disable
status:
description:
- Enable/disable the active status of the sniffer.
type: str
choices:
- enable
- disable
vlan:
description:
- List of VLANs to sniff.
type: str
webfilter_profile:
description:
- Name of an existing web filter profile. Source webfilter.profile.name.
type: str
webfilter_profile_status:
description:
- Enable/disable web filter profile.
type: str
choices:
- enable
- disable
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure sniffer.
fortios_firewall_sniffer:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_sniffer:
anomaly:
-
action: "pass"
log: "enable"
name: "default_name_6"
quarantine: "none"
quarantine_expiry: "<your_own_value>"
quarantine_log: "disable"
status: "disable"
threshold: "11"
threshold(default): "12"
application_list: "<your_own_value> (source application.list.name)"
application_list_status: "enable"
av_profile: "<your_own_value> (source antivirus.profile.name)"
av_profile_status: "enable"
dlp_sensor: "<your_own_value> (source dlp.sensor.name)"
dlp_sensor_status: "enable"
dsri: "enable"
host: "myhostname"
id: "21"
interface: "<your_own_value> (source system.interface.name)"
ips_dos_status: "enable"
ips_sensor: "<your_own_value> (source ips.sensor.name)"
ips_sensor_status: "enable"
ipv6: "enable"
logtraffic: "all"
max_packet_count: "28"
non_ip: "enable"
port: "<your_own_value>"
protocol: "<your_own_value>"
scan_botnet_connections: "disable"
spamfilter_profile: "<your_own_value> (source spamfilter.profile.name)"
spamfilter_profile_status: "enable"
status: "enable"
vlan: "<your_own_value>"
webfilter_profile: "<your_own_value> (source webfilter.profile.name)"
webfilter_profile_status: "enable"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_sniffer_data(json):
option_list = ['anomaly', 'application_list', 'application_list_status',
'av_profile', 'av_profile_status', 'dlp_sensor',
'dlp_sensor_status', 'dsri', 'host',
'id', 'interface', 'ips_dos_status',
'ips_sensor', 'ips_sensor_status', 'ipv6',
'logtraffic', 'max_packet_count', 'non_ip',
'port', 'protocol', 'scan_botnet_connections',
'spamfilter_profile', 'spamfilter_profile_status', 'status',
'vlan', 'webfilter_profile', 'webfilter_profile_status']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_sniffer(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_sniffer'] and data['firewall_sniffer']:
state = data['firewall_sniffer']['state']
else:
state = True
firewall_sniffer_data = data['firewall_sniffer']
filtered_data = underscore_to_hyphen(filter_firewall_sniffer_data(firewall_sniffer_data))
if state == "present":
return fos.set('firewall',
'sniffer',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'sniffer',
mkey=filtered_data['id'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_sniffer']:
resp = firewall_sniffer(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_sniffer": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"anomaly": {"required": False, "type": "list",
"options": {
"action": {"required": False, "type": "str",
"choices": ["pass", "block"]},
"log": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"name": {"required": True, "type": "str"},
"quarantine": {"required": False, "type": "str",
"choices": ["none", "attacker"]},
"quarantine_expiry": {"required": False, "type": "str"},
"quarantine_log": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"status": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"threshold": {"required": False, "type": "int"},
"threshold(default)": {"required": False, "type": "int"}
}},
"application_list": {"required": False, "type": "str"},
"application_list_status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"av_profile": {"required": False, "type": "str"},
"av_profile_status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"dlp_sensor": {"required": False, "type": "str"},
"dlp_sensor_status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"dsri": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"host": {"required": False, "type": "str"},
"id": {"required": True, "type": "int"},
"interface": {"required": False, "type": "str"},
"ips_dos_status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"ips_sensor": {"required": False, "type": "str"},
"ips_sensor_status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"ipv6": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"logtraffic": {"required": False, "type": "str",
"choices": ["all", "utm", "disable"]},
"max_packet_count": {"required": False, "type": "int"},
"non_ip": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"port": {"required": False, "type": "str"},
"protocol": {"required": False, "type": "str"},
"scan_botnet_connections": {"required": False, "type": "str",
"choices": ["disable", "block", "monitor"]},
"spamfilter_profile": {"required": False, "type": "str"},
"spamfilter_profile_status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"vlan": {"required": False, "type": "str"},
"webfilter_profile": {"required": False, "type": "str"},
"webfilter_profile_status": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,396 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_ssh_host_key
short_description: SSH proxy host public keys in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall_ssh feature and host_key category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_ssh_host_key:
description:
- SSH proxy host public keys.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
hostname:
description:
- Hostname of the SSH server.
type: str
ip:
description:
- IP address of the SSH server.
type: str
name:
description:
- SSH public key name.
required: true
type: str
nid:
description:
- Set the nid of the ECDSA key.
type: str
choices:
- 256
- 384
- 521
port:
description:
- Port of the SSH server.
type: int
public_key:
description:
- SSH public key.
type: str
status:
description:
- Set the trust status of the public key.
type: str
choices:
- trusted
- revoked
type:
description:
- Set the type of the public key.
type: str
choices:
- RSA
- DSA
- ECDSA
- ED25519
- RSA-CA
- DSA-CA
- ECDSA-CA
- ED25519-CA
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: SSH proxy host public keys.
fortios_firewall_ssh_host_key:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_ssh_host_key:
hostname: "myhostname"
ip: "<your_own_value>"
name: "default_name_5"
nid: "256"
port: "7"
public_key: "<your_own_value>"
status: "trusted"
type: "RSA"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_ssh_host_key_data(json):
option_list = ['hostname', 'ip', 'name',
'nid', 'port', 'public_key',
'status', 'type']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_ssh_host_key(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_ssh_host_key'] and data['firewall_ssh_host_key']:
state = data['firewall_ssh_host_key']['state']
else:
state = True
firewall_ssh_host_key_data = data['firewall_ssh_host_key']
filtered_data = underscore_to_hyphen(filter_firewall_ssh_host_key_data(firewall_ssh_host_key_data))
if state == "present":
return fos.set('firewall.ssh',
'host-key',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall.ssh',
'host-key',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall_ssh(data, fos):
if data['firewall_ssh_host_key']:
resp = firewall_ssh_host_key(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_ssh_host_key": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"hostname": {"required": False, "type": "str"},
"ip": {"required": False, "type": "str"},
"name": {"required": True, "type": "str"},
"nid": {"required": False, "type": "str",
"choices": ["256", "384", "521"]},
"port": {"required": False, "type": "int"},
"public_key": {"required": False, "type": "str"},
"status": {"required": False, "type": "str",
"choices": ["trusted", "revoked"]},
"type": {"required": False, "type": "str",
"choices": ["RSA", "DSA", "ECDSA",
"ED25519", "RSA-CA", "DSA-CA",
"ECDSA-CA", "ED25519-CA"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall_ssh(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall_ssh(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,360 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_ssh_local_ca
short_description: SSH proxy local CA in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall_ssh feature and local_ca category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_ssh_local_ca:
description:
- SSH proxy local CA.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
name:
description:
- SSH proxy local CA name.
required: true
type: str
password:
description:
- Password for SSH private key.
type: str
private_key:
description:
- SSH proxy private key, encrypted with a password.
type: str
public_key:
description:
- SSH proxy public key.
type: str
source:
description:
- SSH proxy local CA source type.
type: str
choices:
- built-in
- user
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: SSH proxy local CA.
fortios_firewall_ssh_local_ca:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_ssh_local_ca:
name: "default_name_3"
password: "<your_own_value>"
private_key: "<your_own_value>"
public_key: "<your_own_value>"
source: "built-in"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_ssh_local_ca_data(json):
option_list = ['name', 'password', 'private_key',
'public_key', 'source']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_ssh_local_ca(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_ssh_local_ca'] and data['firewall_ssh_local_ca']:
state = data['firewall_ssh_local_ca']['state']
else:
state = True
firewall_ssh_local_ca_data = data['firewall_ssh_local_ca']
filtered_data = underscore_to_hyphen(filter_firewall_ssh_local_ca_data(firewall_ssh_local_ca_data))
if state == "present":
return fos.set('firewall.ssh',
'local-ca',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall.ssh',
'local-ca',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall_ssh(data, fos):
if data['firewall_ssh_local_ca']:
resp = firewall_ssh_local_ca(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_ssh_local_ca": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"name": {"required": True, "type": "str"},
"password": {"required": False, "type": "str"},
"private_key": {"required": False, "type": "str"},
"public_key": {"required": False, "type": "str"},
"source": {"required": False, "type": "str",
"choices": ["built-in", "user"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall_ssh(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall_ssh(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,360 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_ssh_local_key
short_description: SSH proxy local keys in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall_ssh feature and local_key category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_ssh_local_key:
description:
- SSH proxy local keys.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
name:
description:
- SSH proxy local key name.
required: true
type: str
password:
description:
- Password for SSH private key.
type: str
private_key:
description:
- SSH proxy private key, encrypted with a password.
type: str
public_key:
description:
- SSH proxy public key.
type: str
source:
description:
- SSH proxy local key source type.
type: str
choices:
- built-in
- user
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: SSH proxy local keys.
fortios_firewall_ssh_local_key:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_ssh_local_key:
name: "default_name_3"
password: "<your_own_value>"
private_key: "<your_own_value>"
public_key: "<your_own_value>"
source: "built-in"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_ssh_local_key_data(json):
option_list = ['name', 'password', 'private_key',
'public_key', 'source']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_ssh_local_key(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_ssh_local_key'] and data['firewall_ssh_local_key']:
state = data['firewall_ssh_local_key']['state']
else:
state = True
firewall_ssh_local_key_data = data['firewall_ssh_local_key']
filtered_data = underscore_to_hyphen(filter_firewall_ssh_local_key_data(firewall_ssh_local_key_data))
if state == "present":
return fos.set('firewall.ssh',
'local-key',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall.ssh',
'local-key',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall_ssh(data, fos):
if data['firewall_ssh_local_key']:
resp = firewall_ssh_local_key(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_ssh_local_key": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"name": {"required": True, "type": "str"},
"password": {"required": False, "type": "str"},
"private_key": {"required": False, "type": "str"},
"public_key": {"required": False, "type": "str"},
"source": {"required": False, "type": "str",
"choices": ["built-in", "user"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall_ssh(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall_ssh(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,344 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_ssh_setting
short_description: SSH proxy settings in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall_ssh feature and setting category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
firewall_ssh_setting:
description:
- SSH proxy settings.
default: null
type: dict
suboptions:
caname:
description:
- CA certificate used by SSH Inspection. Source firewall.ssh.local-ca.name.
type: str
host_trusted_checking:
description:
- Enable/disable host trusted checking.
type: str
choices:
- enable
- disable
hostkey_dsa1024:
description:
- DSA certificate used by SSH proxy. Source firewall.ssh.local-key.name.
type: str
hostkey_ecdsa256:
description:
- ECDSA nid256 certificate used by SSH proxy. Source firewall.ssh.local-key.name.
type: str
hostkey_ecdsa384:
description:
- ECDSA nid384 certificate used by SSH proxy. Source firewall.ssh.local-key.name.
type: str
hostkey_ecdsa521:
description:
- ECDSA nid384 certificate used by SSH proxy. Source firewall.ssh.local-key.name.
type: str
hostkey_ed25519:
description:
- ED25519 hostkey used by SSH proxy. Source firewall.ssh.local-key.name.
type: str
hostkey_rsa2048:
description:
- RSA certificate used by SSH proxy. Source firewall.ssh.local-key.name.
type: str
untrusted_caname:
description:
- Untrusted CA certificate used by SSH Inspection. Source firewall.ssh.local-ca.name.
type: str
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: SSH proxy settings.
fortios_firewall_ssh_setting:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
firewall_ssh_setting:
caname: "<your_own_value> (source firewall.ssh.local-ca.name)"
host_trusted_checking: "enable"
hostkey_dsa1024: "myhostname (source firewall.ssh.local-key.name)"
hostkey_ecdsa256: "myhostname (source firewall.ssh.local-key.name)"
hostkey_ecdsa384: "myhostname (source firewall.ssh.local-key.name)"
hostkey_ecdsa521: "myhostname (source firewall.ssh.local-key.name)"
hostkey_ed25519: "myhostname (source firewall.ssh.local-key.name)"
hostkey_rsa2048: "myhostname (source firewall.ssh.local-key.name)"
untrusted_caname: "<your_own_value> (source firewall.ssh.local-ca.name)"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_ssh_setting_data(json):
option_list = ['caname', 'host_trusted_checking', 'hostkey_dsa1024',
'hostkey_ecdsa256', 'hostkey_ecdsa384', 'hostkey_ecdsa521',
'hostkey_ed25519', 'hostkey_rsa2048', 'untrusted_caname']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_ssh_setting(data, fos):
vdom = data['vdom']
firewall_ssh_setting_data = data['firewall_ssh_setting']
filtered_data = underscore_to_hyphen(filter_firewall_ssh_setting_data(firewall_ssh_setting_data))
return fos.set('firewall.ssh',
'setting',
data=filtered_data,
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall_ssh(data, fos):
if data['firewall_ssh_setting']:
resp = firewall_ssh_setting(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"firewall_ssh_setting": {
"required": False, "type": "dict", "default": None,
"options": {
"caname": {"required": False, "type": "str"},
"host_trusted_checking": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"hostkey_dsa1024": {"required": False, "type": "str"},
"hostkey_ecdsa256": {"required": False, "type": "str"},
"hostkey_ecdsa384": {"required": False, "type": "str"},
"hostkey_ecdsa521": {"required": False, "type": "str"},
"hostkey_ed25519": {"required": False, "type": "str"},
"hostkey_rsa2048": {"required": False, "type": "str"},
"untrusted_caname": {"required": False, "type": "str"}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall_ssh(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall_ssh(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,456 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_ssl_server
short_description: Configure SSL servers in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and ssl_server category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_ssl_server:
description:
- Configure SSL servers.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
add_header_x_forwarded_proto:
description:
- Enable/disable adding an X-Forwarded-Proto header to forwarded requests.
type: str
choices:
- enable
- disable
ip:
description:
- IPv4 address of the SSL server.
type: str
mapped_port:
description:
- Mapped server service port (1 - 65535).
type: int
name:
description:
- Server name.
required: true
type: str
port:
description:
- Server service port (1 - 65535).
type: int
ssl_algorithm:
description:
- Relative strength of encryption algorithms accepted in negotiation.
type: str
choices:
- high
- medium
- low
ssl_cert:
description:
- Name of certificate for SSL connections to this server. Source vpn.certificate.local.name.
type: str
ssl_client_renegotiation:
description:
- Allow or block client renegotiation by server.
type: str
choices:
- allow
- deny
- secure
ssl_dh_bits:
description:
- Bit-size of Diffie-Hellman (DH) prime used in DHE-RSA negotiation.
type: str
choices:
- 768
- 1024
- 1536
- 2048
ssl_max_version:
description:
- Highest SSL/TLS version to negotiate.
type: str
choices:
- tls-1.0
- tls-1.1
- tls-1.2
ssl_min_version:
description:
- Lowest SSL/TLS version to negotiate.
type: str
choices:
- tls-1.0
- tls-1.1
- tls-1.2
ssl_mode:
description:
- SSL/TLS mode for encryption and decryption of traffic.
type: str
choices:
- half
- full
ssl_send_empty_frags:
description:
- Enable/disable sending empty fragments to avoid attack on CBC IV.
type: str
choices:
- enable
- disable
url_rewrite:
description:
- Enable/disable rewriting the URL.
type: str
choices:
- enable
- disable
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure SSL servers.
fortios_firewall_ssl_server:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_ssl_server:
add_header_x_forwarded_proto: "enable"
ip: "<your_own_value>"
mapped_port: "5"
name: "default_name_6"
port: "7"
ssl_algorithm: "high"
ssl_cert: "<your_own_value> (source vpn.certificate.local.name)"
ssl_client_renegotiation: "allow"
ssl_dh_bits: "768"
ssl_max_version: "tls-1.0"
ssl_min_version: "tls-1.0"
ssl_mode: "half"
ssl_send_empty_frags: "enable"
url_rewrite: "enable"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_ssl_server_data(json):
option_list = ['add_header_x_forwarded_proto', 'ip', 'mapped_port',
'name', 'port', 'ssl_algorithm',
'ssl_cert', 'ssl_client_renegotiation', 'ssl_dh_bits',
'ssl_max_version', 'ssl_min_version', 'ssl_mode',
'ssl_send_empty_frags', 'url_rewrite']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_ssl_server(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_ssl_server'] and data['firewall_ssl_server']:
state = data['firewall_ssl_server']['state']
else:
state = True
firewall_ssl_server_data = data['firewall_ssl_server']
filtered_data = underscore_to_hyphen(filter_firewall_ssl_server_data(firewall_ssl_server_data))
if state == "present":
return fos.set('firewall',
'ssl-server',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'ssl-server',
mkey=filtered_data['name'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_ssl_server']:
resp = firewall_ssl_server(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_ssl_server": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"add_header_x_forwarded_proto": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"ip": {"required": False, "type": "str"},
"mapped_port": {"required": False, "type": "int"},
"name": {"required": True, "type": "str"},
"port": {"required": False, "type": "int"},
"ssl_algorithm": {"required": False, "type": "str",
"choices": ["high", "medium", "low"]},
"ssl_cert": {"required": False, "type": "str"},
"ssl_client_renegotiation": {"required": False, "type": "str",
"choices": ["allow", "deny", "secure"]},
"ssl_dh_bits": {"required": False, "type": "str",
"choices": ["768", "1024", "1536",
"2048"]},
"ssl_max_version": {"required": False, "type": "str",
"choices": ["tls-1.0", "tls-1.1", "tls-1.2"]},
"ssl_min_version": {"required": False, "type": "str",
"choices": ["tls-1.0", "tls-1.1", "tls-1.2"]},
"ssl_mode": {"required": False, "type": "str",
"choices": ["half", "full"]},
"ssl_send_empty_frags": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"url_rewrite": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,372 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_ssl_setting
short_description: SSL proxy settings in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall_ssl feature and setting category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
firewall_ssl_setting:
description:
- SSL proxy settings.
default: null
type: dict
suboptions:
abbreviate_handshake:
description:
- Enable/disable use of SSL abbreviated handshake.
type: str
choices:
- enable
- disable
cert_cache_capacity:
description:
- Maximum capacity of the host certificate cache (0 - 500).
type: int
cert_cache_timeout:
description:
- Time limit to keep certificate cache (1 - 120 min).
type: int
kxp_queue_threshold:
description:
- Maximum length of the CP KXP queue. When the queue becomes full, the proxy switches cipher functions to the main CPU (0 - 512).
type: int
no_matching_cipher_action:
description:
- Bypass or drop the connection when no matching cipher is found.
type: str
choices:
- bypass
- drop
proxy_connect_timeout:
description:
- Time limit to make an internal connection to the appropriate proxy process (1 - 60 sec).
type: int
session_cache_capacity:
description:
- Capacity of the SSL session cache (--Obsolete--) (1 - 1000).
type: int
session_cache_timeout:
description:
- Time limit to keep SSL session state (1 - 60 min).
type: int
ssl_dh_bits:
description:
- Bit-size of Diffie-Hellman (DH) prime used in DHE-RSA negotiation.
type: str
choices:
- 768
- 1024
- 1536
- 2048
ssl_queue_threshold:
description:
- Maximum length of the CP SSL queue. When the queue becomes full, the proxy switches cipher functions to the main CPU (0 - 512).
type: int
ssl_send_empty_frags:
description:
- Enable/disable sending empty fragments to avoid attack on CBC IV (for SSL 3.0 and TLS 1.0 only).
type: str
choices:
- enable
- disable
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: SSL proxy settings.
fortios_firewall_ssl_setting:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
firewall_ssl_setting:
abbreviate_handshake: "enable"
cert_cache_capacity: "4"
cert_cache_timeout: "5"
kxp_queue_threshold: "6"
no_matching_cipher_action: "bypass"
proxy_connect_timeout: "8"
session_cache_capacity: "9"
session_cache_timeout: "10"
ssl_dh_bits: "768"
ssl_queue_threshold: "12"
ssl_send_empty_frags: "enable"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_ssl_setting_data(json):
option_list = ['abbreviate_handshake', 'cert_cache_capacity', 'cert_cache_timeout',
'kxp_queue_threshold', 'no_matching_cipher_action', 'proxy_connect_timeout',
'session_cache_capacity', 'session_cache_timeout', 'ssl_dh_bits',
'ssl_queue_threshold', 'ssl_send_empty_frags']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_ssl_setting(data, fos):
vdom = data['vdom']
firewall_ssl_setting_data = data['firewall_ssl_setting']
filtered_data = underscore_to_hyphen(filter_firewall_ssl_setting_data(firewall_ssl_setting_data))
return fos.set('firewall.ssl',
'setting',
data=filtered_data,
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall_ssl(data, fos):
if data['firewall_ssl_setting']:
resp = firewall_ssl_setting(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"firewall_ssl_setting": {
"required": False, "type": "dict", "default": None,
"options": {
"abbreviate_handshake": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"cert_cache_capacity": {"required": False, "type": "int"},
"cert_cache_timeout": {"required": False, "type": "int"},
"kxp_queue_threshold": {"required": False, "type": "int"},
"no_matching_cipher_action": {"required": False, "type": "str",
"choices": ["bypass", "drop"]},
"proxy_connect_timeout": {"required": False, "type": "int"},
"session_cache_capacity": {"required": False, "type": "int"},
"session_cache_timeout": {"required": False, "type": "int"},
"ssl_dh_bits": {"required": False, "type": "str",
"choices": ["768", "1024", "1536",
"2048"]},
"ssl_queue_threshold": {"required": False, "type": "int"},
"ssl_send_empty_frags": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall_ssl(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall_ssl(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

@ -1,406 +0,0 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2019 Fortinet, Inc.
#
# This program 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.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
__metaclass__ = type
ANSIBLE_METADATA = {'status': ['preview'],
'supported_by': 'community',
'metadata_version': '1.1'}
DOCUMENTATION = '''
---
module: fortios_firewall_ttl_policy
short_description: Configure TTL policies in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify firewall feature and ttl_policy category.
Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.5
version_added: "2.8"
author:
- Miguel Angel Munoz (@mamunozgonzalez)
- Nicolas Thomas (@thomnico)
notes:
- Requires fortiosapi library developed by Fortinet
- Run as a local_action in your playbook
requirements:
- fortiosapi>=0.9.8
options:
host:
description:
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
type: str
required: false
password:
description:
- FortiOS or FortiGate password.
type: str
default: ""
vdom:
description:
- Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and
used as a different unit.
type: str
default: root
https:
description:
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
This attribute was present already in previous version in a deeper level.
It has been moved out to this outer level.
type: str
required: false
choices:
- present
- absent
version_added: 2.9
firewall_ttl_policy:
description:
- Configure TTL policies.
default: null
type: dict
suboptions:
state:
description:
- B(Deprecated)
- Starting with Ansible 2.9 we recommend using the top-level 'state' parameter.
- HORIZONTALLINE
- Indicates whether to create or remove the object.
type: str
required: false
choices:
- present
- absent
action:
description:
- Action to be performed on traffic matching this policy .
type: str
choices:
- accept
- deny
id:
description:
- ID.
required: true
type: int
schedule:
description:
- Schedule object from available options. Source firewall.schedule.onetime.name firewall.schedule.recurring.name firewall.schedule.group
.name.
type: str
service:
description:
- Service object(s) from available options. Separate multiple names with a space.
type: list
suboptions:
name:
description:
- Service name. Source firewall.service.custom.name firewall.service.group.name.
required: true
type: str
srcaddr:
description:
- Source address object(s) from available options. Separate multiple names with a space.
type: list
suboptions:
name:
description:
- Address name. Source firewall.address.name firewall.addrgrp.name.
required: true
type: str
srcintf:
description:
- Source interface name from available interfaces. Source system.zone.name system.interface.name.
type: str
status:
description:
- Enable/disable this TTL policy.
type: str
choices:
- enable
- disable
ttl:
description:
- "Value/range to match against the packet's Time to Live value (format: ttl[ - ttl_high], 1 - 255)."
type: str
'''
EXAMPLES = '''
- hosts: localhost
vars:
host: "192.168.122.40"
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure TTL policies.
fortios_firewall_ttl_policy:
host: "{{ host }}"
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
state: "present"
firewall_ttl_policy:
action: "accept"
id: "4"
schedule: "<your_own_value> (source firewall.schedule.onetime.name firewall.schedule.recurring.name firewall.schedule.group.name)"
service:
-
name: "default_name_7 (source firewall.service.custom.name firewall.service.group.name)"
srcaddr:
-
name: "default_name_9 (source firewall.address.name firewall.addrgrp.name)"
srcintf: "<your_own_value> (source system.zone.name system.interface.name)"
status: "enable"
ttl: "<your_own_value>"
'''
RETURN = '''
build:
description: Build number of the fortigate image
returned: always
type: str
sample: '1547'
http_method:
description: Last method used to provision the content into FortiGate
returned: always
type: str
sample: 'PUT'
http_status:
description: Last result given by FortiGate on last operation applied
returned: always
type: str
sample: "200"
mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
type: str
sample: "urlfilter"
path:
description: Path of the table used to fulfill the request
returned: always
type: str
sample: "webfilter"
revision:
description: Internal revision number
returned: always
type: str
sample: "17.0.2.10658"
serial:
description: Serial number of the unit
returned: always
type: str
sample: "FGVMEVYYQT3AB5352"
status:
description: Indication of the operation's result
returned: always
type: str
sample: "success"
vdom:
description: Virtual domain used
returned: always
type: str
sample: "root"
version:
description: Version of the FortiGate
returned: always
type: str
sample: "v5.6.3"
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos):
host = data['host']
username = data['username']
password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on')
if 'https' in data and not data['https']:
fos.https('off')
else:
fos.https('on')
fos.login(host, username, password, verify=ssl_verify)
def filter_firewall_ttl_policy_data(json):
option_list = ['action', 'id', 'schedule',
'service', 'srcaddr', 'srcintf',
'status', 'ttl']
dictionary = {}
for attribute in option_list:
if attribute in json and json[attribute] is not None:
dictionary[attribute] = json[attribute]
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for i, elem in enumerate(data):
data[i] = underscore_to_hyphen(elem)
elif isinstance(data, dict):
new_data = {}
for k, v in data.items():
new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
data = new_data
return data
def firewall_ttl_policy(data, fos):
vdom = data['vdom']
if 'state' in data and data['state']:
state = data['state']
elif 'state' in data['firewall_ttl_policy'] and data['firewall_ttl_policy']:
state = data['firewall_ttl_policy']['state']
else:
state = True
firewall_ttl_policy_data = data['firewall_ttl_policy']
filtered_data = underscore_to_hyphen(filter_firewall_ttl_policy_data(firewall_ttl_policy_data))
if state == "present":
return fos.set('firewall',
'ttl-policy',
data=filtered_data,
vdom=vdom)
elif state == "absent":
return fos.delete('firewall',
'ttl-policy',
mkey=filtered_data['id'],
vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_firewall(data, fos):
if data['firewall_ttl_policy']:
resp = firewall_ttl_policy(data, fos)
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": False, "type": "str"},
"username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"firewall_ttl_policy": {
"required": False, "type": "dict", "default": None,
"options": {
"state": {"required": False, "type": "str",
"choices": ["present", "absent"]},
"action": {"required": False, "type": "str",
"choices": ["accept", "deny"]},
"id": {"required": True, "type": "int"},
"schedule": {"required": False, "type": "str"},
"service": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"srcaddr": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"srcintf": {"required": False, "type": "str"},
"status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"ttl": {"required": False, "type": "str"}
}
}
}
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
# legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_firewall(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
login(module.params, fos)
is_error, has_changed, result = fortios_firewall(module.params, fos)
fos.logout()
if not is_error:
module.exit_json(changed=has_changed, meta=result)
else:
module.fail_json(msg="Error in repo", meta=result)
if __name__ == '__main__':
main()

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save