FortiOS modules for 2.9 - 1 (#60469)

* FortiOS modules for 2.9 - 1

* Fix empty choices and avoid E337,E338 warnings

* Ansible comments on version_added and ignore.txt only on this PR files

* Add version_added also for state attribute

* Avoid null choices on dlp_sensor

* Change required flag according to argspec
pull/60490/head
Miguel Angel Muñoz González 5 years ago committed by Nilashish Chakraborty
parent 5923a64b20
commit 4cae96109b

@ -1,6 +1,6 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2018 Fortinet, Inc.
# 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
@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ 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 by
allowing the user to configure antivirus feature and heuristic category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS 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)
@ -45,36 +42,47 @@ requirements:
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
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
- 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: false
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
@ -88,6 +96,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure global heuristic options.
fortios_antivirus_heuristic:
@ -95,6 +104,7 @@ EXAMPLES = '''
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
antivirus_heuristic:
mode: "pass"
'''
@ -159,14 +169,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
fos = None
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):
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']:
@ -174,7 +186,7 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_antivirus_heuristic_data(json):
@ -188,38 +200,55 @@ def filter_antivirus_heuristic_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = 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 = filter_antivirus_heuristic_data(antivirus_heuristic_data)
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):
login(data)
methodlist = ['antivirus_heuristic']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['antivirus_heuristic']:
resp = antivirus_heuristic(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"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": "False"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"antivirus_heuristic": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"mode": {"required": False, "type": "str",
"choices": ["pass", "block", "disable"]}
@ -230,15 +259,30 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
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")
global fos
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)

@ -1,6 +1,6 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2018 Fortinet, Inc.
# 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
@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ 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 by
allowing the user to configure antivirus feature and quarantine category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS 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)
@ -45,46 +42,59 @@ requirements:
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
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
- 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: false
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:
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
@ -102,10 +112,11 @@ options:
- mm3
- mm4
- mm7
drop-heuristic:
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
@ -124,9 +135,10 @@ options:
- mm3
- mm4
- mm7
drop-infected:
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
@ -148,18 +160,22 @@ options:
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).
quarantine-quota:
type: int
quarantine_quota:
description:
- The amount of disk space to reserve for quarantining files (0 - 4294967295 Mbytes, depends on disk space).
store-blocked:
type: int
store_blocked:
description:
- Quarantine blocked files found in sessions using the selected protocols.
type: str
choices:
- imap
- smtp
@ -177,9 +193,10 @@ options:
- mm3
- mm4
- mm7
store-heuristic:
store_heuristic:
description:
- Quarantine files detected by heuristics found in sessions using the selected protocols.
type: str
choices:
- imap
- smtp
@ -198,9 +215,10 @@ options:
- mm3
- mm4
- mm7
store-infected:
store_infected:
description:
- Quarantine infected files found in sessions using the selected protocols.
type: str
choices:
- imap
- smtp
@ -228,6 +246,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure quarantine options.
fortios_antivirus_quarantine:
@ -235,18 +254,19 @@ EXAMPLES = '''
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
antivirus_quarantine:
agelimit: "3"
destination: "NULL"
drop-blocked: "imap"
drop-heuristic: "imap"
drop-infected: "imap"
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"
quarantine_quota: "10"
store_blocked: "imap"
store_heuristic: "imap"
store_infected: "imap"
'''
RETURN = '''
@ -309,14 +329,16 @@ version:
'''
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
fos = None
def login(data):
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']:
@ -324,14 +346,14 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
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']
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:
@ -341,57 +363,74 @@ def filter_antivirus_quarantine_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = 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 = filter_antivirus_quarantine_data(antivirus_quarantine_data)
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):
login(data)
methodlist = ['antivirus_quarantine']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['antivirus_quarantine']:
resp = antivirus_quarantine(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"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": "False"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"antivirus_quarantine": {
"required": False, "type": "dict",
"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",
"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",
"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",
"drop_infected": {"required": False, "type": "str",
"choices": ["imap", "smtp", "pop3",
"http", "ftp", "nntp",
"imaps", "smtps", "pop3s",
@ -401,22 +440,22 @@ def main():
"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",
"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",
"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",
"store_infected": {"required": False, "type": "str",
"choices": ["imap", "smtp", "pop3",
"http", "ftp", "nntp",
"imaps", "smtps", "pop3s",
@ -430,15 +469,30 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
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")
global fos
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)

@ -1,6 +1,6 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2018 Fortinet, Inc.
# 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
@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ 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 by
allowing the user to configure antivirus feature and settings category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS 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)
@ -45,36 +42,47 @@ requirements:
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
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
- 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: false
default: true
version_added: 2.9
antivirus_settings:
description:
- Configure AntiVirus settings.
default: null
type: dict
suboptions:
default-db:
default_db:
description:
- Select the AV database to be used for AV scanning.
type: str
choices:
- normal
- extended
@ -82,13 +90,15 @@ options:
grayware:
description:
- Enable/disable grayware detection when an AntiVirus profile is applied to traffic.
type: str
choices:
- enable
- disable
override-timeout:
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 = '''
@ -98,6 +108,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure AntiVirus settings.
fortios_antivirus_settings:
@ -105,10 +116,11 @@ EXAMPLES = '''
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
antivirus_settings:
default-db: "normal"
default_db: "normal"
grayware: "enable"
override-timeout: "5"
override_timeout: "5"
'''
RETURN = '''
@ -171,14 +183,16 @@ version:
'''
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
fos = None
def login(data):
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']:
@ -186,11 +200,11 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_antivirus_settings_data(json):
option_list = ['default-db', 'grayware', 'override-timeout']
option_list = ['default_db', 'grayware', 'override_timeout']
dictionary = {}
for attribute in option_list:
@ -200,44 +214,61 @@ def filter_antivirus_settings_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = 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 = filter_antivirus_settings_data(antivirus_settings_data)
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):
login(data)
methodlist = ['antivirus_settings']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['antivirus_settings']:
resp = antivirus_settings(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"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": "False"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"antivirus_settings": {
"required": False, "type": "dict",
"required": False, "type": "dict", "default": None,
"options": {
"default-db": {"required": False, "type": "str",
"default_db": {"required": False, "type": "str",
"choices": ["normal", "extended", "extreme"]},
"grayware": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"override-timeout": {"required": False, "type": "int"}
"override_timeout": {"required": False, "type": "int"}
}
}
@ -245,15 +276,30 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
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")
global fos
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)

@ -1,6 +1,6 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2018 Fortinet, Inc.
# 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
@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ 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 by
allowing the user to configure application feature and custom category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS 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)
@ -45,70 +42,92 @@ requirements:
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
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
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: false
application_custom:
default: true
ssl_verify:
description:
- Configure custom application signatures.
default: null
suboptions:
- 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
- Indicates whether to create or remove the object.
type: str
choices:
- present
- absent
version_added: 2.9
application_custom:
description:
- Configure custom application signatures.
default: null
type: dict
suboptions:
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 = '''
@ -118,6 +137,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure custom application signatures.
fortios_application_custom:
@ -125,8 +145,9 @@ EXAMPLES = '''
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
application_custom:
https: "False"
state: "present"
application_custom:
behavior: "<your_own_value>"
category: "4"
comment: "Comment."
@ -199,14 +220,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
fos = None
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):
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']:
@ -214,7 +237,7 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_application_custom_data(json):
@ -231,48 +254,66 @@ def filter_application_custom_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = 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']
state = data['state']
application_custom_data = data['application_custom']
filtered_data = filter_application_custom_data(application_custom_data)
if application_custom_data['state'] == "present":
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 application_custom_data['state'] == "absent":
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):
login(data)
methodlist = ['application_custom']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['application_custom']:
resp = application_custom(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"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": "False"},
"application_custom": {
"required": False, "type": "dict",
"options": {
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"application_custom": {
"required": False, "type": "dict", "default": None,
"options": {
"behavior": {"required": False, "type": "str"},
"category": {"required": False, "type": "int"},
"comment": {"required": False, "type": "str"},
@ -290,15 +331,30 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
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")
global fos
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)

@ -1,6 +1,6 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2018 Fortinet, Inc.
# 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
@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ 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 by
allowing the user to configure application feature and group category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS 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)
@ -45,65 +42,84 @@ requirements:
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
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
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: false
application_group:
default: true
ssl_verify:
description:
- Configure firewall application groups.
default: null
suboptions:
- 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
- Indicates whether to create or remove the object.
type: str
choices:
- present
- absent
version_added: 2.9
application_group:
description:
- Configure firewall application groups.
default: null
type: dict
suboptions:
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
@ -116,6 +132,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure firewall application groups.
fortios_application_group:
@ -123,8 +140,9 @@ EXAMPLES = '''
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
application_group:
https: "False"
state: "present"
application_group:
application:
-
id: "4"
@ -196,14 +214,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
fos = None
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):
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']:
@ -211,7 +231,7 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_application_group_data(json):
@ -226,48 +246,66 @@ def filter_application_group_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = 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']
state = data['state']
application_group_data = data['application_group']
filtered_data = filter_application_group_data(application_group_data)
if application_group_data['state'] == "present":
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 application_group_data['state'] == "absent":
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):
login(data)
methodlist = ['application_group']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['application_group']:
resp = application_group(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"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": "False"},
"application_group": {
"required": False, "type": "dict",
"options": {
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"application_group": {
"required": False, "type": "dict", "default": None,
"options": {
"application": {"required": False, "type": "list",
"options": {
"id": {"required": True, "type": "int"}
@ -287,15 +325,30 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
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")
global fos
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)

@ -1,6 +1,6 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2018 Fortinet, Inc.
# 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
@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -27,12 +24,12 @@ ANSIBLE_METADATA = {'status': ['preview'],
DOCUMENTATION = '''
---
module: fortios_application_list
short_description: Configure application control lists.
short_description: Configure application control lists in Fortinet's FortiOS and FortiGate.
description:
- This module is able to configure a FortiGate or FortiOS by
allowing the user to configure application feature and list category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS 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)
@ -45,61 +42,78 @@ requirements:
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
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
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: false
application_list:
default: true
ssl_verify:
description:
- Configure application control lists.
default: null
suboptions:
- 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
- Indicates whether to create or remove the object.
type: str
choices:
- present
- absent
app-replacemsg:
version_added: 2.9
application_list:
description:
- Configure application control lists.
default: null
type: dict
suboptions:
app_replacemsg:
description:
- Enable/disable replacement messages for blocked applications.
type: str
choices:
- disable
- enable
comment:
description:
- comments
deep-app-inspection:
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
@ -107,55 +121,68 @@ options:
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:
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.
per-ip-shaper:
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
@ -165,36 +192,44 @@ options:
protocols:
description:
- Application protocol filter.
type: str
quarantine:
description:
- Quarantine method.
type: str
choices:
- none
- attacker
quarantine-expiry:
quarantine_expiry:
description:
- Duration of quarantine. (Format ###d##h##m, minimum 1m, maximum 364d23h59m, default = 5m). Requires quarantine set to attacker.
quarantine-log:
type: str
quarantine_log:
description:
- Enable/disable quarantine logging.
type: str
choices:
- disable
- enable
rate-count:
rate_count:
description:
- Count of the rate.
rate-duration:
type: int
rate_duration:
description:
- Duration (sec) of the rate.
rate-mode:
type: int
rate_mode:
description:
- Rate limit mode.
type: str
choices:
- periodical
- continuous
rate-track:
rate_track:
description:
- Track the packet protocol field.
type: str
choices:
- none
- src-ip
@ -204,37 +239,47 @@ options:
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
session-ttl:
type: int
session_ttl:
description:
- Session TTL (0 = default).
type: int
shaper:
description:
- Traffic shaper. Source firewall.shaper.traffic-shaper.name.
shaper-reverse:
type: str
shaper_reverse:
description:
- Reverse traffic shaper. Source firewall.shaper.traffic-shaper.name.
sub-category:
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.
extended-log:
type: str
extended_log:
description:
- Enable/disable extended logging.
type: str
choices:
- enable
- disable
@ -242,46 +287,54 @@ options:
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:
other_application_action:
description:
- Action for other applications.
type: str
choices:
- pass
- block
other-application-log:
other_application_log:
description:
- Enable/disable logging for other applications.
type: str
choices:
- disable
- enable
p2p-black-list:
p2p_black_list:
description:
- P2P applications to be black listed.
type: str
choices:
- skype
- edonkey
- bittorrent
replacemsg-group:
replacemsg_group:
description:
- Replacement message group. Source system.replacemsg-group.name.
unknown-application-action:
type: str
unknown_application_action:
description:
- Pass or block traffic from unknown applications.
type: str
choices:
- pass
- block
unknown-application-log:
unknown_application_log:
description:
- Enable/disable logging for unknown applications.
type: str
choices:
- disable
- enable
@ -294,6 +347,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure application control lists.
fortios_application_list:
@ -301,11 +355,12 @@ EXAMPLES = '''
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
application_list:
https: "False"
state: "present"
app-replacemsg: "disable"
application_list:
app_replacemsg: "disable"
comment: "comments"
deep-app-inspection: "disable"
deep_app_inspection: "disable"
entries:
-
action: "pass"
@ -318,41 +373,41 @@ EXAMPLES = '''
id: "12"
id: "13"
log: "disable"
log-packet: "disable"
log_packet: "disable"
parameters:
-
id: "17"
value: "<your_own_value>"
per-ip-shaper: "<your_own_value> (source firewall.shaper.per-ip-shaper.name)"
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"
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"
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:
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"
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"
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 = '''
@ -375,7 +430,7 @@ mkey:
description: Master key (id) used in the last call to FortiGate
returned: success
type: str
sample: "key1"
sample: "id"
name:
description: Name of the table used to fulfill the request
returned: always
@ -415,14 +470,16 @@ version:
'''
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
fos = None
def login(data):
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']:
@ -430,70 +487,88 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
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']
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:
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 elem in data:
elem = 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']
state = data['state']
application_list_data = data['application_list']
filtered_data = filter_application_list_data(application_list_data)
if application_list_data['state'] == "present":
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 application_list_data['state'] == "absent":
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):
login(data)
methodlist = ['application_list']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['application_list']:
resp = application_list(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"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": "False"},
"application_list": {
"required": False, "type": "dict",
"options": {
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"app-replacemsg": {"required": False, "type": "str",
"application_list": {
"required": False, "type": "dict", "default": None,
"options": {
"app_replacemsg": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"comment": {"required": False, "type": "str"},
"deep-app-inspection": {"required": False, "type": "str",
"deep_app_inspection": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"entries": {"required": False, "type": "list",
"options": {
@ -511,60 +586,60 @@ def main():
"id": {"required": True, "type": "int"},
"log": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"log-packet": {"required": False, "type": "str",
"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"},
"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",
"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",
"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",
"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"},
"session_ttl": {"required": False, "type": "int"},
"shaper": {"required": False, "type": "str"},
"shaper-reverse": {"required": False, "type": "str"},
"sub-category": {"required": False, "type": "list",
"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",
"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",
"other_application_action": {"required": False, "type": "str",
"choices": ["pass", "block"]},
"other-application-log": {"required": False, "type": "str",
"other_application_log": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"p2p-black-list": {"required": False, "type": "str",
"p2p_black_list": {"required": False, "type": "str",
"choices": ["skype", "edonkey", "bittorrent"]},
"replacemsg-group": {"required": False, "type": "str"},
"unknown-application-action": {"required": False, "type": "str",
"replacemsg_group": {"required": False, "type": "str"},
"unknown_application_action": {"required": False, "type": "str",
"choices": ["pass", "block"]},
"unknown-application-log": {"required": False, "type": "str",
"unknown_application_log": {"required": False, "type": "str",
"choices": ["disable", "enable"]}
}
@ -573,15 +648,30 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
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")
global fos
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)

@ -1,6 +1,6 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2018 Fortinet, Inc.
# 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
@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ 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 by
allowing the user to configure application feature and name category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS 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)
@ -45,90 +42,118 @@ requirements:
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
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
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: false
application_name:
default: true
ssl_verify:
description:
- Configure application signatures.
default: null
suboptions:
- 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
- Indicates whether to create or remove the object.
type: str
choices:
- present
- absent
version_added: 2.9
application_name:
description:
- Configure application signatures.
default: null
type: dict
suboptions:
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.
sub-category:
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 = '''
@ -138,6 +163,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure application signatures.
fortios_application_name:
@ -145,8 +171,9 @@ EXAMPLES = '''
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
application_name:
https: "False"
state: "present"
application_name:
behavior: "<your_own_value>"
category: "4"
id: "5"
@ -160,7 +187,7 @@ EXAMPLES = '''
popularity: "12"
protocol: "<your_own_value>"
risk: "14"
sub-category: "15"
sub_category: "15"
technology: "<your_own_value>"
vendor: "<your_own_value>"
weight: "18"
@ -226,14 +253,16 @@ version:
'''
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
fos = None
def login(data):
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']:
@ -241,14 +270,14 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
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',
'sub_category', 'technology', 'vendor',
'weight']
dictionary = {}
@ -259,48 +288,66 @@ def filter_application_name_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = 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']
state = data['state']
application_name_data = data['application_name']
filtered_data = filter_application_name_data(application_name_data)
if application_name_data['state'] == "present":
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 application_name_data['state'] == "absent":
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):
login(data)
methodlist = ['application_name']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['application_name']:
resp = application_name(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"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": "False"},
"application_name": {
"required": False, "type": "dict",
"options": {
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"application_name": {
"required": False, "type": "dict", "default": None,
"options": {
"behavior": {"required": False, "type": "str"},
"category": {"required": False, "type": "int"},
"id": {"required": False, "type": "int"},
@ -315,7 +362,7 @@ def main():
"popularity": {"required": False, "type": "int"},
"protocol": {"required": False, "type": "str"},
"risk": {"required": False, "type": "int"},
"sub-category": {"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"}
@ -326,15 +373,30 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
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")
global fos
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)

@ -1,6 +1,6 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2018 Fortinet, Inc.
# 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
@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ 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 by
allowing the user to configure application feature and rule_settings category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS 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)
@ -45,43 +42,56 @@ requirements:
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
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
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: false
application_rule_settings:
default: true
ssl_verify:
description:
- Configure application rule settings.
default: null
suboptions:
- 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
- Indicates whether to create or remove the object.
type: str
choices:
- present
- absent
version_added: 2.9
application_rule_settings:
description:
- Configure application rule settings.
default: null
type: dict
suboptions:
id:
description:
- Rule ID.
required: true
type: int
'''
EXAMPLES = '''
@ -91,6 +101,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure application rule settings.
fortios_application_rule_settings:
@ -98,8 +109,9 @@ EXAMPLES = '''
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
application_rule_settings:
https: "False"
state: "present"
application_rule_settings:
id: "3"
'''
@ -163,14 +175,16 @@ version:
'''
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
fos = None
def login(data):
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']:
@ -178,7 +192,7 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_application_rule_settings_data(json):
@ -192,48 +206,66 @@ def filter_application_rule_settings_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = 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']
state = data['state']
application_rule_settings_data = data['application_rule_settings']
filtered_data = filter_application_rule_settings_data(application_rule_settings_data)
if application_rule_settings_data['state'] == "present":
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 application_rule_settings_data['state'] == "absent":
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):
login(data)
methodlist = ['application_rule_settings']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['application_rule_settings']:
resp = application_rule_settings(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"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": "False"},
"application_rule_settings": {
"required": False, "type": "dict",
"options": {
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"application_rule_settings": {
"required": False, "type": "dict", "default": None,
"options": {
"id": {"required": True, "type": "int"}
}
@ -242,15 +274,30 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
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")
global fos
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)

@ -1,6 +1,6 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2018 Fortinet, Inc.
# 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
@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ 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 by
allowing the user to configure authentication feature and rule category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS 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)
@ -45,48 +42,63 @@ requirements:
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
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
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: false
authentication_rule:
default: true
ssl_verify:
description:
- Configure Authentication Rules.
default: null
suboptions:
- 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
- Indicates whether to create or remove the object.
type: str
choices:
- present
- absent
active-auth-method:
version_added: 2.9
authentication_rule:
description:
- Configure Authentication Rules.
default: null
type: dict
suboptions:
active_auth_method:
description:
- Select an active authentication method. Source authentication.scheme.name.
type: str
comments:
description:
- Comment.
ip-based:
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
@ -94,10 +106,12 @@ options:
description:
- Authentication rule name.
required: true
type: str
protocol:
description:
- Select the protocol to use for authentication (default = http). Users connect to the FortiGate using this protocol and are asked to
authenticate.
type: str
choices:
- http
- ftp
@ -106,37 +120,45 @@ options:
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
sso-auth-method:
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:
transaction_based:
description:
- Enable/disable transaction based authentication (default = disable).
type: str
choices:
- enable
- disable
web-auth-cookie:
web_auth_cookie:
description:
- Enable/disable Web authentication cookies (default = disable).
type: str
choices:
- enable
- disable
@ -149,6 +171,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure Authentication Rules.
fortios_authentication_rule:
@ -156,11 +179,12 @@ EXAMPLES = '''
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
authentication_rule:
https: "False"
state: "present"
active-auth-method: "<your_own_value> (source authentication.scheme.name)"
authentication_rule:
active_auth_method: "<your_own_value> (source authentication.scheme.name)"
comments: "<your_own_value>"
ip-based: "enable"
ip_based: "enable"
name: "default_name_6"
protocol: "http"
srcaddr:
@ -169,10 +193,10 @@ EXAMPLES = '''
srcaddr6:
-
name: "default_name_11 (source firewall.address6.name firewall.addrgrp6.name)"
sso-auth-method: "<your_own_value> (source authentication.scheme.name)"
sso_auth_method: "<your_own_value> (source authentication.scheme.name)"
status: "enable"
transaction-based: "enable"
web-auth-cookie: "enable"
transaction_based: "enable"
web_auth_cookie: "enable"
'''
RETURN = '''
@ -235,14 +259,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
fos = None
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):
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']:
@ -250,14 +276,14 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_authentication_rule_data(json):
option_list = ['active-auth-method', 'comments', 'ip-based',
option_list = ['active_auth_method', 'comments', 'ip_based',
'name', 'protocol', 'srcaddr',
'srcaddr6', 'sso-auth-method', 'status',
'transaction-based', 'web-auth-cookie']
'srcaddr6', 'sso_auth_method', 'status',
'transaction_based', 'web_auth_cookie']
dictionary = {}
for attribute in option_list:
@ -267,51 +293,69 @@ def filter_authentication_rule_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = 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']
state = data['state']
authentication_rule_data = data['authentication_rule']
filtered_data = filter_authentication_rule_data(authentication_rule_data)
if authentication_rule_data['state'] == "present":
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 authentication_rule_data['state'] == "absent":
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):
login(data)
methodlist = ['authentication_rule']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['authentication_rule']:
resp = authentication_rule(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"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": "False"},
"authentication_rule": {
"required": False, "type": "dict",
"options": {
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"active-auth-method": {"required": False, "type": "str"},
"authentication_rule": {
"required": False, "type": "dict", "default": None,
"options": {
"active_auth_method": {"required": False, "type": "str"},
"comments": {"required": False, "type": "str"},
"ip-based": {"required": False, "type": "str",
"ip_based": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"name": {"required": True, "type": "str"},
"protocol": {"required": False, "type": "str",
@ -325,12 +369,12 @@ def main():
"options": {
"name": {"required": True, "type": "str"}
}},
"sso-auth-method": {"required": False, "type": "str"},
"sso_auth_method": {"required": False, "type": "str"},
"status": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"transaction-based": {"required": False, "type": "str",
"transaction_based": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"web-auth-cookie": {"required": False, "type": "str",
"web_auth_cookie": {"required": False, "type": "str",
"choices": ["enable", "disable"]}
}
@ -339,15 +383,30 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
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")
global fos
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)

@ -1,6 +1,6 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2018 Fortinet, Inc.
# 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
@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ 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 by
allowing the user to configure authentication feature and scheme category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS 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)
@ -45,57 +42,74 @@ requirements:
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
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
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: false
authentication_scheme:
default: true
ssl_verify:
description:
- Configure Authentication Schemes.
default: null
suboptions:
- 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
- Indicates whether to create or remove the object.
type: str
choices:
- present
- absent
domain-controller:
version_added: 2.9
authentication_scheme:
description:
- Configure Authentication Schemes.
default: null
type: dict
suboptions:
domain_controller:
description:
- Domain controller setting. Source user.domain-controller.name.
fsso-agent-for-ntlm:
type: str
fsso_agent_for_ntlm:
description:
- FSSO agent to use for NTLM authentication. Source user.fsso.name.
fsso-guest:
type: str
fsso_guest:
description:
- Enable/disable user fsso-guest authentication (default = disable).
type: str
choices:
- enable
- disable
kerberos-keytab:
kerberos_keytab:
description:
- Kerberos keytab setting. Source user.krb-keytab.name.
type: str
method:
description:
- Authentication methods (default = basic).
type: str
choices:
- ntlm
- basic
@ -109,29 +123,35 @@ options:
description:
- Authentication scheme name.
required: true
negotiate-ntlm:
type: str
negotiate_ntlm:
description:
- Enable/disable negotiate authentication for NTLM (default = disable).
type: str
choices:
- enable
- disable
require-tfa:
require_tfa:
description:
- Enable/disable two-factor authentication (default = disable).
type: str
choices:
- enable
- disable
ssh-ca:
ssh_ca:
description:
- SSH CA name. Source firewall.ssh.local-ca.name.
user-database:
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 = '''
@ -141,6 +161,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure Authentication Schemes.
fortios_authentication_scheme:
@ -148,18 +169,19 @@ EXAMPLES = '''
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
authentication_scheme:
https: "False"
state: "present"
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)"
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:
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)"
'''
@ -224,14 +246,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
fos = None
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):
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']:
@ -239,14 +263,14 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
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']
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:
@ -256,64 +280,82 @@ def filter_authentication_scheme_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = 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']
state = data['state']
authentication_scheme_data = data['authentication_scheme']
filtered_data = filter_authentication_scheme_data(authentication_scheme_data)
if authentication_scheme_data['state'] == "present":
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 authentication_scheme_data['state'] == "absent":
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):
login(data)
methodlist = ['authentication_scheme']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['authentication_scheme']:
resp = authentication_scheme(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"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": "False"},
"authentication_scheme": {
"required": False, "type": "dict",
"options": {
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "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",
"authentication_scheme": {
"required": False, "type": "dict", "default": None,
"options": {
"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"},
"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",
"negotiate_ntlm": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"require-tfa": {"required": False, "type": "str",
"require_tfa": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"ssh-ca": {"required": False, "type": "str"},
"user-database": {"required": False, "type": "list",
"ssh_ca": {"required": False, "type": "str"},
"user_database": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}}
@ -324,15 +366,30 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
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")
global fos
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)

@ -1,6 +1,6 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2018 Fortinet, Inc.
# 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
@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ 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 by
allowing the user to configure authentication feature and setting category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS 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)
@ -45,60 +42,78 @@ requirements:
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
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
- 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: false
default: true
version_added: 2.9
authentication_setting:
description:
- Configure authentication setting.
default: null
type: dict
suboptions:
active-auth-scheme:
active_auth_scheme:
description:
- Active authentication method (scheme name). Source authentication.scheme.name.
captive-portal:
type: str
captive_portal:
description:
- Captive portal host name. Source firewall.address.name.
captive-portal-ip:
type: str
captive_portal_ip:
description:
- Captive portal IP address.
captive-portal-ip6:
type: str
captive_portal_ip6:
description:
- Captive portal IPv6 address.
captive-portal-port:
type: str
captive_portal_port:
description:
- Captive portal port number (1 - 65535, default = 0).
captive-portal-type:
type: int
captive_portal_type:
description:
- Captive portal type.
type: str
choices:
- fqdn
- ip
captive-portal6:
captive_portal6:
description:
- IPv6 captive portal host name. Source firewall.address6.name.
sso-auth-scheme:
type: str
sso_auth_scheme:
description:
- Single-Sign-On authentication method (scheme name). Source authentication.scheme.name.
type: str
'''
EXAMPLES = '''
@ -108,6 +123,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure authentication setting.
fortios_authentication_setting:
@ -115,15 +131,16 @@ EXAMPLES = '''
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)"
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 = '''
@ -186,14 +203,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
fos = None
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):
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']:
@ -201,13 +220,13 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
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']
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:
@ -217,48 +236,65 @@ def filter_authentication_setting_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = 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 = filter_authentication_setting_data(authentication_setting_data)
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):
login(data)
methodlist = ['authentication_setting']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['authentication_setting']:
resp = authentication_setting(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"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": "False"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"authentication_setting": {
"required": False, "type": "dict",
"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",
"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"}
"captive_portal6": {"required": False, "type": "str"},
"sso_auth_scheme": {"required": False, "type": "str"}
}
}
@ -266,15 +302,30 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
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")
global fos
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)

@ -1,6 +1,6 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2018 Fortinet, Inc.
# 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
@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ 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 by
allowing the user to configure dlp feature and filepattern category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS 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)
@ -45,49 +42,64 @@ requirements:
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
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
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: false
dlp_filepattern:
default: true
ssl_verify:
description:
- Configure file patterns used by DLP blocking.
default: null
suboptions:
- 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
- Indicates whether to create or remove the object.
type: str
choices:
- present
- absent
version_added: 2.9
dlp_filepattern:
description:
- Configure file patterns used by DLP blocking.
default: null
type: dict
suboptions:
comment:
description:
- Optional comments.
type: str
entries:
description:
- Configure file patterns used by DLP blocking.
type: list
suboptions:
file-type:
file_type:
description:
- Select a file type.
type: str
choices:
- 7z
- arj
@ -148,9 +160,10 @@ options:
- chm
- iso
- crx
filter-type:
filter_type:
description:
- Filter by file name pattern or by file type.
type: str
choices:
- pattern
- type
@ -158,13 +171,16 @@ options:
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 = '''
@ -174,6 +190,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure file patterns used by DLP blocking.
fortios_dlp_filepattern:
@ -181,13 +198,14 @@ EXAMPLES = '''
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
dlp_filepattern:
https: "False"
state: "present"
dlp_filepattern:
comment: "Optional comments."
entries:
-
file-type: "7z"
filter-type: "pattern"
file_type: "7z"
filter_type: "pattern"
pattern: "<your_own_value>"
id: "8"
name: "default_name_9"
@ -253,14 +271,16 @@ version:
'''
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
fos = None
def login(data):
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']:
@ -268,7 +288,7 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_dlp_filepattern_data(json):
@ -283,52 +303,70 @@ def filter_dlp_filepattern_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = 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']
state = data['state']
dlp_filepattern_data = data['dlp_filepattern']
filtered_data = filter_dlp_filepattern_data(dlp_filepattern_data)
if dlp_filepattern_data['state'] == "present":
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 dlp_filepattern_data['state'] == "absent":
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):
login(data)
methodlist = ['dlp_filepattern']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['dlp_filepattern']:
resp = dlp_filepattern(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"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": "False"},
"dlp_filepattern": {
"required": False, "type": "dict",
"options": {
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"dlp_filepattern": {
"required": False, "type": "dict", "default": None,
"options": {
"comment": {"required": False, "type": "str"},
"entries": {"required": False, "type": "list",
"options": {
"file-type": {"required": False, "type": "str",
"file_type": {"required": False, "type": "str",
"choices": ["7z", "arj", "cab",
"lzh", "rar", "tar",
"zip", "bzip", "gzip",
@ -349,7 +387,7 @@ def main():
"msi", "mach-o", "dmg",
".net", "xar", "chm",
"iso", "crx"]},
"filter-type": {"required": False, "type": "str",
"filter_type": {"required": False, "type": "str",
"choices": ["pattern", "type"]},
"pattern": {"required": True, "type": "str"}
}},
@ -362,15 +400,30 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
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")
global fos
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)

@ -1,6 +1,6 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2018 Fortinet, Inc.
# 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
@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -30,10 +27,10 @@ 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 by
allowing the user to configure dlp feature and fp_doc_source category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS 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)
@ -46,51 +43,67 @@ requirements:
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
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
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: false
dlp_fp_doc_source:
default: true
ssl_verify:
description:
- Create a DLP fingerprint database by allowing the FortiGate to access a file server containing files from which to create fingerprints.
default: null
suboptions:
- 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
- Indicates whether to create or remove the object.
type: str
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:
date:
description:
- Day of the month on which to scan the server (1 - 31).
file-path:
type: int
file_path:
description:
- Path on the server to the fingerprint files (max 119 characters).
file-pattern:
type: str
file_pattern:
description:
- Files matching this pattern on the server are fingerprinted. Optionally use the * and ? wildcards.
keep-modified:
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
@ -98,32 +111,38 @@ options:
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:
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:
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:
scan_subdirectories:
description:
- Enable/disable scanning subdirectories to find files to create fingerprints from.
type: str
choices:
- enable
- disable
@ -131,32 +150,40 @@ options:
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.
server-type:
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:
tod_hour:
description:
- Hour of the day on which to scan the server (0 - 23, default = 1).
tod-min:
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
@ -174,6 +201,7 @@ EXAMPLES = '''
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:
@ -181,23 +209,24 @@ EXAMPLES = '''
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
dlp_fp_doc_source:
https: "False"
state: "present"
dlp_fp_doc_source:
date: "3"
file-path: "<your_own_value>"
file-pattern: "<your_own_value>"
keep-modified: "enable"
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"
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"
server_type: "samba"
tod_hour: "16"
tod_min: "17"
username: "<your_own_value>"
vdom: "mgmt"
weekday: "sunday"
@ -263,14 +292,16 @@ version:
'''
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
fos = None
def login(data):
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']:
@ -278,15 +309,15 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
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',
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 = {}
@ -297,70 +328,88 @@ def filter_dlp_fp_doc_source_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = 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']
state = data['state']
dlp_fp_doc_source_data = data['dlp_fp_doc_source']
filtered_data = filter_dlp_fp_doc_source_data(dlp_fp_doc_source_data)
if dlp_fp_doc_source_data['state'] == "present":
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 dlp_fp_doc_source_data['state'] == "absent":
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):
login(data)
methodlist = ['dlp_fp_doc_source']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['dlp_fp_doc_source']:
resp = dlp_fp_doc_source(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"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": "False"},
"dlp_fp_doc_source": {
"required": False, "type": "dict",
"options": {
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"dlp_fp_doc_source": {
"required": False, "type": "dict", "default": None,
"options": {
"date": {"required": False, "type": "int"},
"file-path": {"required": False, "type": "str"},
"file-pattern": {"required": False, "type": "str"},
"keep-modified": {"required": False, "type": "str",
"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",
"remove_deleted": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"scan-on-creation": {"required": False, "type": "str",
"scan_on_creation": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"scan-subdirectories": {"required": False, "type": "str",
"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",
"server_type": {"required": False, "type": "str",
"choices": ["samba"]},
"tod-hour": {"required": False, "type": "int"},
"tod-min": {"required": False, "type": "int"},
"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"]},
@ -375,15 +424,30 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
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")
global fos
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)

@ -1,6 +1,6 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2018 Fortinet, Inc.
# 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
@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -30,10 +27,10 @@ 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 by
allowing the user to configure dlp feature and fp_sensitivity category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS 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)
@ -46,43 +43,56 @@ requirements:
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
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
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: false
dlp_fp_sensitivity:
default: true
ssl_verify:
description:
- Create self-explanatory DLP sensitivity levels to be used when setting sensitivity under config fp-doc-source.
default: null
suboptions:
- 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
- Indicates whether to create or remove the object.
type: str
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:
name:
description:
- DLP Sensitivity Levels.
required: true
type: str
'''
EXAMPLES = '''
@ -92,6 +102,7 @@ EXAMPLES = '''
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:
@ -99,8 +110,9 @@ EXAMPLES = '''
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
dlp_fp_sensitivity:
https: "False"
state: "present"
dlp_fp_sensitivity:
name: "default_name_3"
'''
@ -164,14 +176,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
fos = None
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):
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']:
@ -179,7 +193,7 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_dlp_fp_sensitivity_data(json):
@ -193,48 +207,66 @@ def filter_dlp_fp_sensitivity_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = 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']
state = data['state']
dlp_fp_sensitivity_data = data['dlp_fp_sensitivity']
filtered_data = filter_dlp_fp_sensitivity_data(dlp_fp_sensitivity_data)
if dlp_fp_sensitivity_data['state'] == "present":
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 dlp_fp_sensitivity_data['state'] == "absent":
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):
login(data)
methodlist = ['dlp_fp_sensitivity']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['dlp_fp_sensitivity']:
resp = dlp_fp_sensitivity(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"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": "False"},
"dlp_fp_sensitivity": {
"required": False, "type": "dict",
"options": {
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"dlp_fp_sensitivity": {
"required": False, "type": "dict", "default": None,
"options": {
"name": {"required": True, "type": "str"}
}
@ -243,15 +275,30 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
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")
global fos
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)

@ -1,6 +1,6 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2018 Fortinet, Inc.
# 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
@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ 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 by
allowing the user to configure dlp feature and sensor category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS 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)
@ -45,61 +42,78 @@ requirements:
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
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
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: false
dlp_sensor:
default: true
ssl_verify:
description:
- Configure DLP sensors.
default: null
suboptions:
- 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
- Indicates whether to create or remove the object.
type: str
choices:
- present
- absent
version_added: 2.9
dlp_sensor:
description:
- Configure DLP sensors.
default: null
type: dict
suboptions:
comment:
description:
- Comment.
dlp-log:
type: str
dlp_log:
description:
- Enable/disable DLP logging.
type: str
choices:
- enable
- disable
extended-log:
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
@ -108,24 +122,30 @@ options:
archive:
description:
- Enable/disable DLP archiving.
type: str
choices:
- disable
- enable
company-identifier:
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).
file-size:
type: str
file_size:
description:
- Match files this size or larger (0 - 4294967295 kbytes).
file-type:
type: int
file_type:
description:
- Select the number of a DLP file pattern table to match. Source dlp.filepattern.id.
filter-by:
type: int
filter_by:
description:
- Select the type of content to match.
type: str
choices:
- credit-card
- ssn
@ -135,27 +155,33 @@ options:
- fingerprint
- watermark
- encrypted
fp-sensitivity:
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
match-percentage:
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
@ -172,9 +198,11 @@ options:
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
@ -184,18 +212,21 @@ options:
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:
flow_based:
description:
- Enable/disable flow-based DLP.
type: str
choices:
- enable
- disable
full-archive-proto:
full_archive_proto:
description:
- Protocols to always content archive.
type: str
choices:
- smtp
- pop3
@ -209,9 +240,10 @@ options:
- mm3
- mm4
- mm7
nac-quar-log:
nac_quar_log:
description:
- Enable/disable NAC quarantine logging.
type: str
choices:
- enable
- disable
@ -219,15 +251,19 @@ options:
description:
- Name of the DLP sensor.
required: true
type: str
options:
description:
- Configure DLP options.
replacemsg-group:
type: str
replacemsg_group:
description:
- Replacement message group used by this DLP sensor. Source system.replacemsg-group.name.
summary-proto:
type: str
summary_proto:
description:
- Protocols to always log summary.
type: str
choices:
- smtp
- pop3
@ -250,6 +286,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure DLP sensors.
fortios_dlp_sensor:
@ -257,37 +294,38 @@ EXAMPLES = '''
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
dlp_sensor:
https: "False"
state: "present"
dlp_sensor:
comment: "Comment."
dlp-log: "enable"
extended-log: "enable"
dlp_log: "enable"
extended_log: "enable"
filter:
-
action: "allow"
archive: "disable"
company-identifier: "myId_9"
company_identifier: "myId_9"
expiry: "<your_own_value>"
file-size: "11"
file-type: "12 (source dlp.filepattern.id)"
filter-by: "credit-card"
fp-sensitivity:
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"
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"
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"
replacemsg_group: "<your_own_value> (source system.replacemsg-group.name)"
summary_proto: "smtp"
'''
RETURN = '''
@ -350,14 +388,16 @@ version:
'''
from ansible.module_utils.basic import AnsibleModule
fos = None
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):
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']:
@ -365,14 +405,14 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
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']
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:
@ -382,52 +422,70 @@ def filter_dlp_sensor_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = 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']
state = data['state']
dlp_sensor_data = data['dlp_sensor']
filtered_data = filter_dlp_sensor_data(dlp_sensor_data)
if dlp_sensor_data['state'] == "present":
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 dlp_sensor_data['state'] == "absent":
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):
login(data)
methodlist = ['dlp_sensor']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['dlp_sensor']:
resp = dlp_sensor(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"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": "False"},
"dlp_sensor": {
"required": False, "type": "dict",
"options": {
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"dlp_sensor": {
"required": False, "type": "dict", "default": None,
"options": {
"comment": {"required": False, "type": "str"},
"dlp-log": {"required": False, "type": "str",
"dlp_log": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"extended-log": {"required": False, "type": "str",
"extended_log": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"filter": {"required": False, "type": "list",
"options": {
@ -436,20 +494,20 @@ def main():
"quarantine-ip"]},
"archive": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"company-identifier": {"required": False, "type": "str"},
"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",
"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",
"fp_sensitivity": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"id": {"required": True, "type": "int"},
"match-percentage": {"required": False, "type": "int"},
"match_percentage": {"required": False, "type": "int"},
"name": {"required": False, "type": "str"},
"proto": {"required": False, "type": "str",
"choices": ["smtp", "pop3", "imap",
@ -463,20 +521,19 @@ def main():
"type": {"required": False, "type": "str",
"choices": ["file", "message"]}
}},
"flow-based": {"required": False, "type": "str",
"flow_based": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"full-archive-proto": {"required": False, "type": "str",
"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",
"nac_quar_log": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"name": {"required": True, "type": "str"},
"options": {"required": False, "type": "str",
"choices": []},
"replacemsg-group": {"required": False, "type": "str"},
"summary-proto": {"required": False, "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",
@ -488,15 +545,30 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
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")
global fos
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)

@ -1,6 +1,6 @@
#!/usr/bin/python
from __future__ import (absolute_import, division, print_function)
# Copyright 2018 Fortinet, Inc.
# 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
@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ 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 by
allowing the user to configure dlp feature and settings category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS 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)
@ -45,42 +42,55 @@ requirements:
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
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
- 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: false
default: true
version_added: 2.9
dlp_settings:
description:
- Designate logical storage for DLP fingerprint database.
default: null
type: dict
suboptions:
cache-mem-percent:
cache_mem_percent:
description:
- Maximum percentage of available memory allocated to caching (1 - 15%).
chunk-size:
type: int
chunk_size:
description:
- Maximum fingerprint chunk size. **Changing will flush the entire database**.
db-mode:
type: int
db_mode:
description:
- Behaviour when the maximum size is reached.
type: str
choices:
- stop-adding
- remove-modified-then-oldest
@ -88,9 +98,11 @@ options:
size:
description:
- Maximum total size of files within the storage (MB).
storage-device:
type: int
storage_device:
description:
- Storage device name. Source system.storage.name.
type: str
'''
EXAMPLES = '''
@ -100,6 +112,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Designate logical storage for DLP fingerprint database.
fortios_dlp_settings:
@ -107,12 +120,13 @@ EXAMPLES = '''
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
https: "False"
dlp_settings:
cache-mem-percent: "3"
chunk-size: "4"
db-mode: "stop-adding"
cache_mem_percent: "3"
chunk_size: "4"
db_mode: "stop-adding"
size: "6"
storage-device: "<your_own_value> (source system.storage.name)"
storage_device: "<your_own_value> (source system.storage.name)"
'''
RETURN = '''
@ -175,14 +189,16 @@ version:
'''
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
fos = None
def login(data):
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']:
@ -190,12 +206,12 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
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']
option_list = ['cache_mem_percent', 'chunk_size', 'db_mode',
'size', 'storage_device']
dictionary = {}
for attribute in option_list:
@ -205,45 +221,62 @@ def filter_dlp_settings_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = 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 = filter_dlp_settings_data(dlp_settings_data)
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):
login(data)
methodlist = ['dlp_settings']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['dlp_settings']:
resp = dlp_settings(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"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": "False"},
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"dlp_settings": {
"required": False, "type": "dict",
"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",
"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"}
"storage_device": {"required": False, "type": "str"}
}
}
@ -251,15 +284,30 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
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")
global fos
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)

@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ 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 by
allowing the user to configure dnsfilter feature and domain_filter category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS 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)
@ -45,49 +42,64 @@ requirements:
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
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
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: false
dnsfilter_domain_filter:
default: true
ssl_verify:
description:
- Configure DNS domain filters.
default: null
suboptions:
- 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
- Indicates whether to create or remove the object.
type: str
choices:
- present
- absent
version_added: 2.9
dnsfilter_domain_filter:
description:
- Configure DNS domain filters.
default: null
type: dict
suboptions:
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
@ -95,19 +107,23 @@ options:
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
@ -116,9 +132,11 @@ options:
description:
- ID.
required: true
type: int
name:
description:
- Name of table.
type: str
'''
EXAMPLES = '''
@ -128,6 +146,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure DNS domain filters.
fortios_dnsfilter_domain_filter:
@ -135,8 +154,9 @@ EXAMPLES = '''
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
dnsfilter_domain_filter:
https: "False"
state: "present"
dnsfilter_domain_filter:
comment: "Optional comments."
entries:
-
@ -209,14 +229,16 @@ version:
'''
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
fos = None
def login(data):
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']:
@ -224,7 +246,7 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
fos.login(host, username, password, verify=ssl_verify)
def filter_dnsfilter_domain_filter_data(json):
@ -239,48 +261,66 @@ def filter_dnsfilter_domain_filter_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = 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']
state = data['state']
dnsfilter_domain_filter_data = data['dnsfilter_domain_filter']
filtered_data = filter_dnsfilter_domain_filter_data(dnsfilter_domain_filter_data)
if dnsfilter_domain_filter_data['state'] == "present":
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 dnsfilter_domain_filter_data['state'] == "absent":
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):
login(data)
methodlist = ['dnsfilter_domain_filter']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['dnsfilter_domain_filter']:
resp = dnsfilter_domain_filter(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"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": "False"},
"dnsfilter_domain_filter": {
"required": False, "type": "dict",
"options": {
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"dnsfilter_domain_filter": {
"required": False, "type": "dict", "default": None,
"options": {
"comment": {"required": False, "type": "str"},
"entries": {"required": False, "type": "list",
"options": {
@ -302,15 +342,30 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
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")
global fos
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)

@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ 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 by
allowing the user to configure dnsfilter feature and profile category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS 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)
@ -45,105 +42,132 @@ requirements:
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
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
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: false
dnsfilter_profile:
default: true
ssl_verify:
description:
- Configure DNS domain filter profiles.
default: null
suboptions:
- 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
- Indicates whether to create or remove the object.
type: str
choices:
- present
- absent
block-action:
version_added: 2.9
dnsfilter_profile:
description:
- Configure DNS domain filter profiles.
default: null
type: dict
suboptions:
block_action:
description:
- Action to take for blocked domains.
type: str
choices:
- block
- redirect
block-botnet:
block_botnet:
description:
- Enable/disable blocking botnet C&C DNS lookups.
type: str
choices:
- disable
- enable
comment:
description:
- Comment.
domain-filter:
type: str
domain_filter:
description:
- Domain filter settings.
type: dict
suboptions:
domain-filter-table:
domain_filter_table:
description:
- DNS domain filter table ID. Source dnsfilter.domain-filter.id.
external-ip-blocklist:
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
ftgd-dns:
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:
log_all_domain:
description:
- Enable/disable logging of all domains visited (detailed DNS logging).
type: str
choices:
- enable
- disable
@ -151,30 +175,36 @@ options:
description:
- Profile name.
required: true
redirect-portal:
type: str
redirect_portal:
description:
- IP address of the SDNS redirect portal.
safe-search:
type: str
safe_search:
description:
- Enable/disable Google, Bing, and YouTube safe search.
type: str
choices:
- disable
- enable
sdns-domain-log:
sdns_domain_log:
description:
- Enable/disable domain filtering and botnet domain logging.
type: str
choices:
- enable
- disable
sdns-ftgd-err-log:
sdns_ftgd_err_log:
description:
- Enable/disable FortiGuard SDNS rating error logging.
type: str
choices:
- enable
- disable
youtube-restrict:
youtube_restrict:
description:
- Set safe search for YouTube restriction level.
type: str
choices:
- strict
- moderate
@ -187,6 +217,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure DNS domain filter profiles.
fortios_dnsfilter_profile:
@ -194,17 +225,18 @@ EXAMPLES = '''
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
dnsfilter_profile:
https: "False"
state: "present"
block-action: "block"
block-botnet: "disable"
dnsfilter_profile:
block_action: "block"
block_botnet: "disable"
comment: "Comment."
domain-filter:
domain-filter-table: "7 (source dnsfilter.domain-filter.id)"
external-ip-blocklist:
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:
ftgd_dns:
filters:
-
action: "block"
@ -212,13 +244,13 @@ EXAMPLES = '''
id: "14"
log: "enable"
options: "error-allow"
log-all-domain: "enable"
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"
redirect_portal: "<your_own_value>"
safe_search: "disable"
sdns_domain_log: "enable"
sdns_ftgd_err_log: "enable"
youtube_restrict: "strict"
'''
RETURN = '''
@ -281,14 +313,16 @@ version:
'''
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
fos = None
def login(data):
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']:
@ -296,15 +330,15 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
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']
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:
@ -314,62 +348,80 @@ def filter_dnsfilter_profile_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = 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']
state = data['state']
dnsfilter_profile_data = data['dnsfilter_profile']
filtered_data = filter_dnsfilter_profile_data(dnsfilter_profile_data)
if dnsfilter_profile_data['state'] == "present":
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 dnsfilter_profile_data['state'] == "absent":
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):
login(data)
methodlist = ['dnsfilter_profile']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['dnsfilter_profile']:
resp = dnsfilter_profile(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"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": "False"},
"dnsfilter_profile": {
"required": False, "type": "dict",
"options": {
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"block-action": {"required": False, "type": "str",
"dnsfilter_profile": {
"required": False, "type": "dict", "default": None,
"options": {
"block_action": {"required": False, "type": "str",
"choices": ["block", "redirect"]},
"block-botnet": {"required": False, "type": "str",
"block_botnet": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"comment": {"required": False, "type": "str"},
"domain-filter": {"required": False, "type": "dict",
"domain_filter": {"required": False, "type": "dict",
"options": {
"domain-filter-table": {"required": False, "type": "int"}
"domain_filter_table": {"required": False, "type": "int"}
}},
"external-ip-blocklist": {"required": False, "type": "list",
"external_ip_blocklist": {"required": False, "type": "list",
"options": {
"name": {"required": True, "type": "str"}
}},
"ftgd-dns": {"required": False, "type": "dict",
"ftgd_dns": {"required": False, "type": "dict",
"options": {
"filters": {"required": False, "type": "list",
"options": {
@ -383,17 +435,17 @@ def main():
"options": {"required": False, "type": "str",
"choices": ["error-allow", "ftgd-disable"]}
}},
"log-all-domain": {"required": False, "type": "str",
"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",
"redirect_portal": {"required": False, "type": "str"},
"safe_search": {"required": False, "type": "str",
"choices": ["disable", "enable"]},
"sdns-domain-log": {"required": False, "type": "str",
"sdns_domain_log": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"sdns-ftgd-err-log": {"required": False, "type": "str",
"sdns_ftgd_err_log": {"required": False, "type": "str",
"choices": ["enable", "disable"]},
"youtube-restrict": {"required": False, "type": "str",
"youtube_restrict": {"required": False, "type": "str",
"choices": ["strict", "moderate"]}
}
@ -402,15 +454,30 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
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")
global fos
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)

@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# the lib use python logging can get it if the following is set in your
# Ansible config.
__metaclass__ = type
@ -29,10 +26,10 @@ 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 by
allowing the user to configure endpoint_control feature and client category.
Examples includes all options and need to be adjusted to datasources before usage.
Tested with FOS v6.0.2
- This module is able to configure a FortiGate or FortiOS 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)
@ -45,58 +42,76 @@ requirements:
options:
host:
description:
- FortiOS or FortiGate ip address.
required: true
- FortiOS or FortiGate IP address.
type: str
required: false
username:
description:
- FortiOS or FortiGate username.
required: true
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
- Indicates if the requests towards FortiGate must use HTTPS protocol.
type: bool
default: false
endpoint_control_client:
default: true
ssl_verify:
description:
- Configure endpoint control client lists.
default: null
suboptions:
- 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
- Indicates whether to create or remove the object.
type: str
choices:
- present
- absent
ad-groups:
version_added: 2.9
endpoint_control_client:
description:
- Configure endpoint control client lists.
default: null
type: dict
suboptions:
ad_groups:
description:
- Endpoint client AD logon groups.
ftcl-uid:
type: str
ftcl_uid:
description:
- Endpoint FortiClient UID.
type: str
id:
description:
- Endpoint client ID.
required: true
type: int
info:
description:
- Endpoint client information.
src-ip:
type: str
src_ip:
description:
- Endpoint client IP address.
src-mac:
type: str
src_mac:
description:
- Endpoint client MAC address.
type: str
'''
EXAMPLES = '''
@ -106,6 +121,7 @@ EXAMPLES = '''
username: "admin"
password: ""
vdom: "root"
ssl_verify: "False"
tasks:
- name: Configure endpoint control client lists.
fortios_endpoint_control_client:
@ -113,14 +129,15 @@ EXAMPLES = '''
username: "{{ username }}"
password: "{{ password }}"
vdom: "{{ vdom }}"
endpoint_control_client:
https: "False"
state: "present"
ad-groups: "<your_own_value>"
ftcl-uid: "<your_own_value>"
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>"
src_ip: "<your_own_value>"
src_mac: "<your_own_value>"
'''
RETURN = '''
@ -183,14 +200,16 @@ version:
'''
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
fos = None
def login(data):
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']:
@ -198,12 +217,12 @@ def login(data):
else:
fos.https('on')
fos.login(host, username, password)
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']
option_list = ['ad_groups', 'ftcl_uid', 'id',
'info', 'src_ip', 'src_mac']
dictionary = {}
for attribute in option_list:
@ -213,54 +232,72 @@ def filter_endpoint_control_client_data(json):
return dictionary
def underscore_to_hyphen(data):
if isinstance(data, list):
for elem in data:
elem = 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']
state = data['state']
endpoint_control_client_data = data['endpoint_control_client']
filtered_data = filter_endpoint_control_client_data(endpoint_control_client_data)
if endpoint_control_client_data['state'] == "present":
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 endpoint_control_client_data['state'] == "absent":
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):
login(data)
methodlist = ['endpoint_control_client']
for method in methodlist:
if data[method]:
resp = eval(method)(data, fos)
break
if data['endpoint_control_client']:
resp = endpoint_control_client(data, fos)
fos.logout()
return not resp['status'] == "success", resp['status'] == "success", resp
return not is_successful_status(resp), \
resp['status'] == "success", \
resp
def main():
fields = {
"host": {"required": True, "type": "str"},
"username": {"required": True, "type": "str"},
"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": "False"},
"endpoint_control_client": {
"required": False, "type": "dict",
"options": {
"https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"ad-groups": {"required": False, "type": "str"},
"ftcl-uid": {"required": False, "type": "str"},
"endpoint_control_client": {
"required": False, "type": "dict", "default": None,
"options": {
"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"}
"src_ip": {"required": False, "type": "str"},
"src_mac": {"required": False, "type": "str"}
}
}
@ -268,15 +305,30 @@ def main():
module = AnsibleModule(argument_spec=fields,
supports_check_mode=False)
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")
global fos
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)

@ -3691,42 +3691,8 @@ lib/ansible/modules/network/fortimanager/fmgr_secprof_wanopt.py validate-modules
lib/ansible/modules/network/fortimanager/fmgr_secprof_web.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_address.py validate-modules:E324
lib/ansible/modules/network/fortios/fortios_address.py validate-modules:E338
lib/ansible/modules/network/fortios/fortios_antivirus_heuristic.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_antivirus_profile.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_antivirus_profile.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_antivirus_quarantine.py validate-modules:E326
lib/ansible/modules/network/fortios/fortios_antivirus_quarantine.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_antivirus_quarantine.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_antivirus_settings.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_antivirus_settings.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_application_custom.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_application_group.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_application_list.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_application_list.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_application_name.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_application_name.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_application_rule_settings.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_authentication_rule.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_authentication_rule.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_authentication_scheme.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_authentication_scheme.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_authentication_setting.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_authentication_setting.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_config.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_dlp_filepattern.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_dlp_filepattern.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_dlp_fp_doc_source.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_dlp_fp_doc_source.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_dlp_fp_sensitivity.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_dlp_sensor.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_dlp_sensor.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_dlp_settings.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_dlp_settings.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_dnsfilter_domain_filter.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_dnsfilter_profile.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_dnsfilter_profile.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_endpoint_control_client.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_endpoint_control_client.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_endpoint_control_forticlient_ems.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_endpoint_control_forticlient_ems.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_endpoint_control_forticlient_registration_sync.py validate-modules:E336

@ -0,0 +1,151 @@
# 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 Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_antivirus_heuristic
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_antivirus_heuristic.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_antivirus_heuristic_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'antivirus_heuristic': {
'mode': 'pass'
},
'vdom': 'root'}
is_error, changed, response = fortios_antivirus_heuristic.fortios_antivirus(input_data, fos_instance)
expected_data = {
'mode': 'pass'
}
set_method_mock.assert_called_with('antivirus', 'heuristic', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_antivirus_heuristic_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'antivirus_heuristic': {
'mode': 'pass'
},
'vdom': 'root'}
is_error, changed, response = fortios_antivirus_heuristic.fortios_antivirus(input_data, fos_instance)
expected_data = {
'mode': 'pass'
}
set_method_mock.assert_called_with('antivirus', 'heuristic', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_antivirus_heuristic_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'antivirus_heuristic': {
'mode': 'pass'
},
'vdom': 'root'}
is_error, changed, response = fortios_antivirus_heuristic.fortios_antivirus(input_data, fos_instance)
expected_data = {
'mode': 'pass'
}
set_method_mock.assert_called_with('antivirus', 'heuristic', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_antivirus_heuristic_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'antivirus_heuristic': {
'random_attribute_not_valid': 'tag',
'mode': 'pass'
},
'vdom': 'root'}
is_error, changed, response = fortios_antivirus_heuristic.fortios_antivirus(input_data, fos_instance)
expected_data = {
'mode': 'pass'
}
set_method_mock.assert_called_with('antivirus', 'heuristic', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,339 @@
# 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 Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_antivirus_profile
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_antivirus_profile.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_antivirus_profile_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'antivirus_profile': {
'analytics_bl_filetype': '3',
'analytics_db': 'disable',
'analytics_max_upload': '5',
'analytics_wl_filetype': '6',
'av_block_log': 'enable',
'av_virus_log': 'enable',
'comment': 'Comment.',
'extended_log': 'enable',
'ftgd_analytics': 'disable',
'inspection_mode': 'proxy',
'mobile_malware_db': 'disable',
'name': 'default_name_14',
'replacemsg_group': 'test_value_15',
'scan_mode': 'quick',
},
'vdom': 'root'}
is_error, changed, response = fortios_antivirus_profile.fortios_antivirus(input_data, fos_instance)
expected_data = {
'analytics-bl-filetype': '3',
'analytics-db': 'disable',
'analytics-max-upload': '5',
'analytics-wl-filetype': '6',
'av-block-log': 'enable',
'av-virus-log': 'enable',
'comment': 'Comment.',
'extended-log': 'enable',
'ftgd-analytics': 'disable',
'inspection-mode': 'proxy',
'mobile-malware-db': 'disable',
'name': 'default_name_14',
'replacemsg-group': 'test_value_15',
'scan-mode': 'quick',
}
set_method_mock.assert_called_with('antivirus', 'profile', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_antivirus_profile_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'antivirus_profile': {
'analytics_bl_filetype': '3',
'analytics_db': 'disable',
'analytics_max_upload': '5',
'analytics_wl_filetype': '6',
'av_block_log': 'enable',
'av_virus_log': 'enable',
'comment': 'Comment.',
'extended_log': 'enable',
'ftgd_analytics': 'disable',
'inspection_mode': 'proxy',
'mobile_malware_db': 'disable',
'name': 'default_name_14',
'replacemsg_group': 'test_value_15',
'scan_mode': 'quick',
},
'vdom': 'root'}
is_error, changed, response = fortios_antivirus_profile.fortios_antivirus(input_data, fos_instance)
expected_data = {
'analytics-bl-filetype': '3',
'analytics-db': 'disable',
'analytics-max-upload': '5',
'analytics-wl-filetype': '6',
'av-block-log': 'enable',
'av-virus-log': 'enable',
'comment': 'Comment.',
'extended-log': 'enable',
'ftgd-analytics': 'disable',
'inspection-mode': 'proxy',
'mobile-malware-db': 'disable',
'name': 'default_name_14',
'replacemsg-group': 'test_value_15',
'scan-mode': 'quick',
}
set_method_mock.assert_called_with('antivirus', 'profile', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_antivirus_profile_removal(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'antivirus_profile': {
'analytics_bl_filetype': '3',
'analytics_db': 'disable',
'analytics_max_upload': '5',
'analytics_wl_filetype': '6',
'av_block_log': 'enable',
'av_virus_log': 'enable',
'comment': 'Comment.',
'extended_log': 'enable',
'ftgd_analytics': 'disable',
'inspection_mode': 'proxy',
'mobile_malware_db': 'disable',
'name': 'default_name_14',
'replacemsg_group': 'test_value_15',
'scan_mode': 'quick',
},
'vdom': 'root'}
is_error, changed, response = fortios_antivirus_profile.fortios_antivirus(input_data, fos_instance)
delete_method_mock.assert_called_with('antivirus', 'profile', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_antivirus_profile_deletion_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'antivirus_profile': {
'analytics_bl_filetype': '3',
'analytics_db': 'disable',
'analytics_max_upload': '5',
'analytics_wl_filetype': '6',
'av_block_log': 'enable',
'av_virus_log': 'enable',
'comment': 'Comment.',
'extended_log': 'enable',
'ftgd_analytics': 'disable',
'inspection_mode': 'proxy',
'mobile_malware_db': 'disable',
'name': 'default_name_14',
'replacemsg_group': 'test_value_15',
'scan_mode': 'quick',
},
'vdom': 'root'}
is_error, changed, response = fortios_antivirus_profile.fortios_antivirus(input_data, fos_instance)
delete_method_mock.assert_called_with('antivirus', 'profile', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_antivirus_profile_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'antivirus_profile': {
'analytics_bl_filetype': '3',
'analytics_db': 'disable',
'analytics_max_upload': '5',
'analytics_wl_filetype': '6',
'av_block_log': 'enable',
'av_virus_log': 'enable',
'comment': 'Comment.',
'extended_log': 'enable',
'ftgd_analytics': 'disable',
'inspection_mode': 'proxy',
'mobile_malware_db': 'disable',
'name': 'default_name_14',
'replacemsg_group': 'test_value_15',
'scan_mode': 'quick',
},
'vdom': 'root'}
is_error, changed, response = fortios_antivirus_profile.fortios_antivirus(input_data, fos_instance)
expected_data = {
'analytics-bl-filetype': '3',
'analytics-db': 'disable',
'analytics-max-upload': '5',
'analytics-wl-filetype': '6',
'av-block-log': 'enable',
'av-virus-log': 'enable',
'comment': 'Comment.',
'extended-log': 'enable',
'ftgd-analytics': 'disable',
'inspection-mode': 'proxy',
'mobile-malware-db': 'disable',
'name': 'default_name_14',
'replacemsg-group': 'test_value_15',
'scan-mode': 'quick',
}
set_method_mock.assert_called_with('antivirus', 'profile', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_antivirus_profile_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'antivirus_profile': {
'random_attribute_not_valid': 'tag',
'analytics_bl_filetype': '3',
'analytics_db': 'disable',
'analytics_max_upload': '5',
'analytics_wl_filetype': '6',
'av_block_log': 'enable',
'av_virus_log': 'enable',
'comment': 'Comment.',
'extended_log': 'enable',
'ftgd_analytics': 'disable',
'inspection_mode': 'proxy',
'mobile_malware_db': 'disable',
'name': 'default_name_14',
'replacemsg_group': 'test_value_15',
'scan_mode': 'quick',
},
'vdom': 'root'}
is_error, changed, response = fortios_antivirus_profile.fortios_antivirus(input_data, fos_instance)
expected_data = {
'analytics-bl-filetype': '3',
'analytics-db': 'disable',
'analytics-max-upload': '5',
'analytics-wl-filetype': '6',
'av-block-log': 'enable',
'av-virus-log': 'enable',
'comment': 'Comment.',
'extended-log': 'enable',
'ftgd-analytics': 'disable',
'inspection-mode': 'proxy',
'mobile-malware-db': 'disable',
'name': 'default_name_14',
'replacemsg-group': 'test_value_15',
'scan-mode': 'quick',
}
set_method_mock.assert_called_with('antivirus', 'profile', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,231 @@
# 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 Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_antivirus_quarantine
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_antivirus_quarantine.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_antivirus_quarantine_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'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'
},
'vdom': 'root'}
is_error, changed, response = fortios_antivirus_quarantine.fortios_antivirus(input_data, fos_instance)
expected_data = {
'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'
}
set_method_mock.assert_called_with('antivirus', 'quarantine', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_antivirus_quarantine_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'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'
},
'vdom': 'root'}
is_error, changed, response = fortios_antivirus_quarantine.fortios_antivirus(input_data, fos_instance)
expected_data = {
'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'
}
set_method_mock.assert_called_with('antivirus', 'quarantine', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_antivirus_quarantine_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'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'
},
'vdom': 'root'}
is_error, changed, response = fortios_antivirus_quarantine.fortios_antivirus(input_data, fos_instance)
expected_data = {
'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'
}
set_method_mock.assert_called_with('antivirus', 'quarantine', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_antivirus_quarantine_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'antivirus_quarantine': {
'random_attribute_not_valid': 'tag',
'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'
},
'vdom': 'root'}
is_error, changed, response = fortios_antivirus_quarantine.fortios_antivirus(input_data, fos_instance)
expected_data = {
'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'
}
set_method_mock.assert_called_with('antivirus', 'quarantine', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,167 @@
# 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 Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_antivirus_settings
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_antivirus_settings.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_antivirus_settings_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'antivirus_settings': {
'default_db': 'normal',
'grayware': 'enable',
'override_timeout': '5'
},
'vdom': 'root'}
is_error, changed, response = fortios_antivirus_settings.fortios_antivirus(input_data, fos_instance)
expected_data = {
'default-db': 'normal',
'grayware': 'enable',
'override-timeout': '5'
}
set_method_mock.assert_called_with('antivirus', 'settings', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_antivirus_settings_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'antivirus_settings': {
'default_db': 'normal',
'grayware': 'enable',
'override_timeout': '5'
},
'vdom': 'root'}
is_error, changed, response = fortios_antivirus_settings.fortios_antivirus(input_data, fos_instance)
expected_data = {
'default-db': 'normal',
'grayware': 'enable',
'override-timeout': '5'
}
set_method_mock.assert_called_with('antivirus', 'settings', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_antivirus_settings_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'antivirus_settings': {
'default_db': 'normal',
'grayware': 'enable',
'override_timeout': '5'
},
'vdom': 'root'}
is_error, changed, response = fortios_antivirus_settings.fortios_antivirus(input_data, fos_instance)
expected_data = {
'default-db': 'normal',
'grayware': 'enable',
'override-timeout': '5'
}
set_method_mock.assert_called_with('antivirus', 'settings', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_antivirus_settings_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'antivirus_settings': {
'random_attribute_not_valid': 'tag',
'default_db': 'normal',
'grayware': 'enable',
'override_timeout': '5'
},
'vdom': 'root'}
is_error, changed, response = fortios_antivirus_settings.fortios_antivirus(input_data, fos_instance)
expected_data = {
'default-db': 'normal',
'grayware': 'enable',
'override-timeout': '5'
}
set_method_mock.assert_called_with('antivirus', 'settings', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,289 @@
# 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 Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_application_custom
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_application_custom.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_application_custom_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'application_custom': {
'behavior': 'test_value_3',
'category': '4',
'comment': 'Comment.',
'id': '6',
'name': 'default_name_7',
'protocol': 'test_value_8',
'signature': 'test_value_9',
'tag': 'test_value_10',
'technology': 'test_value_11',
'vendor': 'test_value_12'
},
'vdom': 'root'}
is_error, changed, response = fortios_application_custom.fortios_application(input_data, fos_instance)
expected_data = {
'behavior': 'test_value_3',
'category': '4',
'comment': 'Comment.',
'id': '6',
'name': 'default_name_7',
'protocol': 'test_value_8',
'signature': 'test_value_9',
'tag': 'test_value_10',
'technology': 'test_value_11',
'vendor': 'test_value_12'
}
set_method_mock.assert_called_with('application', 'custom', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_application_custom_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'application_custom': {
'behavior': 'test_value_3',
'category': '4',
'comment': 'Comment.',
'id': '6',
'name': 'default_name_7',
'protocol': 'test_value_8',
'signature': 'test_value_9',
'tag': 'test_value_10',
'technology': 'test_value_11',
'vendor': 'test_value_12'
},
'vdom': 'root'}
is_error, changed, response = fortios_application_custom.fortios_application(input_data, fos_instance)
expected_data = {
'behavior': 'test_value_3',
'category': '4',
'comment': 'Comment.',
'id': '6',
'name': 'default_name_7',
'protocol': 'test_value_8',
'signature': 'test_value_9',
'tag': 'test_value_10',
'technology': 'test_value_11',
'vendor': 'test_value_12'
}
set_method_mock.assert_called_with('application', 'custom', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_application_custom_removal(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'application_custom': {
'behavior': 'test_value_3',
'category': '4',
'comment': 'Comment.',
'id': '6',
'name': 'default_name_7',
'protocol': 'test_value_8',
'signature': 'test_value_9',
'tag': 'test_value_10',
'technology': 'test_value_11',
'vendor': 'test_value_12'
},
'vdom': 'root'}
is_error, changed, response = fortios_application_custom.fortios_application(input_data, fos_instance)
delete_method_mock.assert_called_with('application', 'custom', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_application_custom_deletion_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'application_custom': {
'behavior': 'test_value_3',
'category': '4',
'comment': 'Comment.',
'id': '6',
'name': 'default_name_7',
'protocol': 'test_value_8',
'signature': 'test_value_9',
'tag': 'test_value_10',
'technology': 'test_value_11',
'vendor': 'test_value_12'
},
'vdom': 'root'}
is_error, changed, response = fortios_application_custom.fortios_application(input_data, fos_instance)
delete_method_mock.assert_called_with('application', 'custom', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_application_custom_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'application_custom': {
'behavior': 'test_value_3',
'category': '4',
'comment': 'Comment.',
'id': '6',
'name': 'default_name_7',
'protocol': 'test_value_8',
'signature': 'test_value_9',
'tag': 'test_value_10',
'technology': 'test_value_11',
'vendor': 'test_value_12'
},
'vdom': 'root'}
is_error, changed, response = fortios_application_custom.fortios_application(input_data, fos_instance)
expected_data = {
'behavior': 'test_value_3',
'category': '4',
'comment': 'Comment.',
'id': '6',
'name': 'default_name_7',
'protocol': 'test_value_8',
'signature': 'test_value_9',
'tag': 'test_value_10',
'technology': 'test_value_11',
'vendor': 'test_value_12'
}
set_method_mock.assert_called_with('application', 'custom', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_application_custom_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'application_custom': {
'random_attribute_not_valid': 'tag',
'behavior': 'test_value_3',
'category': '4',
'comment': 'Comment.',
'id': '6',
'name': 'default_name_7',
'protocol': 'test_value_8',
'signature': 'test_value_9',
'tag': 'test_value_10',
'technology': 'test_value_11',
'vendor': 'test_value_12'
},
'vdom': 'root'}
is_error, changed, response = fortios_application_custom.fortios_application(input_data, fos_instance)
expected_data = {
'behavior': 'test_value_3',
'category': '4',
'comment': 'Comment.',
'id': '6',
'name': 'default_name_7',
'protocol': 'test_value_8',
'signature': 'test_value_9',
'tag': 'test_value_10',
'technology': 'test_value_11',
'vendor': 'test_value_12'
}
set_method_mock.assert_called_with('application', 'custom', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,209 @@
# 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 Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_application_group
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_application_group.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_application_group_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'application_group': {'comment': 'Comment',
'name': 'default_name_4',
'type': 'application'
},
'vdom': 'root'}
is_error, changed, response = fortios_application_group.fortios_application(input_data, fos_instance)
expected_data = {'comment': 'Comment',
'name': 'default_name_4',
'type': 'application'
}
set_method_mock.assert_called_with('application', 'group', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_application_group_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'application_group': {'comment': 'Comment',
'name': 'default_name_4',
'type': 'application'
},
'vdom': 'root'}
is_error, changed, response = fortios_application_group.fortios_application(input_data, fos_instance)
expected_data = {'comment': 'Comment',
'name': 'default_name_4',
'type': 'application'
}
set_method_mock.assert_called_with('application', 'group', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_application_group_removal(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'application_group': {'comment': 'Comment',
'name': 'default_name_4',
'type': 'application'
},
'vdom': 'root'}
is_error, changed, response = fortios_application_group.fortios_application(input_data, fos_instance)
delete_method_mock.assert_called_with('application', 'group', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_application_group_deletion_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'application_group': {'comment': 'Comment',
'name': 'default_name_4',
'type': 'application'
},
'vdom': 'root'}
is_error, changed, response = fortios_application_group.fortios_application(input_data, fos_instance)
delete_method_mock.assert_called_with('application', 'group', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_application_group_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'application_group': {'comment': 'Comment',
'name': 'default_name_4',
'type': 'application'
},
'vdom': 'root'}
is_error, changed, response = fortios_application_group.fortios_application(input_data, fos_instance)
expected_data = {'comment': 'Comment',
'name': 'default_name_4',
'type': 'application'
}
set_method_mock.assert_called_with('application', 'group', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_application_group_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'application_group': {
'random_attribute_not_valid': 'tag', 'comment': 'Comment',
'name': 'default_name_4',
'type': 'application'
},
'vdom': 'root'}
is_error, changed, response = fortios_application_group.fortios_application(input_data, fos_instance)
expected_data = {'comment': 'Comment',
'name': 'default_name_4',
'type': 'application'
}
set_method_mock.assert_called_with('application', 'group', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,309 @@
# 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 Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_application_list
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_application_list.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_application_list_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'application_list': {
'app_replacemsg': 'disable',
'comment': 'comments',
'deep_app_inspection': 'disable',
'extended_log': 'enable',
'name': 'default_name_7',
'options': 'allow-dns',
'other_application_action': 'pass',
'other_application_log': 'disable',
'p2p_black_list': 'skype',
'replacemsg_group': 'test_value_12',
'unknown_application_action': 'pass',
'unknown_application_log': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_application_list.fortios_application(input_data, fos_instance)
expected_data = {
'app-replacemsg': 'disable',
'comment': 'comments',
'deep-app-inspection': 'disable',
'extended-log': 'enable',
'name': 'default_name_7',
'options': 'allow-dns',
'other-application-action': 'pass',
'other-application-log': 'disable',
'p2p-black-list': 'skype',
'replacemsg-group': 'test_value_12',
'unknown-application-action': 'pass',
'unknown-application-log': 'disable'
}
set_method_mock.assert_called_with('application', 'list', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_application_list_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'application_list': {
'app_replacemsg': 'disable',
'comment': 'comments',
'deep_app_inspection': 'disable',
'extended_log': 'enable',
'name': 'default_name_7',
'options': 'allow-dns',
'other_application_action': 'pass',
'other_application_log': 'disable',
'p2p_black_list': 'skype',
'replacemsg_group': 'test_value_12',
'unknown_application_action': 'pass',
'unknown_application_log': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_application_list.fortios_application(input_data, fos_instance)
expected_data = {
'app-replacemsg': 'disable',
'comment': 'comments',
'deep-app-inspection': 'disable',
'extended-log': 'enable',
'name': 'default_name_7',
'options': 'allow-dns',
'other-application-action': 'pass',
'other-application-log': 'disable',
'p2p-black-list': 'skype',
'replacemsg-group': 'test_value_12',
'unknown-application-action': 'pass',
'unknown-application-log': 'disable'
}
set_method_mock.assert_called_with('application', 'list', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_application_list_removal(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'application_list': {
'app_replacemsg': 'disable',
'comment': 'comments',
'deep_app_inspection': 'disable',
'extended_log': 'enable',
'name': 'default_name_7',
'options': 'allow-dns',
'other_application_action': 'pass',
'other_application_log': 'disable',
'p2p_black_list': 'skype',
'replacemsg_group': 'test_value_12',
'unknown_application_action': 'pass',
'unknown_application_log': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_application_list.fortios_application(input_data, fos_instance)
delete_method_mock.assert_called_with('application', 'list', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_application_list_deletion_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'application_list': {
'app_replacemsg': 'disable',
'comment': 'comments',
'deep_app_inspection': 'disable',
'extended_log': 'enable',
'name': 'default_name_7',
'options': 'allow-dns',
'other_application_action': 'pass',
'other_application_log': 'disable',
'p2p_black_list': 'skype',
'replacemsg_group': 'test_value_12',
'unknown_application_action': 'pass',
'unknown_application_log': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_application_list.fortios_application(input_data, fos_instance)
delete_method_mock.assert_called_with('application', 'list', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_application_list_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'application_list': {
'app_replacemsg': 'disable',
'comment': 'comments',
'deep_app_inspection': 'disable',
'extended_log': 'enable',
'name': 'default_name_7',
'options': 'allow-dns',
'other_application_action': 'pass',
'other_application_log': 'disable',
'p2p_black_list': 'skype',
'replacemsg_group': 'test_value_12',
'unknown_application_action': 'pass',
'unknown_application_log': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_application_list.fortios_application(input_data, fos_instance)
expected_data = {
'app-replacemsg': 'disable',
'comment': 'comments',
'deep-app-inspection': 'disable',
'extended-log': 'enable',
'name': 'default_name_7',
'options': 'allow-dns',
'other-application-action': 'pass',
'other-application-log': 'disable',
'p2p-black-list': 'skype',
'replacemsg-group': 'test_value_12',
'unknown-application-action': 'pass',
'unknown-application-log': 'disable'
}
set_method_mock.assert_called_with('application', 'list', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_application_list_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'application_list': {
'random_attribute_not_valid': 'tag',
'app_replacemsg': 'disable',
'comment': 'comments',
'deep_app_inspection': 'disable',
'extended_log': 'enable',
'name': 'default_name_7',
'options': 'allow-dns',
'other_application_action': 'pass',
'other_application_log': 'disable',
'p2p_black_list': 'skype',
'replacemsg_group': 'test_value_12',
'unknown_application_action': 'pass',
'unknown_application_log': 'disable'
},
'vdom': 'root'}
is_error, changed, response = fortios_application_list.fortios_application(input_data, fos_instance)
expected_data = {
'app-replacemsg': 'disable',
'comment': 'comments',
'deep-app-inspection': 'disable',
'extended-log': 'enable',
'name': 'default_name_7',
'options': 'allow-dns',
'other-application-action': 'pass',
'other-application-log': 'disable',
'p2p-black-list': 'skype',
'replacemsg-group': 'test_value_12',
'unknown-application-action': 'pass',
'unknown-application-log': 'disable'
}
set_method_mock.assert_called_with('application', 'list', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,309 @@
# 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 Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_application_name
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_application_name.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_application_name_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'application_name': {
'behavior': 'test_value_3',
'category': '4',
'id': '5',
'name': 'default_name_6',
'parameter': 'test_value_7',
'popularity': '8',
'protocol': 'test_value_9',
'risk': '10',
'sub_category': '11',
'technology': 'test_value_12',
'vendor': 'test_value_13',
'weight': '14'
},
'vdom': 'root'}
is_error, changed, response = fortios_application_name.fortios_application(input_data, fos_instance)
expected_data = {
'behavior': 'test_value_3',
'category': '4',
'id': '5',
'name': 'default_name_6',
'parameter': 'test_value_7',
'popularity': '8',
'protocol': 'test_value_9',
'risk': '10',
'sub-category': '11',
'technology': 'test_value_12',
'vendor': 'test_value_13',
'weight': '14'
}
set_method_mock.assert_called_with('application', 'name', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_application_name_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'application_name': {
'behavior': 'test_value_3',
'category': '4',
'id': '5',
'name': 'default_name_6',
'parameter': 'test_value_7',
'popularity': '8',
'protocol': 'test_value_9',
'risk': '10',
'sub_category': '11',
'technology': 'test_value_12',
'vendor': 'test_value_13',
'weight': '14'
},
'vdom': 'root'}
is_error, changed, response = fortios_application_name.fortios_application(input_data, fos_instance)
expected_data = {
'behavior': 'test_value_3',
'category': '4',
'id': '5',
'name': 'default_name_6',
'parameter': 'test_value_7',
'popularity': '8',
'protocol': 'test_value_9',
'risk': '10',
'sub-category': '11',
'technology': 'test_value_12',
'vendor': 'test_value_13',
'weight': '14'
}
set_method_mock.assert_called_with('application', 'name', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_application_name_removal(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'application_name': {
'behavior': 'test_value_3',
'category': '4',
'id': '5',
'name': 'default_name_6',
'parameter': 'test_value_7',
'popularity': '8',
'protocol': 'test_value_9',
'risk': '10',
'sub_category': '11',
'technology': 'test_value_12',
'vendor': 'test_value_13',
'weight': '14'
},
'vdom': 'root'}
is_error, changed, response = fortios_application_name.fortios_application(input_data, fos_instance)
delete_method_mock.assert_called_with('application', 'name', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_application_name_deletion_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'application_name': {
'behavior': 'test_value_3',
'category': '4',
'id': '5',
'name': 'default_name_6',
'parameter': 'test_value_7',
'popularity': '8',
'protocol': 'test_value_9',
'risk': '10',
'sub_category': '11',
'technology': 'test_value_12',
'vendor': 'test_value_13',
'weight': '14'
},
'vdom': 'root'}
is_error, changed, response = fortios_application_name.fortios_application(input_data, fos_instance)
delete_method_mock.assert_called_with('application', 'name', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_application_name_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'application_name': {
'behavior': 'test_value_3',
'category': '4',
'id': '5',
'name': 'default_name_6',
'parameter': 'test_value_7',
'popularity': '8',
'protocol': 'test_value_9',
'risk': '10',
'sub_category': '11',
'technology': 'test_value_12',
'vendor': 'test_value_13',
'weight': '14'
},
'vdom': 'root'}
is_error, changed, response = fortios_application_name.fortios_application(input_data, fos_instance)
expected_data = {
'behavior': 'test_value_3',
'category': '4',
'id': '5',
'name': 'default_name_6',
'parameter': 'test_value_7',
'popularity': '8',
'protocol': 'test_value_9',
'risk': '10',
'sub-category': '11',
'technology': 'test_value_12',
'vendor': 'test_value_13',
'weight': '14'
}
set_method_mock.assert_called_with('application', 'name', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_application_name_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'application_name': {
'random_attribute_not_valid': 'tag',
'behavior': 'test_value_3',
'category': '4',
'id': '5',
'name': 'default_name_6',
'parameter': 'test_value_7',
'popularity': '8',
'protocol': 'test_value_9',
'risk': '10',
'sub_category': '11',
'technology': 'test_value_12',
'vendor': 'test_value_13',
'weight': '14'
},
'vdom': 'root'}
is_error, changed, response = fortios_application_name.fortios_application(input_data, fos_instance)
expected_data = {
'behavior': 'test_value_3',
'category': '4',
'id': '5',
'name': 'default_name_6',
'parameter': 'test_value_7',
'popularity': '8',
'protocol': 'test_value_9',
'risk': '10',
'sub-category': '11',
'technology': 'test_value_12',
'vendor': 'test_value_13',
'weight': '14'
}
set_method_mock.assert_called_with('application', 'name', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,199 @@
# 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 Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_application_rule_settings
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_application_rule_settings.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_application_rule_settings_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'application_rule_settings': {
'id': '3'
},
'vdom': 'root'}
is_error, changed, response = fortios_application_rule_settings.fortios_application(input_data, fos_instance)
expected_data = {
'id': '3'
}
set_method_mock.assert_called_with('application', 'rule-settings', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_application_rule_settings_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'application_rule_settings': {
'id': '3'
},
'vdom': 'root'}
is_error, changed, response = fortios_application_rule_settings.fortios_application(input_data, fos_instance)
expected_data = {
'id': '3'
}
set_method_mock.assert_called_with('application', 'rule-settings', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_application_rule_settings_removal(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'application_rule_settings': {
'id': '3'
},
'vdom': 'root'}
is_error, changed, response = fortios_application_rule_settings.fortios_application(input_data, fos_instance)
delete_method_mock.assert_called_with('application', 'rule-settings', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_application_rule_settings_deletion_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'application_rule_settings': {
'id': '3'
},
'vdom': 'root'}
is_error, changed, response = fortios_application_rule_settings.fortios_application(input_data, fos_instance)
delete_method_mock.assert_called_with('application', 'rule-settings', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_application_rule_settings_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'application_rule_settings': {
'id': '3'
},
'vdom': 'root'}
is_error, changed, response = fortios_application_rule_settings.fortios_application(input_data, fos_instance)
expected_data = {
'id': '3'
}
set_method_mock.assert_called_with('application', 'rule-settings', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_application_rule_settings_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'application_rule_settings': {
'random_attribute_not_valid': 'tag',
'id': '3'
},
'vdom': 'root'}
is_error, changed, response = fortios_application_rule_settings.fortios_application(input_data, fos_instance)
expected_data = {
'id': '3'
}
set_method_mock.assert_called_with('application', 'rule-settings', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,279 @@
# 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 Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_authentication_rule
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_authentication_rule.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_authentication_rule_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'authentication_rule': {
'active_auth_method': 'test_value_3',
'comments': 'test_value_4',
'ip_based': 'enable',
'name': 'default_name_6',
'protocol': 'http',
'sso_auth_method': 'test_value_8',
'status': 'enable',
'transaction_based': 'enable',
'web_auth_cookie': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_authentication_rule.fortios_authentication(input_data, fos_instance)
expected_data = {
'active-auth-method': 'test_value_3',
'comments': 'test_value_4',
'ip-based': 'enable',
'name': 'default_name_6',
'protocol': 'http',
'sso-auth-method': 'test_value_8',
'status': 'enable',
'transaction-based': 'enable',
'web-auth-cookie': 'enable'
}
set_method_mock.assert_called_with('authentication', 'rule', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_authentication_rule_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'authentication_rule': {
'active_auth_method': 'test_value_3',
'comments': 'test_value_4',
'ip_based': 'enable',
'name': 'default_name_6',
'protocol': 'http',
'sso_auth_method': 'test_value_8',
'status': 'enable',
'transaction_based': 'enable',
'web_auth_cookie': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_authentication_rule.fortios_authentication(input_data, fos_instance)
expected_data = {
'active-auth-method': 'test_value_3',
'comments': 'test_value_4',
'ip-based': 'enable',
'name': 'default_name_6',
'protocol': 'http',
'sso-auth-method': 'test_value_8',
'status': 'enable',
'transaction-based': 'enable',
'web-auth-cookie': 'enable'
}
set_method_mock.assert_called_with('authentication', 'rule', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_authentication_rule_removal(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'authentication_rule': {
'active_auth_method': 'test_value_3',
'comments': 'test_value_4',
'ip_based': 'enable',
'name': 'default_name_6',
'protocol': 'http',
'sso_auth_method': 'test_value_8',
'status': 'enable',
'transaction_based': 'enable',
'web_auth_cookie': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_authentication_rule.fortios_authentication(input_data, fos_instance)
delete_method_mock.assert_called_with('authentication', 'rule', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_authentication_rule_deletion_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'authentication_rule': {
'active_auth_method': 'test_value_3',
'comments': 'test_value_4',
'ip_based': 'enable',
'name': 'default_name_6',
'protocol': 'http',
'sso_auth_method': 'test_value_8',
'status': 'enable',
'transaction_based': 'enable',
'web_auth_cookie': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_authentication_rule.fortios_authentication(input_data, fos_instance)
delete_method_mock.assert_called_with('authentication', 'rule', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_authentication_rule_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'authentication_rule': {
'active_auth_method': 'test_value_3',
'comments': 'test_value_4',
'ip_based': 'enable',
'name': 'default_name_6',
'protocol': 'http',
'sso_auth_method': 'test_value_8',
'status': 'enable',
'transaction_based': 'enable',
'web_auth_cookie': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_authentication_rule.fortios_authentication(input_data, fos_instance)
expected_data = {
'active-auth-method': 'test_value_3',
'comments': 'test_value_4',
'ip-based': 'enable',
'name': 'default_name_6',
'protocol': 'http',
'sso-auth-method': 'test_value_8',
'status': 'enable',
'transaction-based': 'enable',
'web-auth-cookie': 'enable'
}
set_method_mock.assert_called_with('authentication', 'rule', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_authentication_rule_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'authentication_rule': {
'random_attribute_not_valid': 'tag',
'active_auth_method': 'test_value_3',
'comments': 'test_value_4',
'ip_based': 'enable',
'name': 'default_name_6',
'protocol': 'http',
'sso_auth_method': 'test_value_8',
'status': 'enable',
'transaction_based': 'enable',
'web_auth_cookie': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_authentication_rule.fortios_authentication(input_data, fos_instance)
expected_data = {
'active-auth-method': 'test_value_3',
'comments': 'test_value_4',
'ip-based': 'enable',
'name': 'default_name_6',
'protocol': 'http',
'sso-auth-method': 'test_value_8',
'status': 'enable',
'transaction-based': 'enable',
'web-auth-cookie': 'enable'
}
set_method_mock.assert_called_with('authentication', 'rule', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,289 @@
# 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 Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_authentication_scheme
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_authentication_scheme.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_authentication_scheme_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'authentication_scheme': {
'domain_controller': 'test_value_3',
'fsso_agent_for_ntlm': 'test_value_4',
'fsso_guest': 'enable',
'kerberos_keytab': 'test_value_6',
'method': 'ntlm',
'name': 'default_name_8',
'negotiate_ntlm': 'enable',
'require_tfa': 'enable',
'ssh_ca': 'test_value_11',
},
'vdom': 'root'}
is_error, changed, response = fortios_authentication_scheme.fortios_authentication(input_data, fos_instance)
expected_data = {
'domain-controller': 'test_value_3',
'fsso-agent-for-ntlm': 'test_value_4',
'fsso-guest': 'enable',
'kerberos-keytab': 'test_value_6',
'method': 'ntlm',
'name': 'default_name_8',
'negotiate-ntlm': 'enable',
'require-tfa': 'enable',
'ssh-ca': 'test_value_11',
}
set_method_mock.assert_called_with('authentication', 'scheme', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_authentication_scheme_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'authentication_scheme': {
'domain_controller': 'test_value_3',
'fsso_agent_for_ntlm': 'test_value_4',
'fsso_guest': 'enable',
'kerberos_keytab': 'test_value_6',
'method': 'ntlm',
'name': 'default_name_8',
'negotiate_ntlm': 'enable',
'require_tfa': 'enable',
'ssh_ca': 'test_value_11',
},
'vdom': 'root'}
is_error, changed, response = fortios_authentication_scheme.fortios_authentication(input_data, fos_instance)
expected_data = {
'domain-controller': 'test_value_3',
'fsso-agent-for-ntlm': 'test_value_4',
'fsso-guest': 'enable',
'kerberos-keytab': 'test_value_6',
'method': 'ntlm',
'name': 'default_name_8',
'negotiate-ntlm': 'enable',
'require-tfa': 'enable',
'ssh-ca': 'test_value_11',
}
set_method_mock.assert_called_with('authentication', 'scheme', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_authentication_scheme_removal(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'authentication_scheme': {
'domain_controller': 'test_value_3',
'fsso_agent_for_ntlm': 'test_value_4',
'fsso_guest': 'enable',
'kerberos_keytab': 'test_value_6',
'method': 'ntlm',
'name': 'default_name_8',
'negotiate_ntlm': 'enable',
'require_tfa': 'enable',
'ssh_ca': 'test_value_11',
},
'vdom': 'root'}
is_error, changed, response = fortios_authentication_scheme.fortios_authentication(input_data, fos_instance)
delete_method_mock.assert_called_with('authentication', 'scheme', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_authentication_scheme_deletion_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'authentication_scheme': {
'domain_controller': 'test_value_3',
'fsso_agent_for_ntlm': 'test_value_4',
'fsso_guest': 'enable',
'kerberos_keytab': 'test_value_6',
'method': 'ntlm',
'name': 'default_name_8',
'negotiate_ntlm': 'enable',
'require_tfa': 'enable',
'ssh_ca': 'test_value_11',
},
'vdom': 'root'}
is_error, changed, response = fortios_authentication_scheme.fortios_authentication(input_data, fos_instance)
delete_method_mock.assert_called_with('authentication', 'scheme', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_authentication_scheme_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'authentication_scheme': {
'domain_controller': 'test_value_3',
'fsso_agent_for_ntlm': 'test_value_4',
'fsso_guest': 'enable',
'kerberos_keytab': 'test_value_6',
'method': 'ntlm',
'name': 'default_name_8',
'negotiate_ntlm': 'enable',
'require_tfa': 'enable',
'ssh_ca': 'test_value_11',
},
'vdom': 'root'}
is_error, changed, response = fortios_authentication_scheme.fortios_authentication(input_data, fos_instance)
expected_data = {
'domain-controller': 'test_value_3',
'fsso-agent-for-ntlm': 'test_value_4',
'fsso-guest': 'enable',
'kerberos-keytab': 'test_value_6',
'method': 'ntlm',
'name': 'default_name_8',
'negotiate-ntlm': 'enable',
'require-tfa': 'enable',
'ssh-ca': 'test_value_11',
}
set_method_mock.assert_called_with('authentication', 'scheme', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_authentication_scheme_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'authentication_scheme': {
'random_attribute_not_valid': 'tag',
'domain_controller': 'test_value_3',
'fsso_agent_for_ntlm': 'test_value_4',
'fsso_guest': 'enable',
'kerberos_keytab': 'test_value_6',
'method': 'ntlm',
'name': 'default_name_8',
'negotiate_ntlm': 'enable',
'require_tfa': 'enable',
'ssh_ca': 'test_value_11',
},
'vdom': 'root'}
is_error, changed, response = fortios_authentication_scheme.fortios_authentication(input_data, fos_instance)
expected_data = {
'domain-controller': 'test_value_3',
'fsso-agent-for-ntlm': 'test_value_4',
'fsso-guest': 'enable',
'kerberos-keytab': 'test_value_6',
'method': 'ntlm',
'name': 'default_name_8',
'negotiate-ntlm': 'enable',
'require-tfa': 'enable',
'ssh-ca': 'test_value_11',
}
set_method_mock.assert_called_with('authentication', 'scheme', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,207 @@
# 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 Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_authentication_setting
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_authentication_setting.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_authentication_setting_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'authentication_setting': {
'active_auth_scheme': 'test_value_3',
'captive_portal': 'test_value_4',
'captive_portal_ip': 'test_value_5',
'captive_portal_ip6': 'test_value_6',
'captive_portal_port': '7',
'captive_portal_type': 'fqdn',
'captive_portal6': 'test_value_9',
'sso_auth_scheme': 'test_value_10'
},
'vdom': 'root'}
is_error, changed, response = fortios_authentication_setting.fortios_authentication(input_data, fos_instance)
expected_data = {
'active-auth-scheme': 'test_value_3',
'captive-portal': 'test_value_4',
'captive-portal-ip': 'test_value_5',
'captive-portal-ip6': 'test_value_6',
'captive-portal-port': '7',
'captive-portal-type': 'fqdn',
'captive-portal6': 'test_value_9',
'sso-auth-scheme': 'test_value_10'
}
set_method_mock.assert_called_with('authentication', 'setting', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_authentication_setting_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'authentication_setting': {
'active_auth_scheme': 'test_value_3',
'captive_portal': 'test_value_4',
'captive_portal_ip': 'test_value_5',
'captive_portal_ip6': 'test_value_6',
'captive_portal_port': '7',
'captive_portal_type': 'fqdn',
'captive_portal6': 'test_value_9',
'sso_auth_scheme': 'test_value_10'
},
'vdom': 'root'}
is_error, changed, response = fortios_authentication_setting.fortios_authentication(input_data, fos_instance)
expected_data = {
'active-auth-scheme': 'test_value_3',
'captive-portal': 'test_value_4',
'captive-portal-ip': 'test_value_5',
'captive-portal-ip6': 'test_value_6',
'captive-portal-port': '7',
'captive-portal-type': 'fqdn',
'captive-portal6': 'test_value_9',
'sso-auth-scheme': 'test_value_10'
}
set_method_mock.assert_called_with('authentication', 'setting', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_authentication_setting_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'authentication_setting': {
'active_auth_scheme': 'test_value_3',
'captive_portal': 'test_value_4',
'captive_portal_ip': 'test_value_5',
'captive_portal_ip6': 'test_value_6',
'captive_portal_port': '7',
'captive_portal_type': 'fqdn',
'captive_portal6': 'test_value_9',
'sso_auth_scheme': 'test_value_10'
},
'vdom': 'root'}
is_error, changed, response = fortios_authentication_setting.fortios_authentication(input_data, fos_instance)
expected_data = {
'active-auth-scheme': 'test_value_3',
'captive-portal': 'test_value_4',
'captive-portal-ip': 'test_value_5',
'captive-portal-ip6': 'test_value_6',
'captive-portal-port': '7',
'captive-portal-type': 'fqdn',
'captive-portal6': 'test_value_9',
'sso-auth-scheme': 'test_value_10'
}
set_method_mock.assert_called_with('authentication', 'setting', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_authentication_setting_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'authentication_setting': {
'random_attribute_not_valid': 'tag',
'active_auth_scheme': 'test_value_3',
'captive_portal': 'test_value_4',
'captive_portal_ip': 'test_value_5',
'captive_portal_ip6': 'test_value_6',
'captive_portal_port': '7',
'captive_portal_type': 'fqdn',
'captive_portal6': 'test_value_9',
'sso_auth_scheme': 'test_value_10'
},
'vdom': 'root'}
is_error, changed, response = fortios_authentication_setting.fortios_authentication(input_data, fos_instance)
expected_data = {
'active-auth-scheme': 'test_value_3',
'captive-portal': 'test_value_4',
'captive-portal-ip': 'test_value_5',
'captive-portal-ip6': 'test_value_6',
'captive-portal-port': '7',
'captive-portal-type': 'fqdn',
'captive-portal6': 'test_value_9',
'sso-auth-scheme': 'test_value_10'
}
set_method_mock.assert_called_with('authentication', 'setting', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,219 @@
# 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 Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_dlp_filepattern
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_dlp_filepattern.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_dlp_filepattern_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'dlp_filepattern': {
'comment': 'Optional comments.',
'id': '4',
'name': 'default_name_5'
},
'vdom': 'root'}
is_error, changed, response = fortios_dlp_filepattern.fortios_dlp(input_data, fos_instance)
expected_data = {
'comment': 'Optional comments.',
'id': '4',
'name': 'default_name_5'
}
set_method_mock.assert_called_with('dlp', 'filepattern', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_dlp_filepattern_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'dlp_filepattern': {
'comment': 'Optional comments.',
'id': '4',
'name': 'default_name_5'
},
'vdom': 'root'}
is_error, changed, response = fortios_dlp_filepattern.fortios_dlp(input_data, fos_instance)
expected_data = {
'comment': 'Optional comments.',
'id': '4',
'name': 'default_name_5'
}
set_method_mock.assert_called_with('dlp', 'filepattern', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_dlp_filepattern_removal(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'dlp_filepattern': {
'comment': 'Optional comments.',
'id': '4',
'name': 'default_name_5'
},
'vdom': 'root'}
is_error, changed, response = fortios_dlp_filepattern.fortios_dlp(input_data, fos_instance)
delete_method_mock.assert_called_with('dlp', 'filepattern', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_dlp_filepattern_deletion_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'dlp_filepattern': {
'comment': 'Optional comments.',
'id': '4',
'name': 'default_name_5'
},
'vdom': 'root'}
is_error, changed, response = fortios_dlp_filepattern.fortios_dlp(input_data, fos_instance)
delete_method_mock.assert_called_with('dlp', 'filepattern', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_dlp_filepattern_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'dlp_filepattern': {
'comment': 'Optional comments.',
'id': '4',
'name': 'default_name_5'
},
'vdom': 'root'}
is_error, changed, response = fortios_dlp_filepattern.fortios_dlp(input_data, fos_instance)
expected_data = {
'comment': 'Optional comments.',
'id': '4',
'name': 'default_name_5'
}
set_method_mock.assert_called_with('dlp', 'filepattern', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_dlp_filepattern_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'dlp_filepattern': {
'random_attribute_not_valid': 'tag',
'comment': 'Optional comments.',
'id': '4',
'name': 'default_name_5'
},
'vdom': 'root'}
is_error, changed, response = fortios_dlp_filepattern.fortios_dlp(input_data, fos_instance)
expected_data = {
'comment': 'Optional comments.',
'id': '4',
'name': 'default_name_5'
}
set_method_mock.assert_called_with('dlp', 'filepattern', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,369 @@
# 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 Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_dlp_fp_doc_source
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_dlp_fp_doc_source.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_dlp_fp_doc_source_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'dlp_fp_doc_source': {
'date': '3',
'file_path': 'test_value_4',
'file_pattern': 'test_value_5',
'keep_modified': 'enable',
'name': 'default_name_7',
'password': 'test_value_8',
'period': 'none',
'remove_deleted': 'enable',
'scan_on_creation': 'enable',
'scan_subdirectories': 'enable',
'sensitivity': 'test_value_13',
'server': '192.168.100.14',
'server_type': 'samba',
'tod_hour': '16',
'tod_min': '17',
'username': 'test_value_18',
'vdom': 'mgmt',
'weekday': 'sunday'
},
'vdom': 'root'}
is_error, changed, response = fortios_dlp_fp_doc_source.fortios_dlp(input_data, fos_instance)
expected_data = {
'date': '3',
'file-path': 'test_value_4',
'file-pattern': 'test_value_5',
'keep-modified': 'enable',
'name': 'default_name_7',
'password': 'test_value_8',
'period': 'none',
'remove-deleted': 'enable',
'scan-on-creation': 'enable',
'scan-subdirectories': 'enable',
'sensitivity': 'test_value_13',
'server': '192.168.100.14',
'server-type': 'samba',
'tod-hour': '16',
'tod-min': '17',
'username': 'test_value_18',
'vdom': 'mgmt',
'weekday': 'sunday'
}
set_method_mock.assert_called_with('dlp', 'fp-doc-source', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_dlp_fp_doc_source_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'dlp_fp_doc_source': {
'date': '3',
'file_path': 'test_value_4',
'file_pattern': 'test_value_5',
'keep_modified': 'enable',
'name': 'default_name_7',
'password': 'test_value_8',
'period': 'none',
'remove_deleted': 'enable',
'scan_on_creation': 'enable',
'scan_subdirectories': 'enable',
'sensitivity': 'test_value_13',
'server': '192.168.100.14',
'server_type': 'samba',
'tod_hour': '16',
'tod_min': '17',
'username': 'test_value_18',
'vdom': 'mgmt',
'weekday': 'sunday'
},
'vdom': 'root'}
is_error, changed, response = fortios_dlp_fp_doc_source.fortios_dlp(input_data, fos_instance)
expected_data = {
'date': '3',
'file-path': 'test_value_4',
'file-pattern': 'test_value_5',
'keep-modified': 'enable',
'name': 'default_name_7',
'password': 'test_value_8',
'period': 'none',
'remove-deleted': 'enable',
'scan-on-creation': 'enable',
'scan-subdirectories': 'enable',
'sensitivity': 'test_value_13',
'server': '192.168.100.14',
'server-type': 'samba',
'tod-hour': '16',
'tod-min': '17',
'username': 'test_value_18',
'vdom': 'mgmt',
'weekday': 'sunday'
}
set_method_mock.assert_called_with('dlp', 'fp-doc-source', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_dlp_fp_doc_source_removal(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'dlp_fp_doc_source': {
'date': '3',
'file_path': 'test_value_4',
'file_pattern': 'test_value_5',
'keep_modified': 'enable',
'name': 'default_name_7',
'password': 'test_value_8',
'period': 'none',
'remove_deleted': 'enable',
'scan_on_creation': 'enable',
'scan_subdirectories': 'enable',
'sensitivity': 'test_value_13',
'server': '192.168.100.14',
'server_type': 'samba',
'tod_hour': '16',
'tod_min': '17',
'username': 'test_value_18',
'vdom': 'mgmt',
'weekday': 'sunday'
},
'vdom': 'root'}
is_error, changed, response = fortios_dlp_fp_doc_source.fortios_dlp(input_data, fos_instance)
delete_method_mock.assert_called_with('dlp', 'fp-doc-source', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_dlp_fp_doc_source_deletion_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'dlp_fp_doc_source': {
'date': '3',
'file_path': 'test_value_4',
'file_pattern': 'test_value_5',
'keep_modified': 'enable',
'name': 'default_name_7',
'password': 'test_value_8',
'period': 'none',
'remove_deleted': 'enable',
'scan_on_creation': 'enable',
'scan_subdirectories': 'enable',
'sensitivity': 'test_value_13',
'server': '192.168.100.14',
'server_type': 'samba',
'tod_hour': '16',
'tod_min': '17',
'username': 'test_value_18',
'vdom': 'mgmt',
'weekday': 'sunday'
},
'vdom': 'root'}
is_error, changed, response = fortios_dlp_fp_doc_source.fortios_dlp(input_data, fos_instance)
delete_method_mock.assert_called_with('dlp', 'fp-doc-source', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_dlp_fp_doc_source_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'dlp_fp_doc_source': {
'date': '3',
'file_path': 'test_value_4',
'file_pattern': 'test_value_5',
'keep_modified': 'enable',
'name': 'default_name_7',
'password': 'test_value_8',
'period': 'none',
'remove_deleted': 'enable',
'scan_on_creation': 'enable',
'scan_subdirectories': 'enable',
'sensitivity': 'test_value_13',
'server': '192.168.100.14',
'server_type': 'samba',
'tod_hour': '16',
'tod_min': '17',
'username': 'test_value_18',
'vdom': 'mgmt',
'weekday': 'sunday'
},
'vdom': 'root'}
is_error, changed, response = fortios_dlp_fp_doc_source.fortios_dlp(input_data, fos_instance)
expected_data = {
'date': '3',
'file-path': 'test_value_4',
'file-pattern': 'test_value_5',
'keep-modified': 'enable',
'name': 'default_name_7',
'password': 'test_value_8',
'period': 'none',
'remove-deleted': 'enable',
'scan-on-creation': 'enable',
'scan-subdirectories': 'enable',
'sensitivity': 'test_value_13',
'server': '192.168.100.14',
'server-type': 'samba',
'tod-hour': '16',
'tod-min': '17',
'username': 'test_value_18',
'vdom': 'mgmt',
'weekday': 'sunday'
}
set_method_mock.assert_called_with('dlp', 'fp-doc-source', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_dlp_fp_doc_source_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'dlp_fp_doc_source': {
'random_attribute_not_valid': 'tag',
'date': '3',
'file_path': 'test_value_4',
'file_pattern': 'test_value_5',
'keep_modified': 'enable',
'name': 'default_name_7',
'password': 'test_value_8',
'period': 'none',
'remove_deleted': 'enable',
'scan_on_creation': 'enable',
'scan_subdirectories': 'enable',
'sensitivity': 'test_value_13',
'server': '192.168.100.14',
'server_type': 'samba',
'tod_hour': '16',
'tod_min': '17',
'username': 'test_value_18',
'vdom': 'mgmt',
'weekday': 'sunday'
},
'vdom': 'root'}
is_error, changed, response = fortios_dlp_fp_doc_source.fortios_dlp(input_data, fos_instance)
expected_data = {
'date': '3',
'file-path': 'test_value_4',
'file-pattern': 'test_value_5',
'keep-modified': 'enable',
'name': 'default_name_7',
'password': 'test_value_8',
'period': 'none',
'remove-deleted': 'enable',
'scan-on-creation': 'enable',
'scan-subdirectories': 'enable',
'sensitivity': 'test_value_13',
'server': '192.168.100.14',
'server-type': 'samba',
'tod-hour': '16',
'tod-min': '17',
'username': 'test_value_18',
'vdom': 'mgmt',
'weekday': 'sunday'
}
set_method_mock.assert_called_with('dlp', 'fp-doc-source', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,199 @@
# 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 Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_dlp_fp_sensitivity
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_dlp_fp_sensitivity.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_dlp_fp_sensitivity_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'dlp_fp_sensitivity': {
'name': 'default_name_3'
},
'vdom': 'root'}
is_error, changed, response = fortios_dlp_fp_sensitivity.fortios_dlp(input_data, fos_instance)
expected_data = {
'name': 'default_name_3'
}
set_method_mock.assert_called_with('dlp', 'fp-sensitivity', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_dlp_fp_sensitivity_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'dlp_fp_sensitivity': {
'name': 'default_name_3'
},
'vdom': 'root'}
is_error, changed, response = fortios_dlp_fp_sensitivity.fortios_dlp(input_data, fos_instance)
expected_data = {
'name': 'default_name_3'
}
set_method_mock.assert_called_with('dlp', 'fp-sensitivity', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_dlp_fp_sensitivity_removal(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'dlp_fp_sensitivity': {
'name': 'default_name_3'
},
'vdom': 'root'}
is_error, changed, response = fortios_dlp_fp_sensitivity.fortios_dlp(input_data, fos_instance)
delete_method_mock.assert_called_with('dlp', 'fp-sensitivity', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_dlp_fp_sensitivity_deletion_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'dlp_fp_sensitivity': {
'name': 'default_name_3'
},
'vdom': 'root'}
is_error, changed, response = fortios_dlp_fp_sensitivity.fortios_dlp(input_data, fos_instance)
delete_method_mock.assert_called_with('dlp', 'fp-sensitivity', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_dlp_fp_sensitivity_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'dlp_fp_sensitivity': {
'name': 'default_name_3'
},
'vdom': 'root'}
is_error, changed, response = fortios_dlp_fp_sensitivity.fortios_dlp(input_data, fos_instance)
expected_data = {
'name': 'default_name_3'
}
set_method_mock.assert_called_with('dlp', 'fp-sensitivity', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_dlp_fp_sensitivity_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'dlp_fp_sensitivity': {
'random_attribute_not_valid': 'tag',
'name': 'default_name_3'
},
'vdom': 'root'}
is_error, changed, response = fortios_dlp_fp_sensitivity.fortios_dlp(input_data, fos_instance)
expected_data = {
'name': 'default_name_3'
}
set_method_mock.assert_called_with('dlp', 'fp-sensitivity', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,289 @@
# 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 Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_dlp_sensor
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_dlp_sensor.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_dlp_sensor_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'dlp_sensor': {
'comment': 'Comment.',
'dlp_log': 'enable',
'extended_log': 'enable',
'flow_based': 'enable',
'full_archive_proto': 'smtp',
'nac_quar_log': 'enable',
'name': 'default_name_9',
'options': 'test_value_10,',
'replacemsg_group': 'test_value_11',
'summary_proto': 'smtp'
},
'vdom': 'root'}
is_error, changed, response = fortios_dlp_sensor.fortios_dlp(input_data, fos_instance)
expected_data = {
'comment': 'Comment.',
'dlp-log': 'enable',
'extended-log': 'enable',
'flow-based': 'enable',
'full-archive-proto': 'smtp',
'nac-quar-log': 'enable',
'name': 'default_name_9',
'options': 'test_value_10,',
'replacemsg-group': 'test_value_11',
'summary-proto': 'smtp'
}
set_method_mock.assert_called_with('dlp', 'sensor', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_dlp_sensor_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'dlp_sensor': {
'comment': 'Comment.',
'dlp_log': 'enable',
'extended_log': 'enable',
'flow_based': 'enable',
'full_archive_proto': 'smtp',
'nac_quar_log': 'enable',
'name': 'default_name_9',
'options': 'test_value_10,',
'replacemsg_group': 'test_value_11',
'summary_proto': 'smtp'
},
'vdom': 'root'}
is_error, changed, response = fortios_dlp_sensor.fortios_dlp(input_data, fos_instance)
expected_data = {
'comment': 'Comment.',
'dlp-log': 'enable',
'extended-log': 'enable',
'flow-based': 'enable',
'full-archive-proto': 'smtp',
'nac-quar-log': 'enable',
'name': 'default_name_9',
'options': 'test_value_10,',
'replacemsg-group': 'test_value_11',
'summary-proto': 'smtp'
}
set_method_mock.assert_called_with('dlp', 'sensor', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_dlp_sensor_removal(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'dlp_sensor': {
'comment': 'Comment.',
'dlp_log': 'enable',
'extended_log': 'enable',
'flow_based': 'enable',
'full_archive_proto': 'smtp',
'nac_quar_log': 'enable',
'name': 'default_name_9',
'options': 'test_value_10,',
'replacemsg_group': 'test_value_11',
'summary_proto': 'smtp'
},
'vdom': 'root'}
is_error, changed, response = fortios_dlp_sensor.fortios_dlp(input_data, fos_instance)
delete_method_mock.assert_called_with('dlp', 'sensor', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_dlp_sensor_deletion_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'dlp_sensor': {
'comment': 'Comment.',
'dlp_log': 'enable',
'extended_log': 'enable',
'flow_based': 'enable',
'full_archive_proto': 'smtp',
'nac_quar_log': 'enable',
'name': 'default_name_9',
'options': 'test_value_10,',
'replacemsg_group': 'test_value_11',
'summary_proto': 'smtp'
},
'vdom': 'root'}
is_error, changed, response = fortios_dlp_sensor.fortios_dlp(input_data, fos_instance)
delete_method_mock.assert_called_with('dlp', 'sensor', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_dlp_sensor_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'dlp_sensor': {
'comment': 'Comment.',
'dlp_log': 'enable',
'extended_log': 'enable',
'flow_based': 'enable',
'full_archive_proto': 'smtp',
'nac_quar_log': 'enable',
'name': 'default_name_9',
'options': 'test_value_10,',
'replacemsg_group': 'test_value_11',
'summary_proto': 'smtp'
},
'vdom': 'root'}
is_error, changed, response = fortios_dlp_sensor.fortios_dlp(input_data, fos_instance)
expected_data = {
'comment': 'Comment.',
'dlp-log': 'enable',
'extended-log': 'enable',
'flow-based': 'enable',
'full-archive-proto': 'smtp',
'nac-quar-log': 'enable',
'name': 'default_name_9',
'options': 'test_value_10,',
'replacemsg-group': 'test_value_11',
'summary-proto': 'smtp'
}
set_method_mock.assert_called_with('dlp', 'sensor', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_dlp_sensor_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'dlp_sensor': {
'random_attribute_not_valid': 'tag',
'comment': 'Comment.',
'dlp_log': 'enable',
'extended_log': 'enable',
'flow_based': 'enable',
'full_archive_proto': 'smtp',
'nac_quar_log': 'enable',
'name': 'default_name_9',
'options': 'test_value_10,',
'replacemsg_group': 'test_value_11',
'summary_proto': 'smtp'
},
'vdom': 'root'}
is_error, changed, response = fortios_dlp_sensor.fortios_dlp(input_data, fos_instance)
expected_data = {
'comment': 'Comment.',
'dlp-log': 'enable',
'extended-log': 'enable',
'flow-based': 'enable',
'full-archive-proto': 'smtp',
'nac-quar-log': 'enable',
'name': 'default_name_9',
'options': 'test_value_10,',
'replacemsg-group': 'test_value_11',
'summary-proto': 'smtp'
}
set_method_mock.assert_called_with('dlp', 'sensor', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,183 @@
# 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 Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_dlp_settings
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_dlp_settings.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_dlp_settings_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'dlp_settings': {
'cache_mem_percent': '3',
'chunk_size': '4',
'db_mode': 'stop-adding',
'size': '6',
'storage_device': 'test_value_7'
},
'vdom': 'root'}
is_error, changed, response = fortios_dlp_settings.fortios_dlp(input_data, fos_instance)
expected_data = {
'cache-mem-percent': '3',
'chunk-size': '4',
'db-mode': 'stop-adding',
'size': '6',
'storage-device': 'test_value_7'
}
set_method_mock.assert_called_with('dlp', 'settings', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_dlp_settings_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'dlp_settings': {
'cache_mem_percent': '3',
'chunk_size': '4',
'db_mode': 'stop-adding',
'size': '6',
'storage_device': 'test_value_7'
},
'vdom': 'root'}
is_error, changed, response = fortios_dlp_settings.fortios_dlp(input_data, fos_instance)
expected_data = {
'cache-mem-percent': '3',
'chunk-size': '4',
'db-mode': 'stop-adding',
'size': '6',
'storage-device': 'test_value_7'
}
set_method_mock.assert_called_with('dlp', 'settings', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_dlp_settings_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'dlp_settings': {
'cache_mem_percent': '3',
'chunk_size': '4',
'db_mode': 'stop-adding',
'size': '6',
'storage_device': 'test_value_7'
},
'vdom': 'root'}
is_error, changed, response = fortios_dlp_settings.fortios_dlp(input_data, fos_instance)
expected_data = {
'cache-mem-percent': '3',
'chunk-size': '4',
'db-mode': 'stop-adding',
'size': '6',
'storage-device': 'test_value_7'
}
set_method_mock.assert_called_with('dlp', 'settings', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_dlp_settings_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'dlp_settings': {
'random_attribute_not_valid': 'tag',
'cache_mem_percent': '3',
'chunk_size': '4',
'db_mode': 'stop-adding',
'size': '6',
'storage_device': 'test_value_7'
},
'vdom': 'root'}
is_error, changed, response = fortios_dlp_settings.fortios_dlp(input_data, fos_instance)
expected_data = {
'cache-mem-percent': '3',
'chunk-size': '4',
'db-mode': 'stop-adding',
'size': '6',
'storage-device': 'test_value_7'
}
set_method_mock.assert_called_with('dlp', 'settings', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,219 @@
# 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 Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_dnsfilter_domain_filter
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_dnsfilter_domain_filter.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_dnsfilter_domain_filter_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'dnsfilter_domain_filter': {
'comment': 'Optional comments.',
'id': '4',
'name': 'default_name_5'
},
'vdom': 'root'}
is_error, changed, response = fortios_dnsfilter_domain_filter.fortios_dnsfilter(input_data, fos_instance)
expected_data = {
'comment': 'Optional comments.',
'id': '4',
'name': 'default_name_5'
}
set_method_mock.assert_called_with('dnsfilter', 'domain-filter', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_dnsfilter_domain_filter_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'dnsfilter_domain_filter': {
'comment': 'Optional comments.',
'id': '4',
'name': 'default_name_5'
},
'vdom': 'root'}
is_error, changed, response = fortios_dnsfilter_domain_filter.fortios_dnsfilter(input_data, fos_instance)
expected_data = {
'comment': 'Optional comments.',
'id': '4',
'name': 'default_name_5'
}
set_method_mock.assert_called_with('dnsfilter', 'domain-filter', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_dnsfilter_domain_filter_removal(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'dnsfilter_domain_filter': {
'comment': 'Optional comments.',
'id': '4',
'name': 'default_name_5'
},
'vdom': 'root'}
is_error, changed, response = fortios_dnsfilter_domain_filter.fortios_dnsfilter(input_data, fos_instance)
delete_method_mock.assert_called_with('dnsfilter', 'domain-filter', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_dnsfilter_domain_filter_deletion_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'dnsfilter_domain_filter': {
'comment': 'Optional comments.',
'id': '4',
'name': 'default_name_5'
},
'vdom': 'root'}
is_error, changed, response = fortios_dnsfilter_domain_filter.fortios_dnsfilter(input_data, fos_instance)
delete_method_mock.assert_called_with('dnsfilter', 'domain-filter', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_dnsfilter_domain_filter_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'dnsfilter_domain_filter': {
'comment': 'Optional comments.',
'id': '4',
'name': 'default_name_5'
},
'vdom': 'root'}
is_error, changed, response = fortios_dnsfilter_domain_filter.fortios_dnsfilter(input_data, fos_instance)
expected_data = {
'comment': 'Optional comments.',
'id': '4',
'name': 'default_name_5'
}
set_method_mock.assert_called_with('dnsfilter', 'domain-filter', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_dnsfilter_domain_filter_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'dnsfilter_domain_filter': {
'random_attribute_not_valid': 'tag',
'comment': 'Optional comments.',
'id': '4',
'name': 'default_name_5'
},
'vdom': 'root'}
is_error, changed, response = fortios_dnsfilter_domain_filter.fortios_dnsfilter(input_data, fos_instance)
expected_data = {
'comment': 'Optional comments.',
'id': '4',
'name': 'default_name_5'
}
set_method_mock.assert_called_with('dnsfilter', 'domain-filter', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,289 @@
# 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 Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_dnsfilter_profile
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_dnsfilter_profile.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_dnsfilter_profile_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'dnsfilter_profile': {
'block_action': 'block',
'block_botnet': 'disable',
'comment': 'Comment.',
'log_all_domain': 'enable',
'name': 'default_name_7',
'redirect_portal': 'test_value_8',
'safe_search': 'disable',
'sdns_domain_log': 'enable',
'sdns_ftgd_err_log': 'enable',
'youtube_restrict': 'strict'
},
'vdom': 'root'}
is_error, changed, response = fortios_dnsfilter_profile.fortios_dnsfilter(input_data, fos_instance)
expected_data = {
'block-action': 'block',
'block-botnet': 'disable',
'comment': 'Comment.',
'log-all-domain': 'enable',
'name': 'default_name_7',
'redirect-portal': 'test_value_8',
'safe-search': 'disable',
'sdns-domain-log': 'enable',
'sdns-ftgd-err-log': 'enable',
'youtube-restrict': 'strict'
}
set_method_mock.assert_called_with('dnsfilter', 'profile', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_dnsfilter_profile_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'dnsfilter_profile': {
'block_action': 'block',
'block_botnet': 'disable',
'comment': 'Comment.',
'log_all_domain': 'enable',
'name': 'default_name_7',
'redirect_portal': 'test_value_8',
'safe_search': 'disable',
'sdns_domain_log': 'enable',
'sdns_ftgd_err_log': 'enable',
'youtube_restrict': 'strict'
},
'vdom': 'root'}
is_error, changed, response = fortios_dnsfilter_profile.fortios_dnsfilter(input_data, fos_instance)
expected_data = {
'block-action': 'block',
'block-botnet': 'disable',
'comment': 'Comment.',
'log-all-domain': 'enable',
'name': 'default_name_7',
'redirect-portal': 'test_value_8',
'safe-search': 'disable',
'sdns-domain-log': 'enable',
'sdns-ftgd-err-log': 'enable',
'youtube-restrict': 'strict'
}
set_method_mock.assert_called_with('dnsfilter', 'profile', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_dnsfilter_profile_removal(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'dnsfilter_profile': {
'block_action': 'block',
'block_botnet': 'disable',
'comment': 'Comment.',
'log_all_domain': 'enable',
'name': 'default_name_7',
'redirect_portal': 'test_value_8',
'safe_search': 'disable',
'sdns_domain_log': 'enable',
'sdns_ftgd_err_log': 'enable',
'youtube_restrict': 'strict'
},
'vdom': 'root'}
is_error, changed, response = fortios_dnsfilter_profile.fortios_dnsfilter(input_data, fos_instance)
delete_method_mock.assert_called_with('dnsfilter', 'profile', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_dnsfilter_profile_deletion_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'dnsfilter_profile': {
'block_action': 'block',
'block_botnet': 'disable',
'comment': 'Comment.',
'log_all_domain': 'enable',
'name': 'default_name_7',
'redirect_portal': 'test_value_8',
'safe_search': 'disable',
'sdns_domain_log': 'enable',
'sdns_ftgd_err_log': 'enable',
'youtube_restrict': 'strict'
},
'vdom': 'root'}
is_error, changed, response = fortios_dnsfilter_profile.fortios_dnsfilter(input_data, fos_instance)
delete_method_mock.assert_called_with('dnsfilter', 'profile', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_dnsfilter_profile_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'dnsfilter_profile': {
'block_action': 'block',
'block_botnet': 'disable',
'comment': 'Comment.',
'log_all_domain': 'enable',
'name': 'default_name_7',
'redirect_portal': 'test_value_8',
'safe_search': 'disable',
'sdns_domain_log': 'enable',
'sdns_ftgd_err_log': 'enable',
'youtube_restrict': 'strict'
},
'vdom': 'root'}
is_error, changed, response = fortios_dnsfilter_profile.fortios_dnsfilter(input_data, fos_instance)
expected_data = {
'block-action': 'block',
'block-botnet': 'disable',
'comment': 'Comment.',
'log-all-domain': 'enable',
'name': 'default_name_7',
'redirect-portal': 'test_value_8',
'safe-search': 'disable',
'sdns-domain-log': 'enable',
'sdns-ftgd-err-log': 'enable',
'youtube-restrict': 'strict'
}
set_method_mock.assert_called_with('dnsfilter', 'profile', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_dnsfilter_profile_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'dnsfilter_profile': {
'random_attribute_not_valid': 'tag',
'block_action': 'block',
'block_botnet': 'disable',
'comment': 'Comment.',
'log_all_domain': 'enable',
'name': 'default_name_7',
'redirect_portal': 'test_value_8',
'safe_search': 'disable',
'sdns_domain_log': 'enable',
'sdns_ftgd_err_log': 'enable',
'youtube_restrict': 'strict'
},
'vdom': 'root'}
is_error, changed, response = fortios_dnsfilter_profile.fortios_dnsfilter(input_data, fos_instance)
expected_data = {
'block-action': 'block',
'block-botnet': 'disable',
'comment': 'Comment.',
'log-all-domain': 'enable',
'name': 'default_name_7',
'redirect-portal': 'test_value_8',
'safe-search': 'disable',
'sdns-domain-log': 'enable',
'sdns-ftgd-err-log': 'enable',
'youtube-restrict': 'strict'
}
set_method_mock.assert_called_with('dnsfilter', 'profile', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200

@ -0,0 +1,249 @@
# 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 Ansible. If not, see <https://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import json
import pytest
from mock import ANY
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
try:
from ansible.modules.network.fortios import fortios_endpoint_control_client
except ImportError:
pytest.skip("Could not load required modules for testing", allow_module_level=True)
@pytest.fixture(autouse=True)
def connection_mock(mocker):
connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_endpoint_control_client.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_endpoint_control_client_creation(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'endpoint_control_client': {
'ad_groups': 'test_value_3',
'ftcl_uid': 'test_value_4',
'id': '5',
'info': 'test_value_6',
'src_ip': 'test_value_7',
'src_mac': 'test_value_8'
},
'vdom': 'root'}
is_error, changed, response = fortios_endpoint_control_client.fortios_endpoint_control(input_data, fos_instance)
expected_data = {
'ad-groups': 'test_value_3',
'ftcl-uid': 'test_value_4',
'id': '5',
'info': 'test_value_6',
'src-ip': 'test_value_7',
'src-mac': 'test_value_8'
}
set_method_mock.assert_called_with('endpoint-control', 'client', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_endpoint_control_client_creation_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'endpoint_control_client': {
'ad_groups': 'test_value_3',
'ftcl_uid': 'test_value_4',
'id': '5',
'info': 'test_value_6',
'src_ip': 'test_value_7',
'src_mac': 'test_value_8'
},
'vdom': 'root'}
is_error, changed, response = fortios_endpoint_control_client.fortios_endpoint_control(input_data, fos_instance)
expected_data = {
'ad-groups': 'test_value_3',
'ftcl-uid': 'test_value_4',
'id': '5',
'info': 'test_value_6',
'src-ip': 'test_value_7',
'src-mac': 'test_value_8'
}
set_method_mock.assert_called_with('endpoint-control', 'client', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_endpoint_control_client_removal(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'endpoint_control_client': {
'ad_groups': 'test_value_3',
'ftcl_uid': 'test_value_4',
'id': '5',
'info': 'test_value_6',
'src_ip': 'test_value_7',
'src_mac': 'test_value_8'
},
'vdom': 'root'}
is_error, changed, response = fortios_endpoint_control_client.fortios_endpoint_control(input_data, fos_instance)
delete_method_mock.assert_called_with('endpoint-control', 'client', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
def test_endpoint_control_client_deletion_fails(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
delete_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
input_data = {
'username': 'admin',
'state': 'absent',
'endpoint_control_client': {
'ad_groups': 'test_value_3',
'ftcl_uid': 'test_value_4',
'id': '5',
'info': 'test_value_6',
'src_ip': 'test_value_7',
'src_mac': 'test_value_8'
},
'vdom': 'root'}
is_error, changed, response = fortios_endpoint_control_client.fortios_endpoint_control(input_data, fos_instance)
delete_method_mock.assert_called_with('endpoint-control', 'client', mkey=ANY, vdom='root')
schema_method_mock.assert_not_called()
assert is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 500
def test_endpoint_control_client_idempotent(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'endpoint_control_client': {
'ad_groups': 'test_value_3',
'ftcl_uid': 'test_value_4',
'id': '5',
'info': 'test_value_6',
'src_ip': 'test_value_7',
'src_mac': 'test_value_8'
},
'vdom': 'root'}
is_error, changed, response = fortios_endpoint_control_client.fortios_endpoint_control(input_data, fos_instance)
expected_data = {
'ad-groups': 'test_value_3',
'ftcl-uid': 'test_value_4',
'id': '5',
'info': 'test_value_6',
'src-ip': 'test_value_7',
'src-mac': 'test_value_8'
}
set_method_mock.assert_called_with('endpoint-control', 'client', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert not changed
assert response['status'] == 'error'
assert response['http_status'] == 404
def test_endpoint_control_client_filter_foreign_attributes(mocker):
schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
input_data = {
'username': 'admin',
'state': 'present',
'endpoint_control_client': {
'random_attribute_not_valid': 'tag',
'ad_groups': 'test_value_3',
'ftcl_uid': 'test_value_4',
'id': '5',
'info': 'test_value_6',
'src_ip': 'test_value_7',
'src_mac': 'test_value_8'
},
'vdom': 'root'}
is_error, changed, response = fortios_endpoint_control_client.fortios_endpoint_control(input_data, fos_instance)
expected_data = {
'ad-groups': 'test_value_3',
'ftcl-uid': 'test_value_4',
'id': '5',
'info': 'test_value_6',
'src-ip': 'test_value_7',
'src-mac': 'test_value_8'
}
set_method_mock.assert_called_with('endpoint-control', 'client', data=expected_data, vdom='root')
schema_method_mock.assert_not_called()
assert not is_error
assert changed
assert response['status'] == 'success'
assert response['http_status'] == 200
Loading…
Cancel
Save