FortiOS modules for 2.9 - 7 (#61217)

pull/61270/head
Miguel Angel Muñoz González 5 years ago committed by Nilashish Chakraborty
parent 9d4dcc7506
commit a6b124cccc

@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function)
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_log_memory_global_setting module: fortios_log_memory_global_setting
short_description: Global settings for memory logging in Fortinet's FortiOS and FortiGate. short_description: Global settings for memory logging in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by allowing the - This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify log_memory feature and global_setting category. user to set and modify log_memory feature and global_setting category.
Examples include all parameters and values need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,46 +41,60 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool type: bool
default: true default: true
version_added: 2.9
log_memory_global_setting: log_memory_global_setting:
description: description:
- Global settings for memory logging. - Global settings for memory logging.
default: null default: null
type: dict
suboptions: suboptions:
full-final-warning-threshold: full_final_warning_threshold:
description: description:
- Log full final warning threshold as a percent (3 - 100, default = 95). - Log full final warning threshold as a percent (3 - 100).
full-first-warning-threshold: type: int
full_first_warning_threshold:
description: description:
- Log full first warning threshold as a percent (1 - 98, default = 75). - Log full first warning threshold as a percent (1 - 98).
full-second-warning-threshold: type: int
full_second_warning_threshold:
description: description:
- Log full second warning threshold as a percent (2 - 99, default = 90). - Log full second warning threshold as a percent (2 - 99).
max-size: type: int
max_size:
description: description:
- Maximum amount of memory that can be used for memory logging in bytes. - Maximum amount of memory that can be used for memory logging in bytes.
type: int
''' '''
EXAMPLES = ''' EXAMPLES = '''
@ -93,6 +104,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Global settings for memory logging. - name: Global settings for memory logging.
fortios_log_memory_global_setting: fortios_log_memory_global_setting:
@ -102,10 +114,10 @@ EXAMPLES = '''
vdom: "{{ vdom }}" vdom: "{{ vdom }}"
https: "False" https: "False"
log_memory_global_setting: log_memory_global_setting:
full-final-warning-threshold: "3" full_final_warning_threshold: "3"
full-first-warning-threshold: "4" full_first_warning_threshold: "4"
full-second-warning-threshold: "5" full_second_warning_threshold: "5"
max-size: "6" max_size: "6"
''' '''
RETURN = ''' RETURN = '''
@ -168,14 +180,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
fos = None 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'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -183,12 +197,12 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_log_memory_global_setting_data(json): def filter_log_memory_global_setting_data(json):
option_list = ['full-final-warning-threshold', 'full-first-warning-threshold', 'full-second-warning-threshold', option_list = ['full_final_warning_threshold', 'full_first_warning_threshold', 'full_second_warning_threshold',
'max-size'] 'max_size']
dictionary = {} dictionary = {}
for attribute in option_list: for attribute in option_list:
@ -198,17 +212,15 @@ def filter_log_memory_global_setting_data(json):
return dictionary return dictionary
def flatten_multilists_attributes(data): def underscore_to_hyphen(data):
multilist_attrs = [] if isinstance(data, list):
for elem in data:
for attr in multilist_attrs: elem = underscore_to_hyphen(elem)
try: elif isinstance(data, dict):
path = "data['" + "']['".join(elem for elem in attr) + "']" new_data = {}
current_val = eval(path) for k, v in data.items():
flattened_val = ' '.join(elem for elem in current_val) new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
exec(path + '= flattened_val') data = new_data
except BaseException:
pass
return data return data
@ -216,38 +228,44 @@ def flatten_multilists_attributes(data):
def log_memory_global_setting(data, fos): def log_memory_global_setting(data, fos):
vdom = data['vdom'] vdom = data['vdom']
log_memory_global_setting_data = data['log_memory_global_setting'] log_memory_global_setting_data = data['log_memory_global_setting']
flattened_data = flatten_multilists_attributes(log_memory_global_setting_data) filtered_data = underscore_to_hyphen(filter_log_memory_global_setting_data(log_memory_global_setting_data))
filtered_data = filter_log_memory_global_setting_data(flattened_data)
return fos.set('log.memory', return fos.set('log.memory',
'global-setting', 'global-setting',
data=filtered_data, data=filtered_data,
vdom=vdom) vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_log_memory(data, fos): def fortios_log_memory(data, fos):
login(data)
if data['log_memory_global_setting']: if data['log_memory_global_setting']:
resp = log_memory_global_setting(data, fos) resp = log_memory_global_setting(data, fos)
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True}, "https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"log_memory_global_setting": { "log_memory_global_setting": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"full-final-warning-threshold": {"required": False, "type": "int"}, "full_final_warning_threshold": {"required": False, "type": "int"},
"full-first-warning-threshold": {"required": False, "type": "int"}, "full_first_warning_threshold": {"required": False, "type": "int"},
"full-second-warning-threshold": {"required": False, "type": "int"}, "full_second_warning_threshold": {"required": False, "type": "int"},
"max-size": {"required": False, "type": "int"} "max_size": {"required": False, "type": "int"}
} }
} }
@ -255,15 +273,31 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos # legacy_mode refers to using fortiosapi instead of HTTPAPI
fos = FortiOSAPI() 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_log_memory(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_log_memory(module.params, fos) login(module.params, fos)
is_error, has_changed, result = fortios_log_memory(module.params, fos)
fos.logout()
if not is_error: if not is_error:
module.exit_json(changed=has_changed, meta=result) 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 # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_log_memory_setting module: fortios_log_memory_setting
short_description: Settings for memory buffer in Fortinet's FortiOS and FortiGate. short_description: Settings for memory buffer in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by allowing the - This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify log_memory feature and setting category. user to set and modify log_memory feature and setting category.
Examples include all parameters and values need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,42 +41,54 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool type: bool
default: true default: true
version_added: 2.9
log_memory_setting: log_memory_setting:
description: description:
- Settings for memory buffer. - Settings for memory buffer.
default: null default: null
type: dict
suboptions: suboptions:
diskfull: diskfull:
description: description:
- Action to take when memory is full. - Action to take when memory is full.
type: str
choices: choices:
- overwrite - overwrite
status: status:
description: description:
- Enable/disable logging to the FortiGate's memory. - Enable/disable logging to the FortiGate's memory.
type: str
choices: choices:
- enable - enable
- disable - disable
@ -92,6 +101,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Settings for memory buffer. - name: Settings for memory buffer.
fortios_log_memory_setting: fortios_log_memory_setting:
@ -165,14 +175,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
fos = None 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'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -180,7 +192,7 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_log_memory_setting_data(json): def filter_log_memory_setting_data(json):
@ -194,17 +206,15 @@ def filter_log_memory_setting_data(json):
return dictionary return dictionary
def flatten_multilists_attributes(data): def underscore_to_hyphen(data):
multilist_attrs = [] if isinstance(data, list):
for elem in data:
for attr in multilist_attrs: elem = underscore_to_hyphen(elem)
try: elif isinstance(data, dict):
path = "data['" + "']['".join(elem for elem in attr) + "']" new_data = {}
current_val = eval(path) for k, v in data.items():
flattened_val = ' '.join(elem for elem in current_val) new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
exec(path + '= flattened_val') data = new_data
except BaseException:
pass
return data return data
@ -212,33 +222,39 @@ def flatten_multilists_attributes(data):
def log_memory_setting(data, fos): def log_memory_setting(data, fos):
vdom = data['vdom'] vdom = data['vdom']
log_memory_setting_data = data['log_memory_setting'] log_memory_setting_data = data['log_memory_setting']
flattened_data = flatten_multilists_attributes(log_memory_setting_data) filtered_data = underscore_to_hyphen(filter_log_memory_setting_data(log_memory_setting_data))
filtered_data = filter_log_memory_setting_data(flattened_data)
return fos.set('log.memory', return fos.set('log.memory',
'setting', 'setting',
data=filtered_data, data=filtered_data,
vdom=vdom) vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_log_memory(data, fos): def fortios_log_memory(data, fos):
login(data)
if data['log_memory_setting']: if data['log_memory_setting']:
resp = log_memory_setting(data, fos) resp = log_memory_setting(data, fos)
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True}, "https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"log_memory_setting": { "log_memory_setting": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"diskfull": {"required": False, "type": "str", "diskfull": {"required": False, "type": "str",
"choices": ["overwrite"]}, "choices": ["overwrite"]},
@ -251,15 +267,31 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos # legacy_mode refers to using fortiosapi instead of HTTPAPI
fos = FortiOSAPI() 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_log_memory(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_log_memory(module.params, fos) login(module.params, fos)
is_error, has_changed, result = fortios_log_memory(module.params, fos)
fos.logout()
if not is_error: if not is_error:
module.exit_json(changed=has_changed, meta=result) 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 # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_log_null_device_filter module: fortios_log_null_device_filter
short_description: Filters for null device logging in Fortinet's FortiOS and FortiGate. short_description: Filters for null device logging in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by allowing the - This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify log_null_device feature and filter category. user to set and modify log_null_device feature and filter category.
Examples include all parameters and values need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,88 +41,109 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool type: bool
default: true default: true
version_added: 2.9
log_null_device_filter: log_null_device_filter:
description: description:
- Filters for null device logging. - Filters for null device logging.
default: null default: null
type: dict
suboptions: suboptions:
anomaly: anomaly:
description: description:
- Enable/disable anomaly logging. - Enable/disable anomaly logging.
type: str
choices: choices:
- enable - enable
- disable - disable
dns: dns:
description: description:
- Enable/disable detailed DNS event logging. - Enable/disable detailed DNS event logging.
type: str
choices: choices:
- enable - enable
- disable - disable
filter: filter:
description: description:
- Null-device log filter. - Null-device log filter.
filter-type: type: str
filter_type:
description: description:
- Include/exclude logs that match the filter. - Include/exclude logs that match the filter.
type: str
choices: choices:
- include - include
- exclude - exclude
forward-traffic: forward_traffic:
description: description:
- Enable/disable forward traffic logging. - Enable/disable forward traffic logging.
type: str
choices: choices:
- enable - enable
- disable - disable
gtp: gtp:
description: description:
- Enable/disable GTP messages logging. - Enable/disable GTP messages logging.
type: str
choices: choices:
- enable - enable
- disable - disable
local-traffic: local_traffic:
description: description:
- Enable/disable local in or out traffic logging. - Enable/disable local in or out traffic logging.
type: str
choices: choices:
- enable - enable
- disable - disable
multicast-traffic: multicast_traffic:
description: description:
- Enable/disable multicast traffic logging. - Enable/disable multicast traffic logging.
type: str
choices: choices:
- enable - enable
- disable - disable
netscan-discovery: netscan_discovery:
description: description:
- Enable/disable netscan discovery event logging. - Enable/disable netscan discovery event logging.
netscan-vulnerability: type: str
netscan_vulnerability:
description: description:
- Enable/disable netscan vulnerability event logging. - Enable/disable netscan vulnerability event logging.
type: str
severity: severity:
description: description:
- Lowest severity level to log. - Lowest severity level to log.
type: str
choices: choices:
- emergency - emergency
- alert - alert
@ -135,21 +153,24 @@ options:
- notification - notification
- information - information
- debug - debug
sniffer-traffic: sniffer_traffic:
description: description:
- Enable/disable sniffer traffic logging. - Enable/disable sniffer traffic logging.
type: str
choices: choices:
- enable - enable
- disable - disable
ssh: ssh:
description: description:
- Enable/disable SSH logging. - Enable/disable SSH logging.
type: str
choices: choices:
- enable - enable
- disable - disable
voip: voip:
description: description:
- Enable/disable VoIP logging. - Enable/disable VoIP logging.
type: str
choices: choices:
- enable - enable
- disable - disable
@ -162,6 +183,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Filters for null device logging. - name: Filters for null device logging.
fortios_log_null_device_filter: fortios_log_null_device_filter:
@ -174,15 +196,15 @@ EXAMPLES = '''
anomaly: "enable" anomaly: "enable"
dns: "enable" dns: "enable"
filter: "<your_own_value>" filter: "<your_own_value>"
filter-type: "include" filter_type: "include"
forward-traffic: "enable" forward_traffic: "enable"
gtp: "enable" gtp: "enable"
local-traffic: "enable" local_traffic: "enable"
multicast-traffic: "enable" multicast_traffic: "enable"
netscan-discovery: "<your_own_value>" netscan_discovery: "<your_own_value>"
netscan-vulnerability: "<your_own_value>" netscan_vulnerability: "<your_own_value>"
severity: "emergency" severity: "emergency"
sniffer-traffic: "enable" sniffer_traffic: "enable"
ssh: "enable" ssh: "enable"
voip: "enable" voip: "enable"
''' '''
@ -247,14 +269,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
fos = None 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'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -262,14 +286,14 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_log_null_device_filter_data(json): def filter_log_null_device_filter_data(json):
option_list = ['anomaly', 'dns', 'filter', option_list = ['anomaly', 'dns', 'filter',
'filter-type', 'forward-traffic', 'gtp', 'filter_type', 'forward_traffic', 'gtp',
'local-traffic', 'multicast-traffic', 'netscan-discovery', 'local_traffic', 'multicast_traffic', 'netscan_discovery',
'netscan-vulnerability', 'severity', 'sniffer-traffic', 'netscan_vulnerability', 'severity', 'sniffer_traffic',
'ssh', 'voip'] 'ssh', 'voip']
dictionary = {} dictionary = {}
@ -280,17 +304,15 @@ def filter_log_null_device_filter_data(json):
return dictionary return dictionary
def flatten_multilists_attributes(data): def underscore_to_hyphen(data):
multilist_attrs = [] if isinstance(data, list):
for elem in data:
for attr in multilist_attrs: elem = underscore_to_hyphen(elem)
try: elif isinstance(data, dict):
path = "data['" + "']['".join(elem for elem in attr) + "']" new_data = {}
current_val = eval(path) for k, v in data.items():
flattened_val = ' '.join(elem for elem in current_val) new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
exec(path + '= flattened_val') data = new_data
except BaseException:
pass
return data return data
@ -298,56 +320,62 @@ def flatten_multilists_attributes(data):
def log_null_device_filter(data, fos): def log_null_device_filter(data, fos):
vdom = data['vdom'] vdom = data['vdom']
log_null_device_filter_data = data['log_null_device_filter'] log_null_device_filter_data = data['log_null_device_filter']
flattened_data = flatten_multilists_attributes(log_null_device_filter_data) filtered_data = underscore_to_hyphen(filter_log_null_device_filter_data(log_null_device_filter_data))
filtered_data = filter_log_null_device_filter_data(flattened_data)
return fos.set('log.null-device', return fos.set('log.null-device',
'filter', 'filter',
data=filtered_data, data=filtered_data,
vdom=vdom) vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_log_null_device(data, fos): def fortios_log_null_device(data, fos):
login(data)
if data['log_null_device_filter']: if data['log_null_device_filter']:
resp = log_null_device_filter(data, fos) resp = log_null_device_filter(data, fos)
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True}, "https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"log_null_device_filter": { "log_null_device_filter": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"anomaly": {"required": False, "type": "str", "anomaly": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"dns": {"required": False, "type": "str", "dns": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"filter": {"required": False, "type": "str"}, "filter": {"required": False, "type": "str"},
"filter-type": {"required": False, "type": "str", "filter_type": {"required": False, "type": "str",
"choices": ["include", "exclude"]}, "choices": ["include", "exclude"]},
"forward-traffic": {"required": False, "type": "str", "forward_traffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"gtp": {"required": False, "type": "str", "gtp": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"local-traffic": {"required": False, "type": "str", "local_traffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"multicast-traffic": {"required": False, "type": "str", "multicast_traffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"netscan-discovery": {"required": False, "type": "str"}, "netscan_discovery": {"required": False, "type": "str"},
"netscan-vulnerability": {"required": False, "type": "str"}, "netscan_vulnerability": {"required": False, "type": "str"},
"severity": {"required": False, "type": "str", "severity": {"required": False, "type": "str",
"choices": ["emergency", "alert", "critical", "choices": ["emergency", "alert", "critical",
"error", "warning", "notification", "error", "warning", "notification",
"information", "debug"]}, "information", "debug"]},
"sniffer-traffic": {"required": False, "type": "str", "sniffer_traffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"ssh": {"required": False, "type": "str", "ssh": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
@ -360,15 +388,31 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos # legacy_mode refers to using fortiosapi instead of HTTPAPI
fos = FortiOSAPI() 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_log_null_device(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_log_null_device(module.params, fos) login(module.params, fos)
is_error, has_changed, result = fortios_log_null_device(module.params, fos)
fos.logout()
if not is_error: if not is_error:
module.exit_json(changed=has_changed, meta=result) 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 # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_log_null_device_setting module: fortios_log_null_device_setting
short_description: Settings for null device logging in Fortinet's FortiOS and FortiGate. short_description: Settings for null device logging in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by allowing the - This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify log_null_device feature and setting category. user to set and modify log_null_device feature and setting category.
Examples include all parameters and values need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,37 +41,48 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool type: bool
default: true default: true
version_added: 2.9
log_null_device_setting: log_null_device_setting:
description: description:
- Settings for null device logging. - Settings for null device logging.
default: null default: null
type: dict
suboptions: suboptions:
status: status:
description: description:
- Enable/disable statistics collection for when no external logging destination, such as FortiAnalyzer, is present (data is not saved). - Enable/disable statistics collection for when no external logging destination, such as FortiAnalyzer, is present (data is not saved).
type: str
choices: choices:
- enable - enable
- disable - disable
@ -87,6 +95,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Settings for null device logging. - name: Settings for null device logging.
fortios_log_null_device_setting: fortios_log_null_device_setting:
@ -159,14 +168,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
fos = None 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'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -174,7 +185,7 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_log_null_device_setting_data(json): def filter_log_null_device_setting_data(json):
@ -188,17 +199,15 @@ def filter_log_null_device_setting_data(json):
return dictionary return dictionary
def flatten_multilists_attributes(data): def underscore_to_hyphen(data):
multilist_attrs = [] if isinstance(data, list):
for elem in data:
for attr in multilist_attrs: elem = underscore_to_hyphen(elem)
try: elif isinstance(data, dict):
path = "data['" + "']['".join(elem for elem in attr) + "']" new_data = {}
current_val = eval(path) for k, v in data.items():
flattened_val = ' '.join(elem for elem in current_val) new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
exec(path + '= flattened_val') data = new_data
except BaseException:
pass
return data return data
@ -206,33 +215,39 @@ def flatten_multilists_attributes(data):
def log_null_device_setting(data, fos): def log_null_device_setting(data, fos):
vdom = data['vdom'] vdom = data['vdom']
log_null_device_setting_data = data['log_null_device_setting'] log_null_device_setting_data = data['log_null_device_setting']
flattened_data = flatten_multilists_attributes(log_null_device_setting_data) filtered_data = underscore_to_hyphen(filter_log_null_device_setting_data(log_null_device_setting_data))
filtered_data = filter_log_null_device_setting_data(flattened_data)
return fos.set('log.null-device', return fos.set('log.null-device',
'setting', 'setting',
data=filtered_data, data=filtered_data,
vdom=vdom) vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_log_null_device(data, fos): def fortios_log_null_device(data, fos):
login(data)
if data['log_null_device_setting']: if data['log_null_device_setting']:
resp = log_null_device_setting(data, fos) resp = log_null_device_setting(data, fos)
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True}, "https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"log_null_device_setting": { "log_null_device_setting": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"status": {"required": False, "type": "str", "status": {"required": False, "type": "str",
"choices": ["enable", "disable"]} "choices": ["enable", "disable"]}
@ -243,15 +258,31 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos # legacy_mode refers to using fortiosapi instead of HTTPAPI
fos = FortiOSAPI() 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_log_null_device(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_log_null_device(module.params, fos) login(module.params, fos)
is_error, has_changed, result = fortios_log_null_device(module.params, fos)
fos.logout()
if not is_error: if not is_error:
module.exit_json(changed=has_changed, meta=result) 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 # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_log_setting module: fortios_log_setting
short_description: Configure general log settings in Fortinet's FortiOS and FortiGate. short_description: Configure general log settings in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by allowing the - This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify log feature and setting category. user to set and modify log feature and setting category.
Examples include all parameters and values need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,141 +41,169 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool type: bool
default: true default: true
version_added: 2.9
log_setting: log_setting:
description: description:
- Configure general log settings. - Configure general log settings.
default: null default: null
type: dict
suboptions: suboptions:
brief-traffic-format: brief_traffic_format:
description: description:
- Enable/disable brief format traffic logging. - Enable/disable brief format traffic logging.
type: str
choices: choices:
- enable - enable
- disable - disable
custom-log-fields: custom_log_fields:
description: description:
- Custom fields to append to all log messages. - Custom fields to append to all log messages.
type: list
suboptions: suboptions:
field-id: field_id:
description: description:
- Custom log field. Source log.custom-field.id. - Custom log field. Source log.custom-field.id.
required: true type: str
daemon-log: daemon_log:
description: description:
- Enable/disable daemon logging. - Enable/disable daemon logging.
type: str
choices: choices:
- enable - enable
- disable - disable
expolicy-implicit-log: expolicy_implicit_log:
description: description:
- Enable/disable explicit proxy firewall implicit policy logging. - Enable/disable explicit proxy firewall implicit policy logging.
type: str
choices: choices:
- enable - enable
- disable - disable
fwpolicy-implicit-log: fwpolicy_implicit_log:
description: description:
- Enable/disable implicit firewall policy logging. - Enable/disable implicit firewall policy logging.
type: str
choices: choices:
- enable - enable
- disable - disable
fwpolicy6-implicit-log: fwpolicy6_implicit_log:
description: description:
- Enable/disable implicit firewall policy6 logging. - Enable/disable implicit firewall policy6 logging.
type: str
choices: choices:
- enable - enable
- disable - disable
local-in-allow: local_in_allow:
description: description:
- Enable/disable local-in-allow logging. - Enable/disable local-in-allow logging.
type: str
choices: choices:
- enable - enable
- disable - disable
local-in-deny-broadcast: local_in_deny_broadcast:
description: description:
- Enable/disable local-in-deny-broadcast logging. - Enable/disable local-in-deny-broadcast logging.
type: str
choices: choices:
- enable - enable
- disable - disable
local-in-deny-unicast: local_in_deny_unicast:
description: description:
- Enable/disable local-in-deny-unicast logging. - Enable/disable local-in-deny-unicast logging.
type: str
choices: choices:
- enable - enable
- disable - disable
local-out: local_out:
description: description:
- Enable/disable local-out logging. - Enable/disable local-out logging.
type: str
choices: choices:
- enable - enable
- disable - disable
log-invalid-packet: log_invalid_packet:
description: description:
- Enable/disable invalid packet traffic logging. - Enable/disable invalid packet traffic logging.
type: str
choices: choices:
- enable - enable
- disable - disable
log-policy-comment: log_policy_comment:
description: description:
- Enable/disable inserting policy comments into traffic logs. - Enable/disable inserting policy comments into traffic logs.
type: str
choices: choices:
- enable - enable
- disable - disable
log-policy-name: log_policy_name:
description: description:
- Enable/disable inserting policy name into traffic logs. - Enable/disable inserting policy name into traffic logs.
type: str
choices: choices:
- enable - enable
- disable - disable
log-user-in-upper: log_user_in_upper:
description: description:
- Enable/disable logs with user-in-upper. - Enable/disable logs with user-in-upper.
type: str
choices: choices:
- enable - enable
- disable - disable
neighbor-event: neighbor_event:
description: description:
- Enable/disable neighbor event logging. - Enable/disable neighbor event logging.
type: str
choices: choices:
- enable - enable
- disable - disable
resolve-ip: resolve_ip:
description: description:
- Enable/disable adding resolved domain names to traffic logs if possible. - Enable/disable adding resolved domain names to traffic logs if possible.
type: str
choices: choices:
- enable - enable
- disable - disable
resolve-port: resolve_port:
description: description:
- Enable/disable adding resolved service names to traffic logs. - Enable/disable adding resolved service names to traffic logs.
type: str
choices: choices:
- enable - enable
- disable - disable
user-anonymize: user_anonymize:
description: description:
- Enable/disable anonymizing user names in log messages. - Enable/disable anonymizing user names in log messages.
type: str
choices: choices:
- enable - enable
- disable - disable
@ -191,6 +216,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Configure general log settings. - name: Configure general log settings.
fortios_log_setting: fortios_log_setting:
@ -200,26 +226,26 @@ EXAMPLES = '''
vdom: "{{ vdom }}" vdom: "{{ vdom }}"
https: "False" https: "False"
log_setting: log_setting:
brief-traffic-format: "enable" brief_traffic_format: "enable"
custom-log-fields: custom_log_fields:
- -
field-id: "<your_own_value> (source log.custom-field.id)" field_id: "<your_own_value> (source log.custom-field.id)"
daemon-log: "enable" daemon_log: "enable"
expolicy-implicit-log: "enable" expolicy_implicit_log: "enable"
fwpolicy-implicit-log: "enable" fwpolicy_implicit_log: "enable"
fwpolicy6-implicit-log: "enable" fwpolicy6_implicit_log: "enable"
local-in-allow: "enable" local_in_allow: "enable"
local-in-deny-broadcast: "enable" local_in_deny_broadcast: "enable"
local-in-deny-unicast: "enable" local_in_deny_unicast: "enable"
local-out: "enable" local_out: "enable"
log-invalid-packet: "enable" log_invalid_packet: "enable"
log-policy-comment: "enable" log_policy_comment: "enable"
log-policy-name: "enable" log_policy_name: "enable"
log-user-in-upper: "enable" log_user_in_upper: "enable"
neighbor-event: "enable" neighbor_event: "enable"
resolve-ip: "enable" resolve_ip: "enable"
resolve-port: "enable" resolve_port: "enable"
user-anonymize: "enable" user_anonymize: "enable"
''' '''
RETURN = ''' RETURN = '''
@ -282,14 +308,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
fos = None 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'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -297,16 +325,16 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_log_setting_data(json): def filter_log_setting_data(json):
option_list = ['brief-traffic-format', 'custom-log-fields', 'daemon-log', option_list = ['brief_traffic_format', 'custom_log_fields', 'daemon_log',
'expolicy-implicit-log', 'fwpolicy-implicit-log', 'fwpolicy6-implicit-log', 'expolicy_implicit_log', 'fwpolicy_implicit_log', 'fwpolicy6_implicit_log',
'local-in-allow', 'local-in-deny-broadcast', 'local-in-deny-unicast', 'local_in_allow', 'local_in_deny_broadcast', 'local_in_deny_unicast',
'local-out', 'log-invalid-packet', 'log-policy-comment', 'local_out', 'log_invalid_packet', 'log_policy_comment',
'log-policy-name', 'log-user-in-upper', 'neighbor-event', 'log_policy_name', 'log_user_in_upper', 'neighbor_event',
'resolve-ip', 'resolve-port', 'user-anonymize'] 'resolve_ip', 'resolve_port', 'user_anonymize']
dictionary = {} dictionary = {}
for attribute in option_list: for attribute in option_list:
@ -316,17 +344,15 @@ def filter_log_setting_data(json):
return dictionary return dictionary
def flatten_multilists_attributes(data): def underscore_to_hyphen(data):
multilist_attrs = [] if isinstance(data, list):
for elem in data:
for attr in multilist_attrs: elem = underscore_to_hyphen(elem)
try: elif isinstance(data, dict):
path = "data['" + "']['".join(elem for elem in attr) + "']" new_data = {}
current_val = eval(path) for k, v in data.items():
flattened_val = ' '.join(elem for elem in current_val) new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
exec(path + '= flattened_val') data = new_data
except BaseException:
pass
return data return data
@ -334,71 +360,77 @@ def flatten_multilists_attributes(data):
def log_setting(data, fos): def log_setting(data, fos):
vdom = data['vdom'] vdom = data['vdom']
log_setting_data = data['log_setting'] log_setting_data = data['log_setting']
flattened_data = flatten_multilists_attributes(log_setting_data) filtered_data = underscore_to_hyphen(filter_log_setting_data(log_setting_data))
filtered_data = filter_log_setting_data(flattened_data)
return fos.set('log', return fos.set('log',
'setting', 'setting',
data=filtered_data, data=filtered_data,
vdom=vdom) vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_log(data, fos): def fortios_log(data, fos):
login(data)
if data['log_setting']: if data['log_setting']:
resp = log_setting(data, fos) resp = log_setting(data, fos)
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True}, "https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"log_setting": { "log_setting": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"brief-traffic-format": {"required": False, "type": "str", "brief_traffic_format": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"custom-log-fields": {"required": False, "type": "list", "custom_log_fields": {"required": False, "type": "list",
"options": { "options": {
"field-id": {"required": True, "type": "str"} "field_id": {"required": False, "type": "str"}
}}, }},
"daemon-log": {"required": False, "type": "str", "daemon_log": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"expolicy-implicit-log": {"required": False, "type": "str", "expolicy_implicit_log": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"fwpolicy-implicit-log": {"required": False, "type": "str", "fwpolicy_implicit_log": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"fwpolicy6-implicit-log": {"required": False, "type": "str", "fwpolicy6_implicit_log": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"local-in-allow": {"required": False, "type": "str", "local_in_allow": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"local-in-deny-broadcast": {"required": False, "type": "str", "local_in_deny_broadcast": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"local-in-deny-unicast": {"required": False, "type": "str", "local_in_deny_unicast": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"local-out": {"required": False, "type": "str", "local_out": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"log-invalid-packet": {"required": False, "type": "str", "log_invalid_packet": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"log-policy-comment": {"required": False, "type": "str", "log_policy_comment": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"log-policy-name": {"required": False, "type": "str", "log_policy_name": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"log-user-in-upper": {"required": False, "type": "str", "log_user_in_upper": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"neighbor-event": {"required": False, "type": "str", "neighbor_event": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"resolve-ip": {"required": False, "type": "str", "resolve_ip": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"resolve-port": {"required": False, "type": "str", "resolve_port": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"user-anonymize": {"required": False, "type": "str", "user_anonymize": {"required": False, "type": "str",
"choices": ["enable", "disable"]} "choices": ["enable", "disable"]}
} }
@ -407,15 +439,31 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos # legacy_mode refers to using fortiosapi instead of HTTPAPI
fos = FortiOSAPI() 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_log(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_log(module.params, fos) login(module.params, fos)
is_error, has_changed, result = fortios_log(module.params, fos)
fos.logout()
if not is_error: if not is_error:
module.exit_json(changed=has_changed, meta=result) 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 # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_log_syslogd2_filter module: fortios_log_syslogd2_filter
short_description: Filters for remote system server in Fortinet's FortiOS and FortiGate. short_description: Filters for remote system server in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by allowing the - This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify log_syslogd2 feature and filter category. user to set and modify log_syslogd2 feature and filter category.
Examples include all parameters and values need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,88 +41,109 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool type: bool
default: true default: true
version_added: 2.9
log_syslogd2_filter: log_syslogd2_filter:
description: description:
- Filters for remote system server. - Filters for remote system server.
default: null default: null
type: dict
suboptions: suboptions:
anomaly: anomaly:
description: description:
- Enable/disable anomaly logging. - Enable/disable anomaly logging.
type: str
choices: choices:
- enable - enable
- disable - disable
dns: dns:
description: description:
- Enable/disable detailed DNS event logging. - Enable/disable detailed DNS event logging.
type: str
choices: choices:
- enable - enable
- disable - disable
filter: filter:
description: description:
- Syslog 2 filter. - Syslog 2 filter.
filter-type: type: str
filter_type:
description: description:
- Include/exclude logs that match the filter. - Include/exclude logs that match the filter.
type: str
choices: choices:
- include - include
- exclude - exclude
forward-traffic: forward_traffic:
description: description:
- Enable/disable forward traffic logging. - Enable/disable forward traffic logging.
type: str
choices: choices:
- enable - enable
- disable - disable
gtp: gtp:
description: description:
- Enable/disable GTP messages logging. - Enable/disable GTP messages logging.
type: str
choices: choices:
- enable - enable
- disable - disable
local-traffic: local_traffic:
description: description:
- Enable/disable local in or out traffic logging. - Enable/disable local in or out traffic logging.
type: str
choices: choices:
- enable - enable
- disable - disable
multicast-traffic: multicast_traffic:
description: description:
- Enable/disable multicast traffic logging. - Enable/disable multicast traffic logging.
type: str
choices: choices:
- enable - enable
- disable - disable
netscan-discovery: netscan_discovery:
description: description:
- Enable/disable netscan discovery event logging. - Enable/disable netscan discovery event logging.
netscan-vulnerability: type: str
netscan_vulnerability:
description: description:
- Enable/disable netscan vulnerability event logging. - Enable/disable netscan vulnerability event logging.
type: str
severity: severity:
description: description:
- Lowest severity level to log. - Lowest severity level to log.
type: str
choices: choices:
- emergency - emergency
- alert - alert
@ -135,21 +153,24 @@ options:
- notification - notification
- information - information
- debug - debug
sniffer-traffic: sniffer_traffic:
description: description:
- Enable/disable sniffer traffic logging. - Enable/disable sniffer traffic logging.
type: str
choices: choices:
- enable - enable
- disable - disable
ssh: ssh:
description: description:
- Enable/disable SSH logging. - Enable/disable SSH logging.
type: str
choices: choices:
- enable - enable
- disable - disable
voip: voip:
description: description:
- Enable/disable VoIP logging. - Enable/disable VoIP logging.
type: str
choices: choices:
- enable - enable
- disable - disable
@ -162,6 +183,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Filters for remote system server. - name: Filters for remote system server.
fortios_log_syslogd2_filter: fortios_log_syslogd2_filter:
@ -174,15 +196,15 @@ EXAMPLES = '''
anomaly: "enable" anomaly: "enable"
dns: "enable" dns: "enable"
filter: "<your_own_value>" filter: "<your_own_value>"
filter-type: "include" filter_type: "include"
forward-traffic: "enable" forward_traffic: "enable"
gtp: "enable" gtp: "enable"
local-traffic: "enable" local_traffic: "enable"
multicast-traffic: "enable" multicast_traffic: "enable"
netscan-discovery: "<your_own_value>" netscan_discovery: "<your_own_value>"
netscan-vulnerability: "<your_own_value>" netscan_vulnerability: "<your_own_value>"
severity: "emergency" severity: "emergency"
sniffer-traffic: "enable" sniffer_traffic: "enable"
ssh: "enable" ssh: "enable"
voip: "enable" voip: "enable"
''' '''
@ -247,14 +269,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
fos = None 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'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -262,14 +286,14 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_log_syslogd2_filter_data(json): def filter_log_syslogd2_filter_data(json):
option_list = ['anomaly', 'dns', 'filter', option_list = ['anomaly', 'dns', 'filter',
'filter-type', 'forward-traffic', 'gtp', 'filter_type', 'forward_traffic', 'gtp',
'local-traffic', 'multicast-traffic', 'netscan-discovery', 'local_traffic', 'multicast_traffic', 'netscan_discovery',
'netscan-vulnerability', 'severity', 'sniffer-traffic', 'netscan_vulnerability', 'severity', 'sniffer_traffic',
'ssh', 'voip'] 'ssh', 'voip']
dictionary = {} dictionary = {}
@ -280,17 +304,15 @@ def filter_log_syslogd2_filter_data(json):
return dictionary return dictionary
def flatten_multilists_attributes(data): def underscore_to_hyphen(data):
multilist_attrs = [] if isinstance(data, list):
for elem in data:
for attr in multilist_attrs: elem = underscore_to_hyphen(elem)
try: elif isinstance(data, dict):
path = "data['" + "']['".join(elem for elem in attr) + "']" new_data = {}
current_val = eval(path) for k, v in data.items():
flattened_val = ' '.join(elem for elem in current_val) new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
exec(path + '= flattened_val') data = new_data
except BaseException:
pass
return data return data
@ -298,56 +320,62 @@ def flatten_multilists_attributes(data):
def log_syslogd2_filter(data, fos): def log_syslogd2_filter(data, fos):
vdom = data['vdom'] vdom = data['vdom']
log_syslogd2_filter_data = data['log_syslogd2_filter'] log_syslogd2_filter_data = data['log_syslogd2_filter']
flattened_data = flatten_multilists_attributes(log_syslogd2_filter_data) filtered_data = underscore_to_hyphen(filter_log_syslogd2_filter_data(log_syslogd2_filter_data))
filtered_data = filter_log_syslogd2_filter_data(flattened_data)
return fos.set('log.syslogd2', return fos.set('log.syslogd2',
'filter', 'filter',
data=filtered_data, data=filtered_data,
vdom=vdom) vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_log_syslogd2(data, fos): def fortios_log_syslogd2(data, fos):
login(data)
if data['log_syslogd2_filter']: if data['log_syslogd2_filter']:
resp = log_syslogd2_filter(data, fos) resp = log_syslogd2_filter(data, fos)
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True}, "https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"log_syslogd2_filter": { "log_syslogd2_filter": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"anomaly": {"required": False, "type": "str", "anomaly": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"dns": {"required": False, "type": "str", "dns": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"filter": {"required": False, "type": "str"}, "filter": {"required": False, "type": "str"},
"filter-type": {"required": False, "type": "str", "filter_type": {"required": False, "type": "str",
"choices": ["include", "exclude"]}, "choices": ["include", "exclude"]},
"forward-traffic": {"required": False, "type": "str", "forward_traffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"gtp": {"required": False, "type": "str", "gtp": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"local-traffic": {"required": False, "type": "str", "local_traffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"multicast-traffic": {"required": False, "type": "str", "multicast_traffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"netscan-discovery": {"required": False, "type": "str"}, "netscan_discovery": {"required": False, "type": "str"},
"netscan-vulnerability": {"required": False, "type": "str"}, "netscan_vulnerability": {"required": False, "type": "str"},
"severity": {"required": False, "type": "str", "severity": {"required": False, "type": "str",
"choices": ["emergency", "alert", "critical", "choices": ["emergency", "alert", "critical",
"error", "warning", "notification", "error", "warning", "notification",
"information", "debug"]}, "information", "debug"]},
"sniffer-traffic": {"required": False, "type": "str", "sniffer_traffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"ssh": {"required": False, "type": "str", "ssh": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
@ -360,15 +388,31 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos # legacy_mode refers to using fortiosapi instead of HTTPAPI
fos = FortiOSAPI() 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_log_syslogd2(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_log_syslogd2(module.params, fos) login(module.params, fos)
is_error, has_changed, result = fortios_log_syslogd2(module.params, fos)
fos.logout()
if not is_error: if not is_error:
module.exit_json(changed=has_changed, meta=result) 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 # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_log_syslogd2_setting module: fortios_log_syslogd2_setting
short_description: Global settings for remote syslog server in Fortinet's FortiOS and FortiGate. short_description: Global settings for remote syslog server in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by allowing the - This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify log_syslogd2 feature and setting category. user to set and modify log_syslogd2 feature and setting category.
Examples include all parameters and values need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,54 +41,70 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool type: bool
default: true default: true
version_added: 2.9
log_syslogd2_setting: log_syslogd2_setting:
description: description:
- Global settings for remote syslog server. - Global settings for remote syslog server.
default: null default: null
type: dict
suboptions: suboptions:
certificate: certificate:
description: description:
- Certificate used to communicate with Syslog server. Source certificate.local.name. - Certificate used to communicate with Syslog server. Source certificate.local.name.
custom-field-name: type: str
custom_field_name:
description: description:
- Custom field name for CEF format logging. - Custom field name for CEF format logging.
type: list
suboptions: suboptions:
custom: custom:
description: description:
- Field custom name. - Field custom name.
type: str
id: id:
description: description:
- Entry ID. - Entry ID.
required: true required: true
type: int
name: name:
description: description:
- Field name. - Field name.
enc-algorithm: type: str
enc_algorithm:
description: description:
- Enable/disable reliable syslogging with TLS encryption. - Enable/disable reliable syslogging with TLS encryption.
type: str
choices: choices:
- high-medium - high-medium
- high - high
@ -100,6 +113,7 @@ options:
facility: facility:
description: description:
- Remote syslog facility. - Remote syslog facility.
type: str
choices: choices:
- kernel - kernel
- user - user
@ -128,6 +142,7 @@ options:
format: format:
description: description:
- Log format. - Log format.
type: str
choices: choices:
- default - default
- csv - csv
@ -135,6 +150,7 @@ options:
mode: mode:
description: description:
- Remote syslog logging over UDP/Reliable TCP. - Remote syslog logging over UDP/Reliable TCP.
type: str
choices: choices:
- udp - udp
- legacy-reliable - legacy-reliable
@ -142,15 +158,29 @@ options:
port: port:
description: description:
- Server listen port. - Server listen port.
type: int
server: server:
description: description:
- Address of remote syslog server. - Address of remote syslog server.
source-ip: type: str
source_ip:
description: description:
- Source IP address of syslog. - Source IP address of syslog.
type: str
ssl_min_proto_version:
description:
- Minimum supported protocol version for SSL/TLS connections .
type: str
choices:
- default
- SSLv3
- TLSv1
- TLSv1-1
- TLSv1-2
status: status:
description: description:
- Enable/disable remote syslog logging. - Enable/disable remote syslog logging.
type: str
choices: choices:
- enable - enable
- disable - disable
@ -163,6 +193,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Global settings for remote syslog server. - name: Global settings for remote syslog server.
fortios_log_syslogd2_setting: fortios_log_syslogd2_setting:
@ -173,18 +204,19 @@ EXAMPLES = '''
https: "False" https: "False"
log_syslogd2_setting: log_syslogd2_setting:
certificate: "<your_own_value> (source certificate.local.name)" certificate: "<your_own_value> (source certificate.local.name)"
custom-field-name: custom_field_name:
- -
custom: "<your_own_value>" custom: "<your_own_value>"
id: "6" id: "6"
name: "default_name_7" name: "default_name_7"
enc-algorithm: "high-medium" enc_algorithm: "high-medium"
facility: "kernel" facility: "kernel"
format: "default" format: "default"
mode: "udp" mode: "udp"
port: "12" port: "12"
server: "192.168.100.40" server: "192.168.100.40"
source-ip: "84.230.14.43" source_ip: "84.230.14.43"
ssl_min_proto_version: "default"
status: "enable" status: "enable"
''' '''
@ -248,14 +280,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule 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, fos):
def login(data):
host = data['host'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -263,14 +297,14 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_log_syslogd2_setting_data(json): def filter_log_syslogd2_setting_data(json):
option_list = ['certificate', 'custom-field-name', 'enc-algorithm', option_list = ['certificate', 'custom_field_name', 'enc_algorithm',
'facility', 'format', 'mode', 'facility', 'format', 'mode',
'port', 'server', 'source-ip', 'port', 'server', 'source_ip',
'status'] 'ssl_min_proto_version', 'status']
dictionary = {} dictionary = {}
for attribute in option_list: for attribute in option_list:
@ -280,17 +314,15 @@ def filter_log_syslogd2_setting_data(json):
return dictionary return dictionary
def flatten_multilists_attributes(data): def underscore_to_hyphen(data):
multilist_attrs = [] if isinstance(data, list):
for elem in data:
for attr in multilist_attrs: elem = underscore_to_hyphen(elem)
try: elif isinstance(data, dict):
path = "data['" + "']['".join(elem for elem in attr) + "']" new_data = {}
current_val = eval(path) for k, v in data.items():
flattened_val = ' '.join(elem for elem in current_val) new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
exec(path + '= flattened_val') data = new_data
except BaseException:
pass
return data return data
@ -298,42 +330,48 @@ def flatten_multilists_attributes(data):
def log_syslogd2_setting(data, fos): def log_syslogd2_setting(data, fos):
vdom = data['vdom'] vdom = data['vdom']
log_syslogd2_setting_data = data['log_syslogd2_setting'] log_syslogd2_setting_data = data['log_syslogd2_setting']
flattened_data = flatten_multilists_attributes(log_syslogd2_setting_data) filtered_data = underscore_to_hyphen(filter_log_syslogd2_setting_data(log_syslogd2_setting_data))
filtered_data = filter_log_syslogd2_setting_data(flattened_data)
return fos.set('log.syslogd2', return fos.set('log.syslogd2',
'setting', 'setting',
data=filtered_data, data=filtered_data,
vdom=vdom) vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_log_syslogd2(data, fos): def fortios_log_syslogd2(data, fos):
login(data)
if data['log_syslogd2_setting']: if data['log_syslogd2_setting']:
resp = log_syslogd2_setting(data, fos) resp = log_syslogd2_setting(data, fos)
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True}, "https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"log_syslogd2_setting": { "log_syslogd2_setting": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"certificate": {"required": False, "type": "str"}, "certificate": {"required": False, "type": "str"},
"custom-field-name": {"required": False, "type": "list", "custom_field_name": {"required": False, "type": "list",
"options": { "options": {
"custom": {"required": False, "type": "str"}, "custom": {"required": False, "type": "str"},
"id": {"required": True, "type": "int"}, "id": {"required": True, "type": "int"},
"name": {"required": False, "type": "str"} "name": {"required": False, "type": "str"}
}}, }},
"enc-algorithm": {"required": False, "type": "str", "enc_algorithm": {"required": False, "type": "str",
"choices": ["high-medium", "high", "low", "choices": ["high-medium", "high", "low",
"disable"]}, "disable"]},
"facility": {"required": False, "type": "str", "facility": {"required": False, "type": "str",
@ -351,7 +389,10 @@ def main():
"choices": ["udp", "legacy-reliable", "reliable"]}, "choices": ["udp", "legacy-reliable", "reliable"]},
"port": {"required": False, "type": "int"}, "port": {"required": False, "type": "int"},
"server": {"required": False, "type": "str"}, "server": {"required": False, "type": "str"},
"source-ip": {"required": False, "type": "str"}, "source_ip": {"required": False, "type": "str"},
"ssl_min_proto_version": {"required": False, "type": "str",
"choices": ["default", "SSLv3", "TLSv1",
"TLSv1-1", "TLSv1-2"]},
"status": {"required": False, "type": "str", "status": {"required": False, "type": "str",
"choices": ["enable", "disable"]} "choices": ["enable", "disable"]}
@ -361,15 +402,31 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos # legacy_mode refers to using fortiosapi instead of HTTPAPI
fos = FortiOSAPI() 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_log_syslogd2(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_log_syslogd2(module.params, fos) login(module.params, fos)
is_error, has_changed, result = fortios_log_syslogd2(module.params, fos)
fos.logout()
if not is_error: if not is_error:
module.exit_json(changed=has_changed, meta=result) 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 # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_log_syslogd3_filter module: fortios_log_syslogd3_filter
short_description: Filters for remote system server in Fortinet's FortiOS and FortiGate. short_description: Filters for remote system server in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by allowing the - This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify log_syslogd3 feature and filter category. user to set and modify log_syslogd3 feature and filter category.
Examples include all parameters and values need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,88 +41,109 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool type: bool
default: true default: true
version_added: 2.9
log_syslogd3_filter: log_syslogd3_filter:
description: description:
- Filters for remote system server. - Filters for remote system server.
default: null default: null
type: dict
suboptions: suboptions:
anomaly: anomaly:
description: description:
- Enable/disable anomaly logging. - Enable/disable anomaly logging.
type: str
choices: choices:
- enable - enable
- disable - disable
dns: dns:
description: description:
- Enable/disable detailed DNS event logging. - Enable/disable detailed DNS event logging.
type: str
choices: choices:
- enable - enable
- disable - disable
filter: filter:
description: description:
- Syslog 3 filter. - Syslog 3 filter.
filter-type: type: str
filter_type:
description: description:
- Include/exclude logs that match the filter. - Include/exclude logs that match the filter.
type: str
choices: choices:
- include - include
- exclude - exclude
forward-traffic: forward_traffic:
description: description:
- Enable/disable forward traffic logging. - Enable/disable forward traffic logging.
type: str
choices: choices:
- enable - enable
- disable - disable
gtp: gtp:
description: description:
- Enable/disable GTP messages logging. - Enable/disable GTP messages logging.
type: str
choices: choices:
- enable - enable
- disable - disable
local-traffic: local_traffic:
description: description:
- Enable/disable local in or out traffic logging. - Enable/disable local in or out traffic logging.
type: str
choices: choices:
- enable - enable
- disable - disable
multicast-traffic: multicast_traffic:
description: description:
- Enable/disable multicast traffic logging. - Enable/disable multicast traffic logging.
type: str
choices: choices:
- enable - enable
- disable - disable
netscan-discovery: netscan_discovery:
description: description:
- Enable/disable netscan discovery event logging. - Enable/disable netscan discovery event logging.
netscan-vulnerability: type: str
netscan_vulnerability:
description: description:
- Enable/disable netscan vulnerability event logging. - Enable/disable netscan vulnerability event logging.
type: str
severity: severity:
description: description:
- Lowest severity level to log. - Lowest severity level to log.
type: str
choices: choices:
- emergency - emergency
- alert - alert
@ -135,21 +153,24 @@ options:
- notification - notification
- information - information
- debug - debug
sniffer-traffic: sniffer_traffic:
description: description:
- Enable/disable sniffer traffic logging. - Enable/disable sniffer traffic logging.
type: str
choices: choices:
- enable - enable
- disable - disable
ssh: ssh:
description: description:
- Enable/disable SSH logging. - Enable/disable SSH logging.
type: str
choices: choices:
- enable - enable
- disable - disable
voip: voip:
description: description:
- Enable/disable VoIP logging. - Enable/disable VoIP logging.
type: str
choices: choices:
- enable - enable
- disable - disable
@ -162,6 +183,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Filters for remote system server. - name: Filters for remote system server.
fortios_log_syslogd3_filter: fortios_log_syslogd3_filter:
@ -174,15 +196,15 @@ EXAMPLES = '''
anomaly: "enable" anomaly: "enable"
dns: "enable" dns: "enable"
filter: "<your_own_value>" filter: "<your_own_value>"
filter-type: "include" filter_type: "include"
forward-traffic: "enable" forward_traffic: "enable"
gtp: "enable" gtp: "enable"
local-traffic: "enable" local_traffic: "enable"
multicast-traffic: "enable" multicast_traffic: "enable"
netscan-discovery: "<your_own_value>" netscan_discovery: "<your_own_value>"
netscan-vulnerability: "<your_own_value>" netscan_vulnerability: "<your_own_value>"
severity: "emergency" severity: "emergency"
sniffer-traffic: "enable" sniffer_traffic: "enable"
ssh: "enable" ssh: "enable"
voip: "enable" voip: "enable"
''' '''
@ -247,14 +269,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
fos = None 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'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -262,14 +286,14 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_log_syslogd3_filter_data(json): def filter_log_syslogd3_filter_data(json):
option_list = ['anomaly', 'dns', 'filter', option_list = ['anomaly', 'dns', 'filter',
'filter-type', 'forward-traffic', 'gtp', 'filter_type', 'forward_traffic', 'gtp',
'local-traffic', 'multicast-traffic', 'netscan-discovery', 'local_traffic', 'multicast_traffic', 'netscan_discovery',
'netscan-vulnerability', 'severity', 'sniffer-traffic', 'netscan_vulnerability', 'severity', 'sniffer_traffic',
'ssh', 'voip'] 'ssh', 'voip']
dictionary = {} dictionary = {}
@ -280,17 +304,15 @@ def filter_log_syslogd3_filter_data(json):
return dictionary return dictionary
def flatten_multilists_attributes(data): def underscore_to_hyphen(data):
multilist_attrs = [] if isinstance(data, list):
for elem in data:
for attr in multilist_attrs: elem = underscore_to_hyphen(elem)
try: elif isinstance(data, dict):
path = "data['" + "']['".join(elem for elem in attr) + "']" new_data = {}
current_val = eval(path) for k, v in data.items():
flattened_val = ' '.join(elem for elem in current_val) new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
exec(path + '= flattened_val') data = new_data
except BaseException:
pass
return data return data
@ -298,56 +320,62 @@ def flatten_multilists_attributes(data):
def log_syslogd3_filter(data, fos): def log_syslogd3_filter(data, fos):
vdom = data['vdom'] vdom = data['vdom']
log_syslogd3_filter_data = data['log_syslogd3_filter'] log_syslogd3_filter_data = data['log_syslogd3_filter']
flattened_data = flatten_multilists_attributes(log_syslogd3_filter_data) filtered_data = underscore_to_hyphen(filter_log_syslogd3_filter_data(log_syslogd3_filter_data))
filtered_data = filter_log_syslogd3_filter_data(flattened_data)
return fos.set('log.syslogd3', return fos.set('log.syslogd3',
'filter', 'filter',
data=filtered_data, data=filtered_data,
vdom=vdom) vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_log_syslogd3(data, fos): def fortios_log_syslogd3(data, fos):
login(data)
if data['log_syslogd3_filter']: if data['log_syslogd3_filter']:
resp = log_syslogd3_filter(data, fos) resp = log_syslogd3_filter(data, fos)
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True}, "https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"log_syslogd3_filter": { "log_syslogd3_filter": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"anomaly": {"required": False, "type": "str", "anomaly": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"dns": {"required": False, "type": "str", "dns": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"filter": {"required": False, "type": "str"}, "filter": {"required": False, "type": "str"},
"filter-type": {"required": False, "type": "str", "filter_type": {"required": False, "type": "str",
"choices": ["include", "exclude"]}, "choices": ["include", "exclude"]},
"forward-traffic": {"required": False, "type": "str", "forward_traffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"gtp": {"required": False, "type": "str", "gtp": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"local-traffic": {"required": False, "type": "str", "local_traffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"multicast-traffic": {"required": False, "type": "str", "multicast_traffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"netscan-discovery": {"required": False, "type": "str"}, "netscan_discovery": {"required": False, "type": "str"},
"netscan-vulnerability": {"required": False, "type": "str"}, "netscan_vulnerability": {"required": False, "type": "str"},
"severity": {"required": False, "type": "str", "severity": {"required": False, "type": "str",
"choices": ["emergency", "alert", "critical", "choices": ["emergency", "alert", "critical",
"error", "warning", "notification", "error", "warning", "notification",
"information", "debug"]}, "information", "debug"]},
"sniffer-traffic": {"required": False, "type": "str", "sniffer_traffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"ssh": {"required": False, "type": "str", "ssh": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
@ -360,15 +388,31 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos # legacy_mode refers to using fortiosapi instead of HTTPAPI
fos = FortiOSAPI() 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_log_syslogd3(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_log_syslogd3(module.params, fos) login(module.params, fos)
is_error, has_changed, result = fortios_log_syslogd3(module.params, fos)
fos.logout()
if not is_error: if not is_error:
module.exit_json(changed=has_changed, meta=result) 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 # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_log_syslogd3_setting module: fortios_log_syslogd3_setting
short_description: Global settings for remote syslog server in Fortinet's FortiOS and FortiGate. short_description: Global settings for remote syslog server in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by allowing the - This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify log_syslogd3 feature and setting category. user to set and modify log_syslogd3 feature and setting category.
Examples include all parameters and values need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,54 +41,70 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool type: bool
default: true default: true
version_added: 2.9
log_syslogd3_setting: log_syslogd3_setting:
description: description:
- Global settings for remote syslog server. - Global settings for remote syslog server.
default: null default: null
type: dict
suboptions: suboptions:
certificate: certificate:
description: description:
- Certificate used to communicate with Syslog server. Source certificate.local.name. - Certificate used to communicate with Syslog server. Source certificate.local.name.
custom-field-name: type: str
custom_field_name:
description: description:
- Custom field name for CEF format logging. - Custom field name for CEF format logging.
type: list
suboptions: suboptions:
custom: custom:
description: description:
- Field custom name. - Field custom name.
type: str
id: id:
description: description:
- Entry ID. - Entry ID.
required: true required: true
type: int
name: name:
description: description:
- Field name. - Field name.
enc-algorithm: type: str
enc_algorithm:
description: description:
- Enable/disable reliable syslogging with TLS encryption. - Enable/disable reliable syslogging with TLS encryption.
type: str
choices: choices:
- high-medium - high-medium
- high - high
@ -100,6 +113,7 @@ options:
facility: facility:
description: description:
- Remote syslog facility. - Remote syslog facility.
type: str
choices: choices:
- kernel - kernel
- user - user
@ -128,6 +142,7 @@ options:
format: format:
description: description:
- Log format. - Log format.
type: str
choices: choices:
- default - default
- csv - csv
@ -135,6 +150,7 @@ options:
mode: mode:
description: description:
- Remote syslog logging over UDP/Reliable TCP. - Remote syslog logging over UDP/Reliable TCP.
type: str
choices: choices:
- udp - udp
- legacy-reliable - legacy-reliable
@ -142,15 +158,29 @@ options:
port: port:
description: description:
- Server listen port. - Server listen port.
type: int
server: server:
description: description:
- Address of remote syslog server. - Address of remote syslog server.
source-ip: type: str
source_ip:
description: description:
- Source IP address of syslog. - Source IP address of syslog.
type: str
ssl_min_proto_version:
description:
- Minimum supported protocol version for SSL/TLS connections .
type: str
choices:
- default
- SSLv3
- TLSv1
- TLSv1-1
- TLSv1-2
status: status:
description: description:
- Enable/disable remote syslog logging. - Enable/disable remote syslog logging.
type: str
choices: choices:
- enable - enable
- disable - disable
@ -163,6 +193,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Global settings for remote syslog server. - name: Global settings for remote syslog server.
fortios_log_syslogd3_setting: fortios_log_syslogd3_setting:
@ -173,18 +204,19 @@ EXAMPLES = '''
https: "False" https: "False"
log_syslogd3_setting: log_syslogd3_setting:
certificate: "<your_own_value> (source certificate.local.name)" certificate: "<your_own_value> (source certificate.local.name)"
custom-field-name: custom_field_name:
- -
custom: "<your_own_value>" custom: "<your_own_value>"
id: "6" id: "6"
name: "default_name_7" name: "default_name_7"
enc-algorithm: "high-medium" enc_algorithm: "high-medium"
facility: "kernel" facility: "kernel"
format: "default" format: "default"
mode: "udp" mode: "udp"
port: "12" port: "12"
server: "192.168.100.40" server: "192.168.100.40"
source-ip: "84.230.14.43" source_ip: "84.230.14.43"
ssl_min_proto_version: "default"
status: "enable" status: "enable"
''' '''
@ -248,14 +280,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule 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, fos):
def login(data):
host = data['host'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -263,14 +297,14 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_log_syslogd3_setting_data(json): def filter_log_syslogd3_setting_data(json):
option_list = ['certificate', 'custom-field-name', 'enc-algorithm', option_list = ['certificate', 'custom_field_name', 'enc_algorithm',
'facility', 'format', 'mode', 'facility', 'format', 'mode',
'port', 'server', 'source-ip', 'port', 'server', 'source_ip',
'status'] 'ssl_min_proto_version', 'status']
dictionary = {} dictionary = {}
for attribute in option_list: for attribute in option_list:
@ -280,17 +314,15 @@ def filter_log_syslogd3_setting_data(json):
return dictionary return dictionary
def flatten_multilists_attributes(data): def underscore_to_hyphen(data):
multilist_attrs = [] if isinstance(data, list):
for elem in data:
for attr in multilist_attrs: elem = underscore_to_hyphen(elem)
try: elif isinstance(data, dict):
path = "data['" + "']['".join(elem for elem in attr) + "']" new_data = {}
current_val = eval(path) for k, v in data.items():
flattened_val = ' '.join(elem for elem in current_val) new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
exec(path + '= flattened_val') data = new_data
except BaseException:
pass
return data return data
@ -298,42 +330,48 @@ def flatten_multilists_attributes(data):
def log_syslogd3_setting(data, fos): def log_syslogd3_setting(data, fos):
vdom = data['vdom'] vdom = data['vdom']
log_syslogd3_setting_data = data['log_syslogd3_setting'] log_syslogd3_setting_data = data['log_syslogd3_setting']
flattened_data = flatten_multilists_attributes(log_syslogd3_setting_data) filtered_data = underscore_to_hyphen(filter_log_syslogd3_setting_data(log_syslogd3_setting_data))
filtered_data = filter_log_syslogd3_setting_data(flattened_data)
return fos.set('log.syslogd3', return fos.set('log.syslogd3',
'setting', 'setting',
data=filtered_data, data=filtered_data,
vdom=vdom) vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_log_syslogd3(data, fos): def fortios_log_syslogd3(data, fos):
login(data)
if data['log_syslogd3_setting']: if data['log_syslogd3_setting']:
resp = log_syslogd3_setting(data, fos) resp = log_syslogd3_setting(data, fos)
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True}, "https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"log_syslogd3_setting": { "log_syslogd3_setting": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"certificate": {"required": False, "type": "str"}, "certificate": {"required": False, "type": "str"},
"custom-field-name": {"required": False, "type": "list", "custom_field_name": {"required": False, "type": "list",
"options": { "options": {
"custom": {"required": False, "type": "str"}, "custom": {"required": False, "type": "str"},
"id": {"required": True, "type": "int"}, "id": {"required": True, "type": "int"},
"name": {"required": False, "type": "str"} "name": {"required": False, "type": "str"}
}}, }},
"enc-algorithm": {"required": False, "type": "str", "enc_algorithm": {"required": False, "type": "str",
"choices": ["high-medium", "high", "low", "choices": ["high-medium", "high", "low",
"disable"]}, "disable"]},
"facility": {"required": False, "type": "str", "facility": {"required": False, "type": "str",
@ -351,7 +389,10 @@ def main():
"choices": ["udp", "legacy-reliable", "reliable"]}, "choices": ["udp", "legacy-reliable", "reliable"]},
"port": {"required": False, "type": "int"}, "port": {"required": False, "type": "int"},
"server": {"required": False, "type": "str"}, "server": {"required": False, "type": "str"},
"source-ip": {"required": False, "type": "str"}, "source_ip": {"required": False, "type": "str"},
"ssl_min_proto_version": {"required": False, "type": "str",
"choices": ["default", "SSLv3", "TLSv1",
"TLSv1-1", "TLSv1-2"]},
"status": {"required": False, "type": "str", "status": {"required": False, "type": "str",
"choices": ["enable", "disable"]} "choices": ["enable", "disable"]}
@ -361,15 +402,31 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos # legacy_mode refers to using fortiosapi instead of HTTPAPI
fos = FortiOSAPI() 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_log_syslogd3(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_log_syslogd3(module.params, fos) login(module.params, fos)
is_error, has_changed, result = fortios_log_syslogd3(module.params, fos)
fos.logout()
if not is_error: if not is_error:
module.exit_json(changed=has_changed, meta=result) 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 # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_log_syslogd4_filter module: fortios_log_syslogd4_filter
short_description: Filters for remote system server in Fortinet's FortiOS and FortiGate. short_description: Filters for remote system server in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by allowing the - This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify log_syslogd4 feature and filter category. user to set and modify log_syslogd4 feature and filter category.
Examples include all parameters and values need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,88 +41,109 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool type: bool
default: true default: true
version_added: 2.9
log_syslogd4_filter: log_syslogd4_filter:
description: description:
- Filters for remote system server. - Filters for remote system server.
default: null default: null
type: dict
suboptions: suboptions:
anomaly: anomaly:
description: description:
- Enable/disable anomaly logging. - Enable/disable anomaly logging.
type: str
choices: choices:
- enable - enable
- disable - disable
dns: dns:
description: description:
- Enable/disable detailed DNS event logging. - Enable/disable detailed DNS event logging.
type: str
choices: choices:
- enable - enable
- disable - disable
filter: filter:
description: description:
- Syslog 4 filter. - Syslog 4 filter.
filter-type: type: str
filter_type:
description: description:
- Include/exclude logs that match the filter. - Include/exclude logs that match the filter.
type: str
choices: choices:
- include - include
- exclude - exclude
forward-traffic: forward_traffic:
description: description:
- Enable/disable forward traffic logging. - Enable/disable forward traffic logging.
type: str
choices: choices:
- enable - enable
- disable - disable
gtp: gtp:
description: description:
- Enable/disable GTP messages logging. - Enable/disable GTP messages logging.
type: str
choices: choices:
- enable - enable
- disable - disable
local-traffic: local_traffic:
description: description:
- Enable/disable local in or out traffic logging. - Enable/disable local in or out traffic logging.
type: str
choices: choices:
- enable - enable
- disable - disable
multicast-traffic: multicast_traffic:
description: description:
- Enable/disable multicast traffic logging. - Enable/disable multicast traffic logging.
type: str
choices: choices:
- enable - enable
- disable - disable
netscan-discovery: netscan_discovery:
description: description:
- Enable/disable netscan discovery event logging. - Enable/disable netscan discovery event logging.
netscan-vulnerability: type: str
netscan_vulnerability:
description: description:
- Enable/disable netscan vulnerability event logging. - Enable/disable netscan vulnerability event logging.
type: str
severity: severity:
description: description:
- Lowest severity level to log. - Lowest severity level to log.
type: str
choices: choices:
- emergency - emergency
- alert - alert
@ -135,21 +153,24 @@ options:
- notification - notification
- information - information
- debug - debug
sniffer-traffic: sniffer_traffic:
description: description:
- Enable/disable sniffer traffic logging. - Enable/disable sniffer traffic logging.
type: str
choices: choices:
- enable - enable
- disable - disable
ssh: ssh:
description: description:
- Enable/disable SSH logging. - Enable/disable SSH logging.
type: str
choices: choices:
- enable - enable
- disable - disable
voip: voip:
description: description:
- Enable/disable VoIP logging. - Enable/disable VoIP logging.
type: str
choices: choices:
- enable - enable
- disable - disable
@ -162,6 +183,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Filters for remote system server. - name: Filters for remote system server.
fortios_log_syslogd4_filter: fortios_log_syslogd4_filter:
@ -174,15 +196,15 @@ EXAMPLES = '''
anomaly: "enable" anomaly: "enable"
dns: "enable" dns: "enable"
filter: "<your_own_value>" filter: "<your_own_value>"
filter-type: "include" filter_type: "include"
forward-traffic: "enable" forward_traffic: "enable"
gtp: "enable" gtp: "enable"
local-traffic: "enable" local_traffic: "enable"
multicast-traffic: "enable" multicast_traffic: "enable"
netscan-discovery: "<your_own_value>" netscan_discovery: "<your_own_value>"
netscan-vulnerability: "<your_own_value>" netscan_vulnerability: "<your_own_value>"
severity: "emergency" severity: "emergency"
sniffer-traffic: "enable" sniffer_traffic: "enable"
ssh: "enable" ssh: "enable"
voip: "enable" voip: "enable"
''' '''
@ -247,14 +269,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
fos = None 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'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -262,14 +286,14 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_log_syslogd4_filter_data(json): def filter_log_syslogd4_filter_data(json):
option_list = ['anomaly', 'dns', 'filter', option_list = ['anomaly', 'dns', 'filter',
'filter-type', 'forward-traffic', 'gtp', 'filter_type', 'forward_traffic', 'gtp',
'local-traffic', 'multicast-traffic', 'netscan-discovery', 'local_traffic', 'multicast_traffic', 'netscan_discovery',
'netscan-vulnerability', 'severity', 'sniffer-traffic', 'netscan_vulnerability', 'severity', 'sniffer_traffic',
'ssh', 'voip'] 'ssh', 'voip']
dictionary = {} dictionary = {}
@ -280,17 +304,15 @@ def filter_log_syslogd4_filter_data(json):
return dictionary return dictionary
def flatten_multilists_attributes(data): def underscore_to_hyphen(data):
multilist_attrs = [] if isinstance(data, list):
for elem in data:
for attr in multilist_attrs: elem = underscore_to_hyphen(elem)
try: elif isinstance(data, dict):
path = "data['" + "']['".join(elem for elem in attr) + "']" new_data = {}
current_val = eval(path) for k, v in data.items():
flattened_val = ' '.join(elem for elem in current_val) new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
exec(path + '= flattened_val') data = new_data
except BaseException:
pass
return data return data
@ -298,56 +320,62 @@ def flatten_multilists_attributes(data):
def log_syslogd4_filter(data, fos): def log_syslogd4_filter(data, fos):
vdom = data['vdom'] vdom = data['vdom']
log_syslogd4_filter_data = data['log_syslogd4_filter'] log_syslogd4_filter_data = data['log_syslogd4_filter']
flattened_data = flatten_multilists_attributes(log_syslogd4_filter_data) filtered_data = underscore_to_hyphen(filter_log_syslogd4_filter_data(log_syslogd4_filter_data))
filtered_data = filter_log_syslogd4_filter_data(flattened_data)
return fos.set('log.syslogd4', return fos.set('log.syslogd4',
'filter', 'filter',
data=filtered_data, data=filtered_data,
vdom=vdom) vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_log_syslogd4(data, fos): def fortios_log_syslogd4(data, fos):
login(data)
if data['log_syslogd4_filter']: if data['log_syslogd4_filter']:
resp = log_syslogd4_filter(data, fos) resp = log_syslogd4_filter(data, fos)
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True}, "https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"log_syslogd4_filter": { "log_syslogd4_filter": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"anomaly": {"required": False, "type": "str", "anomaly": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"dns": {"required": False, "type": "str", "dns": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"filter": {"required": False, "type": "str"}, "filter": {"required": False, "type": "str"},
"filter-type": {"required": False, "type": "str", "filter_type": {"required": False, "type": "str",
"choices": ["include", "exclude"]}, "choices": ["include", "exclude"]},
"forward-traffic": {"required": False, "type": "str", "forward_traffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"gtp": {"required": False, "type": "str", "gtp": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"local-traffic": {"required": False, "type": "str", "local_traffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"multicast-traffic": {"required": False, "type": "str", "multicast_traffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"netscan-discovery": {"required": False, "type": "str"}, "netscan_discovery": {"required": False, "type": "str"},
"netscan-vulnerability": {"required": False, "type": "str"}, "netscan_vulnerability": {"required": False, "type": "str"},
"severity": {"required": False, "type": "str", "severity": {"required": False, "type": "str",
"choices": ["emergency", "alert", "critical", "choices": ["emergency", "alert", "critical",
"error", "warning", "notification", "error", "warning", "notification",
"information", "debug"]}, "information", "debug"]},
"sniffer-traffic": {"required": False, "type": "str", "sniffer_traffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"ssh": {"required": False, "type": "str", "ssh": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
@ -360,15 +388,31 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos # legacy_mode refers to using fortiosapi instead of HTTPAPI
fos = FortiOSAPI() 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_log_syslogd4(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_log_syslogd4(module.params, fos) login(module.params, fos)
is_error, has_changed, result = fortios_log_syslogd4(module.params, fos)
fos.logout()
if not is_error: if not is_error:
module.exit_json(changed=has_changed, meta=result) 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 # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_log_syslogd4_setting module: fortios_log_syslogd4_setting
short_description: Global settings for remote syslog server in Fortinet's FortiOS and FortiGate. short_description: Global settings for remote syslog server in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by allowing the - This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify log_syslogd4 feature and setting category. user to set and modify log_syslogd4 feature and setting category.
Examples include all parameters and values need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,54 +41,70 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool type: bool
default: true default: true
version_added: 2.9
log_syslogd4_setting: log_syslogd4_setting:
description: description:
- Global settings for remote syslog server. - Global settings for remote syslog server.
default: null default: null
type: dict
suboptions: suboptions:
certificate: certificate:
description: description:
- Certificate used to communicate with Syslog server. Source certificate.local.name. - Certificate used to communicate with Syslog server. Source certificate.local.name.
custom-field-name: type: str
custom_field_name:
description: description:
- Custom field name for CEF format logging. - Custom field name for CEF format logging.
type: list
suboptions: suboptions:
custom: custom:
description: description:
- Field custom name. - Field custom name.
type: str
id: id:
description: description:
- Entry ID. - Entry ID.
required: true required: true
type: int
name: name:
description: description:
- Field name. - Field name.
enc-algorithm: type: str
enc_algorithm:
description: description:
- Enable/disable reliable syslogging with TLS encryption. - Enable/disable reliable syslogging with TLS encryption.
type: str
choices: choices:
- high-medium - high-medium
- high - high
@ -100,6 +113,7 @@ options:
facility: facility:
description: description:
- Remote syslog facility. - Remote syslog facility.
type: str
choices: choices:
- kernel - kernel
- user - user
@ -128,6 +142,7 @@ options:
format: format:
description: description:
- Log format. - Log format.
type: str
choices: choices:
- default - default
- csv - csv
@ -135,6 +150,7 @@ options:
mode: mode:
description: description:
- Remote syslog logging over UDP/Reliable TCP. - Remote syslog logging over UDP/Reliable TCP.
type: str
choices: choices:
- udp - udp
- legacy-reliable - legacy-reliable
@ -142,15 +158,29 @@ options:
port: port:
description: description:
- Server listen port. - Server listen port.
type: int
server: server:
description: description:
- Address of remote syslog server. - Address of remote syslog server.
source-ip: type: str
source_ip:
description: description:
- Source IP address of syslog. - Source IP address of syslog.
type: str
ssl_min_proto_version:
description:
- Minimum supported protocol version for SSL/TLS connections .
type: str
choices:
- default
- SSLv3
- TLSv1
- TLSv1-1
- TLSv1-2
status: status:
description: description:
- Enable/disable remote syslog logging. - Enable/disable remote syslog logging.
type: str
choices: choices:
- enable - enable
- disable - disable
@ -163,6 +193,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Global settings for remote syslog server. - name: Global settings for remote syslog server.
fortios_log_syslogd4_setting: fortios_log_syslogd4_setting:
@ -173,18 +204,19 @@ EXAMPLES = '''
https: "False" https: "False"
log_syslogd4_setting: log_syslogd4_setting:
certificate: "<your_own_value> (source certificate.local.name)" certificate: "<your_own_value> (source certificate.local.name)"
custom-field-name: custom_field_name:
- -
custom: "<your_own_value>" custom: "<your_own_value>"
id: "6" id: "6"
name: "default_name_7" name: "default_name_7"
enc-algorithm: "high-medium" enc_algorithm: "high-medium"
facility: "kernel" facility: "kernel"
format: "default" format: "default"
mode: "udp" mode: "udp"
port: "12" port: "12"
server: "192.168.100.40" server: "192.168.100.40"
source-ip: "84.230.14.43" source_ip: "84.230.14.43"
ssl_min_proto_version: "default"
status: "enable" status: "enable"
''' '''
@ -248,14 +280,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule 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, fos):
def login(data):
host = data['host'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -263,14 +297,14 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_log_syslogd4_setting_data(json): def filter_log_syslogd4_setting_data(json):
option_list = ['certificate', 'custom-field-name', 'enc-algorithm', option_list = ['certificate', 'custom_field_name', 'enc_algorithm',
'facility', 'format', 'mode', 'facility', 'format', 'mode',
'port', 'server', 'source-ip', 'port', 'server', 'source_ip',
'status'] 'ssl_min_proto_version', 'status']
dictionary = {} dictionary = {}
for attribute in option_list: for attribute in option_list:
@ -280,17 +314,15 @@ def filter_log_syslogd4_setting_data(json):
return dictionary return dictionary
def flatten_multilists_attributes(data): def underscore_to_hyphen(data):
multilist_attrs = [] if isinstance(data, list):
for elem in data:
for attr in multilist_attrs: elem = underscore_to_hyphen(elem)
try: elif isinstance(data, dict):
path = "data['" + "']['".join(elem for elem in attr) + "']" new_data = {}
current_val = eval(path) for k, v in data.items():
flattened_val = ' '.join(elem for elem in current_val) new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
exec(path + '= flattened_val') data = new_data
except BaseException:
pass
return data return data
@ -298,42 +330,48 @@ def flatten_multilists_attributes(data):
def log_syslogd4_setting(data, fos): def log_syslogd4_setting(data, fos):
vdom = data['vdom'] vdom = data['vdom']
log_syslogd4_setting_data = data['log_syslogd4_setting'] log_syslogd4_setting_data = data['log_syslogd4_setting']
flattened_data = flatten_multilists_attributes(log_syslogd4_setting_data) filtered_data = underscore_to_hyphen(filter_log_syslogd4_setting_data(log_syslogd4_setting_data))
filtered_data = filter_log_syslogd4_setting_data(flattened_data)
return fos.set('log.syslogd4', return fos.set('log.syslogd4',
'setting', 'setting',
data=filtered_data, data=filtered_data,
vdom=vdom) vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_log_syslogd4(data, fos): def fortios_log_syslogd4(data, fos):
login(data)
if data['log_syslogd4_setting']: if data['log_syslogd4_setting']:
resp = log_syslogd4_setting(data, fos) resp = log_syslogd4_setting(data, fos)
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True}, "https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"log_syslogd4_setting": { "log_syslogd4_setting": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"certificate": {"required": False, "type": "str"}, "certificate": {"required": False, "type": "str"},
"custom-field-name": {"required": False, "type": "list", "custom_field_name": {"required": False, "type": "list",
"options": { "options": {
"custom": {"required": False, "type": "str"}, "custom": {"required": False, "type": "str"},
"id": {"required": True, "type": "int"}, "id": {"required": True, "type": "int"},
"name": {"required": False, "type": "str"} "name": {"required": False, "type": "str"}
}}, }},
"enc-algorithm": {"required": False, "type": "str", "enc_algorithm": {"required": False, "type": "str",
"choices": ["high-medium", "high", "low", "choices": ["high-medium", "high", "low",
"disable"]}, "disable"]},
"facility": {"required": False, "type": "str", "facility": {"required": False, "type": "str",
@ -351,7 +389,10 @@ def main():
"choices": ["udp", "legacy-reliable", "reliable"]}, "choices": ["udp", "legacy-reliable", "reliable"]},
"port": {"required": False, "type": "int"}, "port": {"required": False, "type": "int"},
"server": {"required": False, "type": "str"}, "server": {"required": False, "type": "str"},
"source-ip": {"required": False, "type": "str"}, "source_ip": {"required": False, "type": "str"},
"ssl_min_proto_version": {"required": False, "type": "str",
"choices": ["default", "SSLv3", "TLSv1",
"TLSv1-1", "TLSv1-2"]},
"status": {"required": False, "type": "str", "status": {"required": False, "type": "str",
"choices": ["enable", "disable"]} "choices": ["enable", "disable"]}
@ -361,15 +402,31 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos # legacy_mode refers to using fortiosapi instead of HTTPAPI
fos = FortiOSAPI() 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_log_syslogd4(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_log_syslogd4(module.params, fos) login(module.params, fos)
is_error, has_changed, result = fortios_log_syslogd4(module.params, fos)
fos.logout()
if not is_error: if not is_error:
module.exit_json(changed=has_changed, meta=result) 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 # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_log_syslogd_filter module: fortios_log_syslogd_filter
short_description: Filters for remote system server in Fortinet's FortiOS and FortiGate. short_description: Filters for remote system server in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by allowing the - This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify log_syslogd feature and filter category. user to set and modify log_syslogd feature and filter category.
Examples include all parameters and values need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,88 +41,109 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool type: bool
default: true default: true
version_added: 2.9
log_syslogd_filter: log_syslogd_filter:
description: description:
- Filters for remote system server. - Filters for remote system server.
default: null default: null
type: dict
suboptions: suboptions:
anomaly: anomaly:
description: description:
- Enable/disable anomaly logging. - Enable/disable anomaly logging.
type: str
choices: choices:
- enable - enable
- disable - disable
dns: dns:
description: description:
- Enable/disable detailed DNS event logging. - Enable/disable detailed DNS event logging.
type: str
choices: choices:
- enable - enable
- disable - disable
filter: filter:
description: description:
- Syslog filter. - Syslog filter.
filter-type: type: str
filter_type:
description: description:
- Include/exclude logs that match the filter. - Include/exclude logs that match the filter.
type: str
choices: choices:
- include - include
- exclude - exclude
forward-traffic: forward_traffic:
description: description:
- Enable/disable forward traffic logging. - Enable/disable forward traffic logging.
type: str
choices: choices:
- enable - enable
- disable - disable
gtp: gtp:
description: description:
- Enable/disable GTP messages logging. - Enable/disable GTP messages logging.
type: str
choices: choices:
- enable - enable
- disable - disable
local-traffic: local_traffic:
description: description:
- Enable/disable local in or out traffic logging. - Enable/disable local in or out traffic logging.
type: str
choices: choices:
- enable - enable
- disable - disable
multicast-traffic: multicast_traffic:
description: description:
- Enable/disable multicast traffic logging. - Enable/disable multicast traffic logging.
type: str
choices: choices:
- enable - enable
- disable - disable
netscan-discovery: netscan_discovery:
description: description:
- Enable/disable netscan discovery event logging. - Enable/disable netscan discovery event logging.
netscan-vulnerability: type: str
netscan_vulnerability:
description: description:
- Enable/disable netscan vulnerability event logging. - Enable/disable netscan vulnerability event logging.
type: str
severity: severity:
description: description:
- Lowest severity level to log. - Lowest severity level to log.
type: str
choices: choices:
- emergency - emergency
- alert - alert
@ -135,21 +153,24 @@ options:
- notification - notification
- information - information
- debug - debug
sniffer-traffic: sniffer_traffic:
description: description:
- Enable/disable sniffer traffic logging. - Enable/disable sniffer traffic logging.
type: str
choices: choices:
- enable - enable
- disable - disable
ssh: ssh:
description: description:
- Enable/disable SSH logging. - Enable/disable SSH logging.
type: str
choices: choices:
- enable - enable
- disable - disable
voip: voip:
description: description:
- Enable/disable VoIP logging. - Enable/disable VoIP logging.
type: str
choices: choices:
- enable - enable
- disable - disable
@ -162,6 +183,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Filters for remote system server. - name: Filters for remote system server.
fortios_log_syslogd_filter: fortios_log_syslogd_filter:
@ -174,15 +196,15 @@ EXAMPLES = '''
anomaly: "enable" anomaly: "enable"
dns: "enable" dns: "enable"
filter: "<your_own_value>" filter: "<your_own_value>"
filter-type: "include" filter_type: "include"
forward-traffic: "enable" forward_traffic: "enable"
gtp: "enable" gtp: "enable"
local-traffic: "enable" local_traffic: "enable"
multicast-traffic: "enable" multicast_traffic: "enable"
netscan-discovery: "<your_own_value>" netscan_discovery: "<your_own_value>"
netscan-vulnerability: "<your_own_value>" netscan_vulnerability: "<your_own_value>"
severity: "emergency" severity: "emergency"
sniffer-traffic: "enable" sniffer_traffic: "enable"
ssh: "enable" ssh: "enable"
voip: "enable" voip: "enable"
''' '''
@ -247,14 +269,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
fos = None 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'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -262,14 +286,14 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_log_syslogd_filter_data(json): def filter_log_syslogd_filter_data(json):
option_list = ['anomaly', 'dns', 'filter', option_list = ['anomaly', 'dns', 'filter',
'filter-type', 'forward-traffic', 'gtp', 'filter_type', 'forward_traffic', 'gtp',
'local-traffic', 'multicast-traffic', 'netscan-discovery', 'local_traffic', 'multicast_traffic', 'netscan_discovery',
'netscan-vulnerability', 'severity', 'sniffer-traffic', 'netscan_vulnerability', 'severity', 'sniffer_traffic',
'ssh', 'voip'] 'ssh', 'voip']
dictionary = {} dictionary = {}
@ -280,17 +304,15 @@ def filter_log_syslogd_filter_data(json):
return dictionary return dictionary
def flatten_multilists_attributes(data): def underscore_to_hyphen(data):
multilist_attrs = [] if isinstance(data, list):
for elem in data:
for attr in multilist_attrs: elem = underscore_to_hyphen(elem)
try: elif isinstance(data, dict):
path = "data['" + "']['".join(elem for elem in attr) + "']" new_data = {}
current_val = eval(path) for k, v in data.items():
flattened_val = ' '.join(elem for elem in current_val) new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
exec(path + '= flattened_val') data = new_data
except BaseException:
pass
return data return data
@ -298,56 +320,62 @@ def flatten_multilists_attributes(data):
def log_syslogd_filter(data, fos): def log_syslogd_filter(data, fos):
vdom = data['vdom'] vdom = data['vdom']
log_syslogd_filter_data = data['log_syslogd_filter'] log_syslogd_filter_data = data['log_syslogd_filter']
flattened_data = flatten_multilists_attributes(log_syslogd_filter_data) filtered_data = underscore_to_hyphen(filter_log_syslogd_filter_data(log_syslogd_filter_data))
filtered_data = filter_log_syslogd_filter_data(flattened_data)
return fos.set('log.syslogd', return fos.set('log.syslogd',
'filter', 'filter',
data=filtered_data, data=filtered_data,
vdom=vdom) vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_log_syslogd(data, fos): def fortios_log_syslogd(data, fos):
login(data)
if data['log_syslogd_filter']: if data['log_syslogd_filter']:
resp = log_syslogd_filter(data, fos) resp = log_syslogd_filter(data, fos)
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True}, "https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"log_syslogd_filter": { "log_syslogd_filter": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"anomaly": {"required": False, "type": "str", "anomaly": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"dns": {"required": False, "type": "str", "dns": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"filter": {"required": False, "type": "str"}, "filter": {"required": False, "type": "str"},
"filter-type": {"required": False, "type": "str", "filter_type": {"required": False, "type": "str",
"choices": ["include", "exclude"]}, "choices": ["include", "exclude"]},
"forward-traffic": {"required": False, "type": "str", "forward_traffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"gtp": {"required": False, "type": "str", "gtp": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"local-traffic": {"required": False, "type": "str", "local_traffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"multicast-traffic": {"required": False, "type": "str", "multicast_traffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"netscan-discovery": {"required": False, "type": "str"}, "netscan_discovery": {"required": False, "type": "str"},
"netscan-vulnerability": {"required": False, "type": "str"}, "netscan_vulnerability": {"required": False, "type": "str"},
"severity": {"required": False, "type": "str", "severity": {"required": False, "type": "str",
"choices": ["emergency", "alert", "critical", "choices": ["emergency", "alert", "critical",
"error", "warning", "notification", "error", "warning", "notification",
"information", "debug"]}, "information", "debug"]},
"sniffer-traffic": {"required": False, "type": "str", "sniffer_traffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"ssh": {"required": False, "type": "str", "ssh": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
@ -360,15 +388,31 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos # legacy_mode refers to using fortiosapi instead of HTTPAPI
fos = FortiOSAPI() 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_log_syslogd(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_log_syslogd(module.params, fos) login(module.params, fos)
is_error, has_changed, result = fortios_log_syslogd(module.params, fos)
fos.logout()
if not is_error: if not is_error:
module.exit_json(changed=has_changed, meta=result) 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 # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_log_syslogd_override_filter module: fortios_log_syslogd_override_filter
short_description: Override filters for remote system server in Fortinet's FortiOS and FortiGate. short_description: Override filters for remote system server in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by allowing the - This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify log_syslogd feature and override_filter category. user to set and modify log_syslogd feature and override_filter category.
Examples include all parameters and values need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,88 +41,109 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool type: bool
default: true default: true
version_added: 2.9
log_syslogd_override_filter: log_syslogd_override_filter:
description: description:
- Override filters for remote system server. - Override filters for remote system server.
default: null default: null
type: dict
suboptions: suboptions:
anomaly: anomaly:
description: description:
- Enable/disable anomaly logging. - Enable/disable anomaly logging.
type: str
choices: choices:
- enable - enable
- disable - disable
dns: dns:
description: description:
- Enable/disable detailed DNS event logging. - Enable/disable detailed DNS event logging.
type: str
choices: choices:
- enable - enable
- disable - disable
filter: filter:
description: description:
- Syslog filter. - Syslog filter.
filter-type: type: str
filter_type:
description: description:
- Include/exclude logs that match the filter. - Include/exclude logs that match the filter.
type: str
choices: choices:
- include - include
- exclude - exclude
forward-traffic: forward_traffic:
description: description:
- Enable/disable forward traffic logging. - Enable/disable forward traffic logging.
type: str
choices: choices:
- enable - enable
- disable - disable
gtp: gtp:
description: description:
- Enable/disable GTP messages logging. - Enable/disable GTP messages logging.
type: str
choices: choices:
- enable - enable
- disable - disable
local-traffic: local_traffic:
description: description:
- Enable/disable local in or out traffic logging. - Enable/disable local in or out traffic logging.
type: str
choices: choices:
- enable - enable
- disable - disable
multicast-traffic: multicast_traffic:
description: description:
- Enable/disable multicast traffic logging. - Enable/disable multicast traffic logging.
type: str
choices: choices:
- enable - enable
- disable - disable
netscan-discovery: netscan_discovery:
description: description:
- Enable/disable netscan discovery event logging. - Enable/disable netscan discovery event logging.
netscan-vulnerability: type: str
netscan_vulnerability:
description: description:
- Enable/disable netscan vulnerability event logging. - Enable/disable netscan vulnerability event logging.
type: str
severity: severity:
description: description:
- Lowest severity level to log. - Lowest severity level to log.
type: str
choices: choices:
- emergency - emergency
- alert - alert
@ -135,21 +153,24 @@ options:
- notification - notification
- information - information
- debug - debug
sniffer-traffic: sniffer_traffic:
description: description:
- Enable/disable sniffer traffic logging. - Enable/disable sniffer traffic logging.
type: str
choices: choices:
- enable - enable
- disable - disable
ssh: ssh:
description: description:
- Enable/disable SSH logging. - Enable/disable SSH logging.
type: str
choices: choices:
- enable - enable
- disable - disable
voip: voip:
description: description:
- Enable/disable VoIP logging. - Enable/disable VoIP logging.
type: str
choices: choices:
- enable - enable
- disable - disable
@ -162,6 +183,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Override filters for remote system server. - name: Override filters for remote system server.
fortios_log_syslogd_override_filter: fortios_log_syslogd_override_filter:
@ -174,15 +196,15 @@ EXAMPLES = '''
anomaly: "enable" anomaly: "enable"
dns: "enable" dns: "enable"
filter: "<your_own_value>" filter: "<your_own_value>"
filter-type: "include" filter_type: "include"
forward-traffic: "enable" forward_traffic: "enable"
gtp: "enable" gtp: "enable"
local-traffic: "enable" local_traffic: "enable"
multicast-traffic: "enable" multicast_traffic: "enable"
netscan-discovery: "<your_own_value>" netscan_discovery: "<your_own_value>"
netscan-vulnerability: "<your_own_value>" netscan_vulnerability: "<your_own_value>"
severity: "emergency" severity: "emergency"
sniffer-traffic: "enable" sniffer_traffic: "enable"
ssh: "enable" ssh: "enable"
voip: "enable" voip: "enable"
''' '''
@ -247,14 +269,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
fos = None 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'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -262,14 +286,14 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_log_syslogd_override_filter_data(json): def filter_log_syslogd_override_filter_data(json):
option_list = ['anomaly', 'dns', 'filter', option_list = ['anomaly', 'dns', 'filter',
'filter-type', 'forward-traffic', 'gtp', 'filter_type', 'forward_traffic', 'gtp',
'local-traffic', 'multicast-traffic', 'netscan-discovery', 'local_traffic', 'multicast_traffic', 'netscan_discovery',
'netscan-vulnerability', 'severity', 'sniffer-traffic', 'netscan_vulnerability', 'severity', 'sniffer_traffic',
'ssh', 'voip'] 'ssh', 'voip']
dictionary = {} dictionary = {}
@ -280,17 +304,15 @@ def filter_log_syslogd_override_filter_data(json):
return dictionary return dictionary
def flatten_multilists_attributes(data): def underscore_to_hyphen(data):
multilist_attrs = [] if isinstance(data, list):
for elem in data:
for attr in multilist_attrs: elem = underscore_to_hyphen(elem)
try: elif isinstance(data, dict):
path = "data['" + "']['".join(elem for elem in attr) + "']" new_data = {}
current_val = eval(path) for k, v in data.items():
flattened_val = ' '.join(elem for elem in current_val) new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
exec(path + '= flattened_val') data = new_data
except BaseException:
pass
return data return data
@ -298,56 +320,62 @@ def flatten_multilists_attributes(data):
def log_syslogd_override_filter(data, fos): def log_syslogd_override_filter(data, fos):
vdom = data['vdom'] vdom = data['vdom']
log_syslogd_override_filter_data = data['log_syslogd_override_filter'] log_syslogd_override_filter_data = data['log_syslogd_override_filter']
flattened_data = flatten_multilists_attributes(log_syslogd_override_filter_data) filtered_data = underscore_to_hyphen(filter_log_syslogd_override_filter_data(log_syslogd_override_filter_data))
filtered_data = filter_log_syslogd_override_filter_data(flattened_data)
return fos.set('log.syslogd', return fos.set('log.syslogd',
'override-filter', 'override-filter',
data=filtered_data, data=filtered_data,
vdom=vdom) vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_log_syslogd(data, fos): def fortios_log_syslogd(data, fos):
login(data)
if data['log_syslogd_override_filter']: if data['log_syslogd_override_filter']:
resp = log_syslogd_override_filter(data, fos) resp = log_syslogd_override_filter(data, fos)
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True}, "https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"log_syslogd_override_filter": { "log_syslogd_override_filter": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"anomaly": {"required": False, "type": "str", "anomaly": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"dns": {"required": False, "type": "str", "dns": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"filter": {"required": False, "type": "str"}, "filter": {"required": False, "type": "str"},
"filter-type": {"required": False, "type": "str", "filter_type": {"required": False, "type": "str",
"choices": ["include", "exclude"]}, "choices": ["include", "exclude"]},
"forward-traffic": {"required": False, "type": "str", "forward_traffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"gtp": {"required": False, "type": "str", "gtp": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"local-traffic": {"required": False, "type": "str", "local_traffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"multicast-traffic": {"required": False, "type": "str", "multicast_traffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"netscan-discovery": {"required": False, "type": "str"}, "netscan_discovery": {"required": False, "type": "str"},
"netscan-vulnerability": {"required": False, "type": "str"}, "netscan_vulnerability": {"required": False, "type": "str"},
"severity": {"required": False, "type": "str", "severity": {"required": False, "type": "str",
"choices": ["emergency", "alert", "critical", "choices": ["emergency", "alert", "critical",
"error", "warning", "notification", "error", "warning", "notification",
"information", "debug"]}, "information", "debug"]},
"sniffer-traffic": {"required": False, "type": "str", "sniffer_traffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"ssh": {"required": False, "type": "str", "ssh": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
@ -360,15 +388,31 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos # legacy_mode refers to using fortiosapi instead of HTTPAPI
fos = FortiOSAPI() 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_log_syslogd(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_log_syslogd(module.params, fos) login(module.params, fos)
is_error, has_changed, result = fortios_log_syslogd(module.params, fos)
fos.logout()
if not is_error: if not is_error:
module.exit_json(changed=has_changed, meta=result) 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 # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_log_syslogd_override_setting module: fortios_log_syslogd_override_setting
short_description: Override settings for remote syslog server in Fortinet's FortiOS and FortiGate. short_description: Override settings for remote syslog server in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by allowing the - This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify log_syslogd feature and override_setting category. user to set and modify log_syslogd feature and override_setting category.
Examples include all parameters and values need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,54 +41,70 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool type: bool
default: true default: true
version_added: 2.9
log_syslogd_override_setting: log_syslogd_override_setting:
description: description:
- Override settings for remote syslog server. - Override settings for remote syslog server.
default: null default: null
type: dict
suboptions: suboptions:
certificate: certificate:
description: description:
- Certificate used to communicate with Syslog server. Source certificate.local.name. - Certificate used to communicate with Syslog server. Source certificate.local.name.
custom-field-name: type: str
custom_field_name:
description: description:
- Custom field name for CEF format logging. - Custom field name for CEF format logging.
type: list
suboptions: suboptions:
custom: custom:
description: description:
- Field custom name. - Field custom name.
type: str
id: id:
description: description:
- Entry ID. - Entry ID.
required: true required: true
type: int
name: name:
description: description:
- Field name. - Field name.
enc-algorithm: type: str
enc_algorithm:
description: description:
- Enable/disable reliable syslogging with TLS encryption. - Enable/disable reliable syslogging with TLS encryption.
type: str
choices: choices:
- high-medium - high-medium
- high - high
@ -100,6 +113,7 @@ options:
facility: facility:
description: description:
- Remote syslog facility. - Remote syslog facility.
type: str
choices: choices:
- kernel - kernel
- user - user
@ -128,6 +142,7 @@ options:
format: format:
description: description:
- Log format. - Log format.
type: str
choices: choices:
- default - default
- csv - csv
@ -135,6 +150,7 @@ options:
mode: mode:
description: description:
- Remote syslog logging over UDP/Reliable TCP. - Remote syslog logging over UDP/Reliable TCP.
type: str
choices: choices:
- udp - udp
- legacy-reliable - legacy-reliable
@ -142,21 +158,36 @@ options:
override: override:
description: description:
- Enable/disable override syslog settings. - Enable/disable override syslog settings.
type: str
choices: choices:
- enable - enable
- disable - disable
port: port:
description: description:
- Server listen port. - Server listen port.
type: int
server: server:
description: description:
- Address of remote syslog server. - Address of remote syslog server.
source-ip: type: str
source_ip:
description: description:
- Source IP address of syslog. - Source IP address of syslog.
type: str
ssl_min_proto_version:
description:
- Minimum supported protocol version for SSL/TLS connections .
type: str
choices:
- default
- SSLv3
- TLSv1
- TLSv1-1
- TLSv1-2
status: status:
description: description:
- Enable/disable remote syslog logging. - Enable/disable remote syslog logging.
type: str
choices: choices:
- enable - enable
- disable - disable
@ -169,6 +200,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Override settings for remote syslog server. - name: Override settings for remote syslog server.
fortios_log_syslogd_override_setting: fortios_log_syslogd_override_setting:
@ -179,19 +211,20 @@ EXAMPLES = '''
https: "False" https: "False"
log_syslogd_override_setting: log_syslogd_override_setting:
certificate: "<your_own_value> (source certificate.local.name)" certificate: "<your_own_value> (source certificate.local.name)"
custom-field-name: custom_field_name:
- -
custom: "<your_own_value>" custom: "<your_own_value>"
id: "6" id: "6"
name: "default_name_7" name: "default_name_7"
enc-algorithm: "high-medium" enc_algorithm: "high-medium"
facility: "kernel" facility: "kernel"
format: "default" format: "default"
mode: "udp" mode: "udp"
override: "enable" override: "enable"
port: "13" port: "13"
server: "192.168.100.40" server: "192.168.100.40"
source-ip: "84.230.14.43" source_ip: "84.230.14.43"
ssl_min_proto_version: "default"
status: "enable" status: "enable"
''' '''
@ -255,14 +288,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule 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, fos):
def login(data):
host = data['host'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -270,14 +305,14 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_log_syslogd_override_setting_data(json): def filter_log_syslogd_override_setting_data(json):
option_list = ['certificate', 'custom-field-name', 'enc-algorithm', option_list = ['certificate', 'custom_field_name', 'enc_algorithm',
'facility', 'format', 'mode', 'facility', 'format', 'mode',
'override', 'port', 'server', 'override', 'port', 'server',
'source-ip', 'status'] 'source_ip', 'ssl_min_proto_version', 'status']
dictionary = {} dictionary = {}
for attribute in option_list: for attribute in option_list:
@ -287,17 +322,15 @@ def filter_log_syslogd_override_setting_data(json):
return dictionary return dictionary
def flatten_multilists_attributes(data): def underscore_to_hyphen(data):
multilist_attrs = [] if isinstance(data, list):
for elem in data:
for attr in multilist_attrs: elem = underscore_to_hyphen(elem)
try: elif isinstance(data, dict):
path = "data['" + "']['".join(elem for elem in attr) + "']" new_data = {}
current_val = eval(path) for k, v in data.items():
flattened_val = ' '.join(elem for elem in current_val) new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
exec(path + '= flattened_val') data = new_data
except BaseException:
pass
return data return data
@ -305,42 +338,48 @@ def flatten_multilists_attributes(data):
def log_syslogd_override_setting(data, fos): def log_syslogd_override_setting(data, fos):
vdom = data['vdom'] vdom = data['vdom']
log_syslogd_override_setting_data = data['log_syslogd_override_setting'] log_syslogd_override_setting_data = data['log_syslogd_override_setting']
flattened_data = flatten_multilists_attributes(log_syslogd_override_setting_data) filtered_data = underscore_to_hyphen(filter_log_syslogd_override_setting_data(log_syslogd_override_setting_data))
filtered_data = filter_log_syslogd_override_setting_data(flattened_data)
return fos.set('log.syslogd', return fos.set('log.syslogd',
'override-setting', 'override-setting',
data=filtered_data, data=filtered_data,
vdom=vdom) vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_log_syslogd(data, fos): def fortios_log_syslogd(data, fos):
login(data)
if data['log_syslogd_override_setting']: if data['log_syslogd_override_setting']:
resp = log_syslogd_override_setting(data, fos) resp = log_syslogd_override_setting(data, fos)
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True}, "https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"log_syslogd_override_setting": { "log_syslogd_override_setting": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"certificate": {"required": False, "type": "str"}, "certificate": {"required": False, "type": "str"},
"custom-field-name": {"required": False, "type": "list", "custom_field_name": {"required": False, "type": "list",
"options": { "options": {
"custom": {"required": False, "type": "str"}, "custom": {"required": False, "type": "str"},
"id": {"required": True, "type": "int"}, "id": {"required": True, "type": "int"},
"name": {"required": False, "type": "str"} "name": {"required": False, "type": "str"}
}}, }},
"enc-algorithm": {"required": False, "type": "str", "enc_algorithm": {"required": False, "type": "str",
"choices": ["high-medium", "high", "low", "choices": ["high-medium", "high", "low",
"disable"]}, "disable"]},
"facility": {"required": False, "type": "str", "facility": {"required": False, "type": "str",
@ -360,7 +399,10 @@ def main():
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"port": {"required": False, "type": "int"}, "port": {"required": False, "type": "int"},
"server": {"required": False, "type": "str"}, "server": {"required": False, "type": "str"},
"source-ip": {"required": False, "type": "str"}, "source_ip": {"required": False, "type": "str"},
"ssl_min_proto_version": {"required": False, "type": "str",
"choices": ["default", "SSLv3", "TLSv1",
"TLSv1-1", "TLSv1-2"]},
"status": {"required": False, "type": "str", "status": {"required": False, "type": "str",
"choices": ["enable", "disable"]} "choices": ["enable", "disable"]}
@ -370,15 +412,31 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos # legacy_mode refers to using fortiosapi instead of HTTPAPI
fos = FortiOSAPI() 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_log_syslogd(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_log_syslogd(module.params, fos) login(module.params, fos)
is_error, has_changed, result = fortios_log_syslogd(module.params, fos)
fos.logout()
if not is_error: if not is_error:
module.exit_json(changed=has_changed, meta=result) 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 # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_log_syslogd_setting module: fortios_log_syslogd_setting
short_description: Global settings for remote syslog server in Fortinet's FortiOS and FortiGate. short_description: Global settings for remote syslog server in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by allowing the - This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify log_syslogd feature and setting category. user to set and modify log_syslogd feature and setting category.
Examples include all parameters and values need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,54 +41,70 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool type: bool
default: true default: true
version_added: 2.9
log_syslogd_setting: log_syslogd_setting:
description: description:
- Global settings for remote syslog server. - Global settings for remote syslog server.
default: null default: null
type: dict
suboptions: suboptions:
certificate: certificate:
description: description:
- Certificate used to communicate with Syslog server. Source certificate.local.name. - Certificate used to communicate with Syslog server. Source certificate.local.name.
custom-field-name: type: str
custom_field_name:
description: description:
- Custom field name for CEF format logging. - Custom field name for CEF format logging.
type: list
suboptions: suboptions:
custom: custom:
description: description:
- Field custom name. - Field custom name.
type: str
id: id:
description: description:
- Entry ID. - Entry ID.
required: true required: true
type: int
name: name:
description: description:
- Field name. - Field name.
enc-algorithm: type: str
enc_algorithm:
description: description:
- Enable/disable reliable syslogging with TLS encryption. - Enable/disable reliable syslogging with TLS encryption.
type: str
choices: choices:
- high-medium - high-medium
- high - high
@ -100,6 +113,7 @@ options:
facility: facility:
description: description:
- Remote syslog facility. - Remote syslog facility.
type: str
choices: choices:
- kernel - kernel
- user - user
@ -128,6 +142,7 @@ options:
format: format:
description: description:
- Log format. - Log format.
type: str
choices: choices:
- default - default
- csv - csv
@ -135,6 +150,7 @@ options:
mode: mode:
description: description:
- Remote syslog logging over UDP/Reliable TCP. - Remote syslog logging over UDP/Reliable TCP.
type: str
choices: choices:
- udp - udp
- legacy-reliable - legacy-reliable
@ -142,15 +158,29 @@ options:
port: port:
description: description:
- Server listen port. - Server listen port.
type: int
server: server:
description: description:
- Address of remote syslog server. - Address of remote syslog server.
source-ip: type: str
source_ip:
description: description:
- Source IP address of syslog. - Source IP address of syslog.
type: str
ssl_min_proto_version:
description:
- Minimum supported protocol version for SSL/TLS connections .
type: str
choices:
- default
- SSLv3
- TLSv1
- TLSv1-1
- TLSv1-2
status: status:
description: description:
- Enable/disable remote syslog logging. - Enable/disable remote syslog logging.
type: str
choices: choices:
- enable - enable
- disable - disable
@ -163,6 +193,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Global settings for remote syslog server. - name: Global settings for remote syslog server.
fortios_log_syslogd_setting: fortios_log_syslogd_setting:
@ -173,18 +204,19 @@ EXAMPLES = '''
https: "False" https: "False"
log_syslogd_setting: log_syslogd_setting:
certificate: "<your_own_value> (source certificate.local.name)" certificate: "<your_own_value> (source certificate.local.name)"
custom-field-name: custom_field_name:
- -
custom: "<your_own_value>" custom: "<your_own_value>"
id: "6" id: "6"
name: "default_name_7" name: "default_name_7"
enc-algorithm: "high-medium" enc_algorithm: "high-medium"
facility: "kernel" facility: "kernel"
format: "default" format: "default"
mode: "udp" mode: "udp"
port: "12" port: "12"
server: "192.168.100.40" server: "192.168.100.40"
source-ip: "84.230.14.43" source_ip: "84.230.14.43"
ssl_min_proto_version: "default"
status: "enable" status: "enable"
''' '''
@ -248,14 +280,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule 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, fos):
def login(data):
host = data['host'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -263,14 +297,14 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_log_syslogd_setting_data(json): def filter_log_syslogd_setting_data(json):
option_list = ['certificate', 'custom-field-name', 'enc-algorithm', option_list = ['certificate', 'custom_field_name', 'enc_algorithm',
'facility', 'format', 'mode', 'facility', 'format', 'mode',
'port', 'server', 'source-ip', 'port', 'server', 'source_ip',
'status'] 'ssl_min_proto_version', 'status']
dictionary = {} dictionary = {}
for attribute in option_list: for attribute in option_list:
@ -280,17 +314,15 @@ def filter_log_syslogd_setting_data(json):
return dictionary return dictionary
def flatten_multilists_attributes(data): def underscore_to_hyphen(data):
multilist_attrs = [] if isinstance(data, list):
for elem in data:
for attr in multilist_attrs: elem = underscore_to_hyphen(elem)
try: elif isinstance(data, dict):
path = "data['" + "']['".join(elem for elem in attr) + "']" new_data = {}
current_val = eval(path) for k, v in data.items():
flattened_val = ' '.join(elem for elem in current_val) new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
exec(path + '= flattened_val') data = new_data
except BaseException:
pass
return data return data
@ -298,42 +330,48 @@ def flatten_multilists_attributes(data):
def log_syslogd_setting(data, fos): def log_syslogd_setting(data, fos):
vdom = data['vdom'] vdom = data['vdom']
log_syslogd_setting_data = data['log_syslogd_setting'] log_syslogd_setting_data = data['log_syslogd_setting']
flattened_data = flatten_multilists_attributes(log_syslogd_setting_data) filtered_data = underscore_to_hyphen(filter_log_syslogd_setting_data(log_syslogd_setting_data))
filtered_data = filter_log_syslogd_setting_data(flattened_data)
return fos.set('log.syslogd', return fos.set('log.syslogd',
'setting', 'setting',
data=filtered_data, data=filtered_data,
vdom=vdom) vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_log_syslogd(data, fos): def fortios_log_syslogd(data, fos):
login(data)
if data['log_syslogd_setting']: if data['log_syslogd_setting']:
resp = log_syslogd_setting(data, fos) resp = log_syslogd_setting(data, fos)
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True}, "https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"log_syslogd_setting": { "log_syslogd_setting": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"certificate": {"required": False, "type": "str"}, "certificate": {"required": False, "type": "str"},
"custom-field-name": {"required": False, "type": "list", "custom_field_name": {"required": False, "type": "list",
"options": { "options": {
"custom": {"required": False, "type": "str"}, "custom": {"required": False, "type": "str"},
"id": {"required": True, "type": "int"}, "id": {"required": True, "type": "int"},
"name": {"required": False, "type": "str"} "name": {"required": False, "type": "str"}
}}, }},
"enc-algorithm": {"required": False, "type": "str", "enc_algorithm": {"required": False, "type": "str",
"choices": ["high-medium", "high", "low", "choices": ["high-medium", "high", "low",
"disable"]}, "disable"]},
"facility": {"required": False, "type": "str", "facility": {"required": False, "type": "str",
@ -351,7 +389,10 @@ def main():
"choices": ["udp", "legacy-reliable", "reliable"]}, "choices": ["udp", "legacy-reliable", "reliable"]},
"port": {"required": False, "type": "int"}, "port": {"required": False, "type": "int"},
"server": {"required": False, "type": "str"}, "server": {"required": False, "type": "str"},
"source-ip": {"required": False, "type": "str"}, "source_ip": {"required": False, "type": "str"},
"ssl_min_proto_version": {"required": False, "type": "str",
"choices": ["default", "SSLv3", "TLSv1",
"TLSv1-1", "TLSv1-2"]},
"status": {"required": False, "type": "str", "status": {"required": False, "type": "str",
"choices": ["enable", "disable"]} "choices": ["enable", "disable"]}
@ -361,15 +402,31 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos # legacy_mode refers to using fortiosapi instead of HTTPAPI
fos = FortiOSAPI() 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_log_syslogd(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_log_syslogd(module.params, fos) login(module.params, fos)
is_error, has_changed, result = fortios_log_syslogd(module.params, fos)
fos.logout()
if not is_error: if not is_error:
module.exit_json(changed=has_changed, meta=result) 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 # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_log_threat_weight module: fortios_log_threat_weight
short_description: Configure threat weight settings in Fortinet's FortiOS and FortiGate. short_description: Configure threat weight settings in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by allowing the - This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify log feature and threat_weight category. user to set and modify log feature and threat_weight category.
Examples include all parameters and values need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,66 +41,82 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol
type: bool type: bool
default: true default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool
default: true
version_added: 2.9
log_threat_weight: log_threat_weight:
description: description:
- Configure threat weight settings. - Configure threat weight settings.
default: null default: null
type: dict
suboptions: suboptions:
application: application:
description: description:
- Application-control threat weight settings. - Application-control threat weight settings.
type: list
suboptions: suboptions:
category: category:
description: description:
- Application category. - Application category.
type: int
id: id:
description: description:
- Entry ID. - Entry ID.
required: true required: true
type: int
level: level:
description: description:
- Threat weight score for Application events. - Threat weight score for Application events.
type: str
choices: choices:
- disable - disable
- low - low
- medium - medium
- high - high
- critical - critical
blocked-connection: blocked_connection:
description: description:
- Threat weight score for blocked connections. - Threat weight score for blocked connections.
type: str
choices: choices:
- disable - disable
- low - low
- medium - medium
- high - high
- critical - critical
failed-connection: failed_connection:
description: description:
- Threat weight score for failed connections. - Threat weight score for failed connections.
type: str
choices: choices:
- disable - disable
- low - low
@ -113,17 +126,21 @@ options:
geolocation: geolocation:
description: description:
- Geolocation-based threat weight settings. - Geolocation-based threat weight settings.
type: list
suboptions: suboptions:
country: country:
description: description:
- Country code. - Country code.
type: str
id: id:
description: description:
- Entry ID. - Entry ID.
required: true required: true
type: int
level: level:
description: description:
- Threat weight score for Geolocation-based events. - Threat weight score for Geolocation-based events.
type: str
choices: choices:
- disable - disable
- low - low
@ -133,46 +150,52 @@ options:
ips: ips:
description: description:
- IPS threat weight settings. - IPS threat weight settings.
type: dict
suboptions: suboptions:
critical-severity: critical_severity:
description: description:
- Threat weight score for IPS critical severity events. - Threat weight score for IPS critical severity events.
type: str
choices: choices:
- disable - disable
- low - low
- medium - medium
- high - high
- critical - critical
high-severity: high_severity:
description: description:
- Threat weight score for IPS high severity events. - Threat weight score for IPS high severity events.
type: str
choices: choices:
- disable - disable
- low - low
- medium - medium
- high - high
- critical - critical
info-severity: info_severity:
description: description:
- Threat weight score for IPS info severity events. - Threat weight score for IPS info severity events.
type: str
choices: choices:
- disable - disable
- low - low
- medium - medium
- high - high
- critical - critical
low-severity: low_severity:
description: description:
- Threat weight score for IPS low severity events. - Threat weight score for IPS low severity events.
type: str
choices: choices:
- disable - disable
- low - low
- medium - medium
- high - high
- critical - critical
medium-severity: medium_severity:
description: description:
- Threat weight score for IPS medium severity events. - Threat weight score for IPS medium severity events.
type: str
choices: choices:
- disable - disable
- low - low
@ -182,35 +205,53 @@ options:
level: level:
description: description:
- Score mapping for threat weight levels. - Score mapping for threat weight levels.
type: dict
suboptions: suboptions:
critical: critical:
description: description:
- Critical level score value (1 - 100). - Critical level score value (1 - 100).
type: int
high: high:
description: description:
- High level score value (1 - 100). - High level score value (1 - 100).
type: int
low: low:
description: description:
- Low level score value (1 - 100). - Low level score value (1 - 100).
type: int
medium: medium:
description: description:
- Medium level score value (1 - 100). - Medium level score value (1 - 100).
type: int
malware: malware:
description: description:
- Anti-virus malware threat weight settings. - Anti-virus malware threat weight settings.
type: dict
suboptions: suboptions:
botnet-connection: botnet_connection:
description: description:
- Threat weight score for detected botnet connections. - Threat weight score for detected botnet connections.
type: str
choices: choices:
- disable - disable
- low - low
- medium - medium
- high - high
- critical - critical
command-blocked: command_blocked:
description: description:
- Threat weight score for blocked command detected. - Threat weight score for blocked command detected.
type: str
choices:
- disable
- low
- medium
- high
- critical
content_disarm:
description:
- Threat weight score for virus (content disarm) detected.
type: str
choices: choices:
- disable - disable
- low - low
@ -220,6 +261,7 @@ options:
mimefragmented: mimefragmented:
description: description:
- Threat weight score for mimefragmented detected. - Threat weight score for mimefragmented detected.
type: str
choices: choices:
- disable - disable
- low - low
@ -229,60 +271,67 @@ options:
oversized: oversized:
description: description:
- Threat weight score for oversized file detected. - Threat weight score for oversized file detected.
type: str
choices: choices:
- disable - disable
- low - low
- medium - medium
- high - high
- critical - critical
switch-proto: switch_proto:
description: description:
- Threat weight score for switch proto detected. - Threat weight score for switch proto detected.
type: str
choices: choices:
- disable - disable
- low - low
- medium - medium
- high - high
- critical - critical
virus-blocked: virus_blocked:
description: description:
- Threat weight score for virus (blocked) detected. - Threat weight score for virus (blocked) detected.
type: str
choices: choices:
- disable - disable
- low - low
- medium - medium
- high - high
- critical - critical
virus-file-type-executable: virus_file_type_executable:
description: description:
- Threat weight score for virus (filetype executable) detected. - Threat weight score for virus (filetype executable) detected.
type: str
choices: choices:
- disable - disable
- low - low
- medium - medium
- high - high
- critical - critical
virus-infected: virus_infected:
description: description:
- Threat weight score for virus (infected) detected. - Threat weight score for virus (infected) detected.
type: str
choices: choices:
- disable - disable
- low - low
- medium - medium
- high - high
- critical - critical
virus-outbreak-prevention: virus_outbreak_prevention:
description: description:
- Threat weight score for virus (outbreak prevention) event. - Threat weight score for virus (outbreak prevention) event.
type: str
choices: choices:
- disable - disable
- low - low
- medium - medium
- high - high
- critical - critical
virus-scan-error: virus_scan_error:
description: description:
- Threat weight score for virus (scan error) detected. - Threat weight score for virus (scan error) detected.
type: str
choices: choices:
- disable - disable
- low - low
@ -292,12 +341,14 @@ options:
status: status:
description: description:
- Enable/disable the threat weight feature. - Enable/disable the threat weight feature.
type: str
choices: choices:
- enable - enable
- disable - disable
url-block-detected: url_block_detected:
description: description:
- Threat weight score for URL blocking. - Threat weight score for URL blocking.
type: str
choices: choices:
- disable - disable
- low - low
@ -307,17 +358,21 @@ options:
web: web:
description: description:
- Web filtering threat weight settings. - Web filtering threat weight settings.
type: list
suboptions: suboptions:
category: category:
description: description:
- Threat weight score for web category filtering matches. - Threat weight score for web category filtering matches.
type: int
id: id:
description: description:
- Entry ID. - Entry ID.
required: true required: true
type: int
level: level:
description: description:
- Threat weight score for web category filtering matches. - Threat weight score for web category filtering matches.
type: str
choices: choices:
- disable - disable
- low - low
@ -333,6 +388,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Configure threat weight settings. - name: Configure threat weight settings.
fortios_log_threat_weight: fortios_log_threat_weight:
@ -347,41 +403,42 @@ EXAMPLES = '''
category: "4" category: "4"
id: "5" id: "5"
level: "disable" level: "disable"
blocked-connection: "disable" blocked_connection: "disable"
failed-connection: "disable" failed_connection: "disable"
geolocation: geolocation:
- -
country: "<your_own_value>" country: "<your_own_value>"
id: "11" id: "11"
level: "disable" level: "disable"
ips: ips:
critical-severity: "disable" critical_severity: "disable"
high-severity: "disable" high_severity: "disable"
info-severity: "disable" info_severity: "disable"
low-severity: "disable" low_severity: "disable"
medium-severity: "disable" medium_severity: "disable"
level: level:
critical: "20" critical: "20"
high: "21" high: "21"
low: "22" low: "22"
medium: "23" medium: "23"
malware: malware:
botnet-connection: "disable" botnet_connection: "disable"
command-blocked: "disable" command_blocked: "disable"
content_disarm: "disable"
mimefragmented: "disable" mimefragmented: "disable"
oversized: "disable" oversized: "disable"
switch-proto: "disable" switch_proto: "disable"
virus-blocked: "disable" virus_blocked: "disable"
virus-file-type-executable: "disable" virus_file_type_executable: "disable"
virus-infected: "disable" virus_infected: "disable"
virus-outbreak-prevention: "disable" virus_outbreak_prevention: "disable"
virus-scan-error: "disable" virus_scan_error: "disable"
status: "enable" status: "enable"
url-block-detected: "disable" url_block_detected: "disable"
web: web:
- -
category: "38" category: "39"
id: "39" id: "40"
level: "disable" level: "disable"
''' '''
@ -445,14 +502,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
fos = None 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'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -460,13 +519,13 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_log_threat_weight_data(json): def filter_log_threat_weight_data(json):
option_list = ['application', 'blocked-connection', 'failed-connection', option_list = ['application', 'blocked_connection', 'failed_connection',
'geolocation', 'ips', 'level', 'geolocation', 'ips', 'level',
'malware', 'status', 'url-block-detected', 'malware', 'status', 'url_block_detected',
'web'] 'web']
dictionary = {} dictionary = {}
@ -477,17 +536,15 @@ def filter_log_threat_weight_data(json):
return dictionary return dictionary
def flatten_multilists_attributes(data): def underscore_to_hyphen(data):
multilist_attrs = [] if isinstance(data, list):
for elem in data:
for attr in multilist_attrs: elem = underscore_to_hyphen(elem)
try: elif isinstance(data, dict):
path = "data['" + "']['".join(elem for elem in attr) + "']" new_data = {}
current_val = eval(path) for k, v in data.items():
flattened_val = ' '.join(elem for elem in current_val) new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
exec(path + '= flattened_val') data = new_data
except BaseException:
pass
return data return data
@ -495,33 +552,39 @@ def flatten_multilists_attributes(data):
def log_threat_weight(data, fos): def log_threat_weight(data, fos):
vdom = data['vdom'] vdom = data['vdom']
log_threat_weight_data = data['log_threat_weight'] log_threat_weight_data = data['log_threat_weight']
flattened_data = flatten_multilists_attributes(log_threat_weight_data) filtered_data = underscore_to_hyphen(filter_log_threat_weight_data(log_threat_weight_data))
filtered_data = filter_log_threat_weight_data(flattened_data)
return fos.set('log', return fos.set('log',
'threat-weight', 'threat-weight',
data=filtered_data, data=filtered_data,
vdom=vdom) vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_log(data, fos): def fortios_log(data, fos):
login(data)
if data['log_threat_weight']: if data['log_threat_weight']:
resp = log_threat_weight(data, fos) resp = log_threat_weight(data, fos)
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True}, "https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"log_threat_weight": { "log_threat_weight": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"application": {"required": False, "type": "list", "application": {"required": False, "type": "list",
"options": { "options": {
@ -531,10 +594,10 @@ def main():
"choices": ["disable", "low", "medium", "choices": ["disable", "low", "medium",
"high", "critical"]} "high", "critical"]}
}}, }},
"blocked-connection": {"required": False, "type": "str", "blocked_connection": {"required": False, "type": "str",
"choices": ["disable", "low", "medium", "choices": ["disable", "low", "medium",
"high", "critical"]}, "high", "critical"]},
"failed-connection": {"required": False, "type": "str", "failed_connection": {"required": False, "type": "str",
"choices": ["disable", "low", "medium", "choices": ["disable", "low", "medium",
"high", "critical"]}, "high", "critical"]},
"geolocation": {"required": False, "type": "list", "geolocation": {"required": False, "type": "list",
@ -547,19 +610,19 @@ def main():
}}, }},
"ips": {"required": False, "type": "dict", "ips": {"required": False, "type": "dict",
"options": { "options": {
"critical-severity": {"required": False, "type": "str", "critical_severity": {"required": False, "type": "str",
"choices": ["disable", "low", "medium", "choices": ["disable", "low", "medium",
"high", "critical"]}, "high", "critical"]},
"high-severity": {"required": False, "type": "str", "high_severity": {"required": False, "type": "str",
"choices": ["disable", "low", "medium", "choices": ["disable", "low", "medium",
"high", "critical"]}, "high", "critical"]},
"info-severity": {"required": False, "type": "str", "info_severity": {"required": False, "type": "str",
"choices": ["disable", "low", "medium", "choices": ["disable", "low", "medium",
"high", "critical"]}, "high", "critical"]},
"low-severity": {"required": False, "type": "str", "low_severity": {"required": False, "type": "str",
"choices": ["disable", "low", "medium", "choices": ["disable", "low", "medium",
"high", "critical"]}, "high", "critical"]},
"medium-severity": {"required": False, "type": "str", "medium_severity": {"required": False, "type": "str",
"choices": ["disable", "low", "medium", "choices": ["disable", "low", "medium",
"high", "critical"]} "high", "critical"]}
}}, }},
@ -572,40 +635,43 @@ def main():
}}, }},
"malware": {"required": False, "type": "dict", "malware": {"required": False, "type": "dict",
"options": { "options": {
"botnet-connection": {"required": False, "type": "str", "botnet_connection": {"required": False, "type": "str",
"choices": ["disable", "low", "medium", "choices": ["disable", "low", "medium",
"high", "critical"]}, "high", "critical"]},
"command-blocked": {"required": False, "type": "str", "command_blocked": {"required": False, "type": "str",
"choices": ["disable", "low", "medium", "choices": ["disable", "low", "medium",
"high", "critical"]}, "high", "critical"]},
"content_disarm": {"required": False, "type": "str",
"choices": ["disable", "low", "medium",
"high", "critical"]},
"mimefragmented": {"required": False, "type": "str", "mimefragmented": {"required": False, "type": "str",
"choices": ["disable", "low", "medium", "choices": ["disable", "low", "medium",
"high", "critical"]}, "high", "critical"]},
"oversized": {"required": False, "type": "str", "oversized": {"required": False, "type": "str",
"choices": ["disable", "low", "medium", "choices": ["disable", "low", "medium",
"high", "critical"]}, "high", "critical"]},
"switch-proto": {"required": False, "type": "str", "switch_proto": {"required": False, "type": "str",
"choices": ["disable", "low", "medium", "choices": ["disable", "low", "medium",
"high", "critical"]}, "high", "critical"]},
"virus-blocked": {"required": False, "type": "str", "virus_blocked": {"required": False, "type": "str",
"choices": ["disable", "low", "medium", "choices": ["disable", "low", "medium",
"high", "critical"]}, "high", "critical"]},
"virus-file-type-executable": {"required": False, "type": "str", "virus_file_type_executable": {"required": False, "type": "str",
"choices": ["disable", "low", "medium", "choices": ["disable", "low", "medium",
"high", "critical"]}, "high", "critical"]},
"virus-infected": {"required": False, "type": "str", "virus_infected": {"required": False, "type": "str",
"choices": ["disable", "low", "medium", "choices": ["disable", "low", "medium",
"high", "critical"]}, "high", "critical"]},
"virus-outbreak-prevention": {"required": False, "type": "str", "virus_outbreak_prevention": {"required": False, "type": "str",
"choices": ["disable", "low", "medium", "choices": ["disable", "low", "medium",
"high", "critical"]}, "high", "critical"]},
"virus-scan-error": {"required": False, "type": "str", "virus_scan_error": {"required": False, "type": "str",
"choices": ["disable", "low", "medium", "choices": ["disable", "low", "medium",
"high", "critical"]} "high", "critical"]}
}}, }},
"status": {"required": False, "type": "str", "status": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"url-block-detected": {"required": False, "type": "str", "url_block_detected": {"required": False, "type": "str",
"choices": ["disable", "low", "medium", "choices": ["disable", "low", "medium",
"high", "critical"]}, "high", "critical"]},
"web": {"required": False, "type": "list", "web": {"required": False, "type": "list",
@ -623,15 +689,31 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos # legacy_mode refers to using fortiosapi instead of HTTPAPI
fos = FortiOSAPI() 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_log(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_log(module.params, fos) login(module.params, fos)
is_error, has_changed, result = fortios_log(module.params, fos)
fos.logout()
if not is_error: if not is_error:
module.exit_json(changed=has_changed, meta=result) module.exit_json(changed=has_changed, meta=result)

@ -26,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_log_webtrends_filter module: fortios_log_webtrends_filter
short_description: Filters for WebTrends in Fortinet's FortiOS and FortiGate. short_description: Filters for WebTrends in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by allowing the - This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify log_webtrends feature and filter category. user to set and modify log_webtrends feature and filter category.
Examples include all parameters and values need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -41,88 +41,109 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool type: bool
default: true default: true
version_added: 2.9
log_webtrends_filter: log_webtrends_filter:
description: description:
- Filters for WebTrends. - Filters for WebTrends.
default: null default: null
type: dict
suboptions: suboptions:
anomaly: anomaly:
description: description:
- Enable/disable anomaly logging. - Enable/disable anomaly logging.
type: str
choices: choices:
- enable - enable
- disable - disable
dns: dns:
description: description:
- Enable/disable detailed DNS event logging. - Enable/disable detailed DNS event logging.
type: str
choices: choices:
- enable - enable
- disable - disable
filter: filter:
description: description:
- Webtrends log filter. - Webtrends log filter.
filter-type: type: str
filter_type:
description: description:
- Include/exclude logs that match the filter. - Include/exclude logs that match the filter.
type: str
choices: choices:
- include - include
- exclude - exclude
forward-traffic: forward_traffic:
description: description:
- Enable/disable forward traffic logging. - Enable/disable forward traffic logging.
type: str
choices: choices:
- enable - enable
- disable - disable
gtp: gtp:
description: description:
- Enable/disable GTP messages logging. - Enable/disable GTP messages logging.
type: str
choices: choices:
- enable - enable
- disable - disable
local-traffic: local_traffic:
description: description:
- Enable/disable local in or out traffic logging. - Enable/disable local in or out traffic logging.
type: str
choices: choices:
- enable - enable
- disable - disable
multicast-traffic: multicast_traffic:
description: description:
- Enable/disable multicast traffic logging. - Enable/disable multicast traffic logging.
type: str
choices: choices:
- enable - enable
- disable - disable
netscan-discovery: netscan_discovery:
description: description:
- Enable/disable netscan discovery event logging. - Enable/disable netscan discovery event logging.
netscan-vulnerability: type: str
netscan_vulnerability:
description: description:
- Enable/disable netscan vulnerability event logging. - Enable/disable netscan vulnerability event logging.
type: str
severity: severity:
description: description:
- Lowest severity level to log to WebTrends. - Lowest severity level to log to WebTrends.
type: str
choices: choices:
- emergency - emergency
- alert - alert
@ -132,21 +153,24 @@ options:
- notification - notification
- information - information
- debug - debug
sniffer-traffic: sniffer_traffic:
description: description:
- Enable/disable sniffer traffic logging. - Enable/disable sniffer traffic logging.
type: str
choices: choices:
- enable - enable
- disable - disable
ssh: ssh:
description: description:
- Enable/disable SSH logging. - Enable/disable SSH logging.
type: str
choices: choices:
- enable - enable
- disable - disable
voip: voip:
description: description:
- Enable/disable VoIP logging. - Enable/disable VoIP logging.
type: str
choices: choices:
- enable - enable
- disable - disable
@ -159,6 +183,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Filters for WebTrends. - name: Filters for WebTrends.
fortios_log_webtrends_filter: fortios_log_webtrends_filter:
@ -171,15 +196,15 @@ EXAMPLES = '''
anomaly: "enable" anomaly: "enable"
dns: "enable" dns: "enable"
filter: "<your_own_value>" filter: "<your_own_value>"
filter-type: "include" filter_type: "include"
forward-traffic: "enable" forward_traffic: "enable"
gtp: "enable" gtp: "enable"
local-traffic: "enable" local_traffic: "enable"
multicast-traffic: "enable" multicast_traffic: "enable"
netscan-discovery: "<your_own_value>" netscan_discovery: "<your_own_value>"
netscan-vulnerability: "<your_own_value>" netscan_vulnerability: "<your_own_value>"
severity: "emergency" severity: "emergency"
sniffer-traffic: "enable" sniffer_traffic: "enable"
ssh: "enable" ssh: "enable"
voip: "enable" voip: "enable"
''' '''
@ -244,12 +269,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
from ansible.module_utils.network.fortios.fortios import FortiOSHandler
from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
def login(data, fos): def login(data, fos):
host = data['host'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -257,14 +286,14 @@ def login(data, fos):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_log_webtrends_filter_data(json): def filter_log_webtrends_filter_data(json):
option_list = ['anomaly', 'dns', 'filter', option_list = ['anomaly', 'dns', 'filter',
'filter-type', 'forward-traffic', 'gtp', 'filter_type', 'forward_traffic', 'gtp',
'local-traffic', 'multicast-traffic', 'netscan-discovery', 'local_traffic', 'multicast_traffic', 'netscan_discovery',
'netscan-vulnerability', 'severity', 'sniffer-traffic', 'netscan_vulnerability', 'severity', 'sniffer_traffic',
'ssh', 'voip'] 'ssh', 'voip']
dictionary = {} dictionary = {}
@ -275,10 +304,23 @@ def filter_log_webtrends_filter_data(json):
return dictionary 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 log_webtrends_filter(data, fos): def log_webtrends_filter(data, fos):
vdom = data['vdom'] vdom = data['vdom']
log_webtrends_filter_data = data['log_webtrends_filter'] log_webtrends_filter_data = data['log_webtrends_filter']
filtered_data = filter_log_webtrends_filter_data(log_webtrends_filter_data) filtered_data = underscore_to_hyphen(filter_log_webtrends_filter_data(log_webtrends_filter_data))
return fos.set('log.webtrends', return fos.set('log.webtrends',
'filter', 'filter',
@ -286,48 +328,54 @@ def log_webtrends_filter(data, fos):
vdom=vdom) vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_log_webtrends(data, fos): def fortios_log_webtrends(data, fos):
login(data, fos)
if data['log_webtrends_filter']: if data['log_webtrends_filter']:
resp = log_webtrends_filter(data, fos) resp = log_webtrends_filter(data, fos)
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True}, "https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"log_webtrends_filter": { "log_webtrends_filter": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"anomaly": {"required": False, "type": "str", "anomaly": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"dns": {"required": False, "type": "str", "dns": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"filter": {"required": False, "type": "str"}, "filter": {"required": False, "type": "str"},
"filter-type": {"required": False, "type": "str", "filter_type": {"required": False, "type": "str",
"choices": ["include", "exclude"]}, "choices": ["include", "exclude"]},
"forward-traffic": {"required": False, "type": "str", "forward_traffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"gtp": {"required": False, "type": "str", "gtp": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"local-traffic": {"required": False, "type": "str", "local_traffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"multicast-traffic": {"required": False, "type": "str", "multicast_traffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"netscan-discovery": {"required": False, "type": "str"}, "netscan_discovery": {"required": False, "type": "str"},
"netscan-vulnerability": {"required": False, "type": "str"}, "netscan_vulnerability": {"required": False, "type": "str"},
"severity": {"required": False, "type": "str", "severity": {"required": False, "type": "str",
"choices": ["emergency", "alert", "critical", "choices": ["emergency", "alert", "critical",
"error", "warning", "notification", "error", "warning", "notification",
"information", "debug"]}, "information", "debug"]},
"sniffer-traffic": {"required": False, "type": "str", "sniffer_traffic": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"ssh": {"required": False, "type": "str", "ssh": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
@ -340,14 +388,31 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI() # legacy_mode refers to using fortiosapi instead of HTTPAPI
legacy_mode = 'host' in module.params and module.params['host'] is not None and \
'username' in module.params and module.params['username'] is not None and \
'password' in module.params and module.params['password'] is not None
if not legacy_mode:
if module._socket_path:
connection = Connection(module._socket_path)
fos = FortiOSHandler(connection)
is_error, has_changed, result = fortios_log_webtrends(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_log_webtrends(module.params, fos) login(module.params, fos)
is_error, has_changed, result = fortios_log_webtrends(module.params, fos)
fos.logout()
if not is_error: if not is_error:
module.exit_json(changed=has_changed, meta=result) 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 # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_log_webtrends_setting module: fortios_log_webtrends_setting
short_description: Settings for WebTrends in Fortinet's FortiOS and FortiGate. short_description: Settings for WebTrends in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by allowing the - This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify log_webtrends feature and setting category. user to set and modify log_webtrends feature and setting category.
Examples include all parameters and values need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,40 +41,52 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool type: bool
default: true default: true
version_added: 2.9
log_webtrends_setting: log_webtrends_setting:
description: description:
- Settings for WebTrends. - Settings for WebTrends.
default: null default: null
type: dict
suboptions: suboptions:
server: server:
description: description:
- Address of the remote WebTrends server. - Address of the remote WebTrends server.
type: str
status: status:
description: description:
- Enable/disable logging to WebTrends. - Enable/disable logging to WebTrends.
type: str
choices: choices:
- enable - enable
- disable - disable
@ -90,6 +99,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Settings for WebTrends. - name: Settings for WebTrends.
fortios_log_webtrends_setting: fortios_log_webtrends_setting:
@ -163,14 +173,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
fos = None 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'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -178,7 +190,7 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_log_webtrends_setting_data(json): def filter_log_webtrends_setting_data(json):
@ -192,17 +204,15 @@ def filter_log_webtrends_setting_data(json):
return dictionary return dictionary
def flatten_multilists_attributes(data): def underscore_to_hyphen(data):
multilist_attrs = [] if isinstance(data, list):
for elem in data:
for attr in multilist_attrs: elem = underscore_to_hyphen(elem)
try: elif isinstance(data, dict):
path = "data['" + "']['".join(elem for elem in attr) + "']" new_data = {}
current_val = eval(path) for k, v in data.items():
flattened_val = ' '.join(elem for elem in current_val) new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
exec(path + '= flattened_val') data = new_data
except BaseException:
pass
return data return data
@ -210,33 +220,39 @@ def flatten_multilists_attributes(data):
def log_webtrends_setting(data, fos): def log_webtrends_setting(data, fos):
vdom = data['vdom'] vdom = data['vdom']
log_webtrends_setting_data = data['log_webtrends_setting'] log_webtrends_setting_data = data['log_webtrends_setting']
flattened_data = flatten_multilists_attributes(log_webtrends_setting_data) filtered_data = underscore_to_hyphen(filter_log_webtrends_setting_data(log_webtrends_setting_data))
filtered_data = filter_log_webtrends_setting_data(flattened_data)
return fos.set('log.webtrends', return fos.set('log.webtrends',
'setting', 'setting',
data=filtered_data, data=filtered_data,
vdom=vdom) vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_log_webtrends(data, fos): def fortios_log_webtrends(data, fos):
login(data)
if data['log_webtrends_setting']: if data['log_webtrends_setting']:
resp = log_webtrends_setting(data, fos) resp = log_webtrends_setting(data, fos)
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True}, "https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"log_webtrends_setting": { "log_webtrends_setting": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"server": {"required": False, "type": "str"}, "server": {"required": False, "type": "str"},
"status": {"required": False, "type": "str", "status": {"required": False, "type": "str",
@ -248,15 +264,31 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos # legacy_mode refers to using fortiosapi instead of HTTPAPI
fos = FortiOSAPI() 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_log_webtrends(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_log_webtrends(module.params, fos) login(module.params, fos)
is_error, has_changed, result = fortios_log_webtrends(module.params, fos)
fos.logout()
if not is_error: if not is_error:
module.exit_json(changed=has_changed, meta=result) 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 # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_report_chart module: fortios_report_chart
short_description: Report chart widget configuration in Fortinet's FortiOS and FortiGate. short_description: Report chart widget configuration in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by allowing the - This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify report feature and chart category. user to set and modify report feature and chart category.
Examples include all parameters and values need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,46 +41,61 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool type: bool
default: true default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
required: true
choices:
- present
- absent
version_added: 2.9
report_chart: report_chart:
description: description:
- Report chart widget configuration. - Report chart widget configuration.
default: null default: null
type: dict
suboptions: suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
background: background:
description: description:
- Chart background. - Chart background.
type: str
category: category:
description: description:
- Category. - Category.
type: str
choices: choices:
- misc - misc
- traffic - traffic
@ -95,56 +107,71 @@ options:
- dlp - dlp
- app-ctrl - app-ctrl
- vulnerability - vulnerability
category-series: category_series:
description: description:
- Category series of pie chart. - Category series of pie chart.
type: dict
suboptions: suboptions:
databind: databind:
description: description:
- Category series value expression. - Category series value expression.
font-size: type: str
font_size:
description: description:
- Font size of category-series title. - Font size of category-series title.
color-palette: type: int
color_palette:
description: description:
- Color palette (system will pick color automatically by default). - Color palette (system will pick color automatically by default).
type: str
column: column:
description: description:
- Table column definition. - Table column definition.
type: list
suboptions: suboptions:
detail-unit: detail_unit:
description: description:
- Detail unit of column. - Detail unit of column.
detail-value: type: str
detail_value:
description: description:
- Detail value of column. - Detail value of column.
footer-unit: type: str
footer_unit:
description: description:
- Footer unit of column. - Footer unit of column.
footer-value: type: str
footer_value:
description: description:
- Footer value of column. - Footer value of column.
header-value: type: str
header_value:
description: description:
- Display name of table header. - Display name of table header.
type: str
id: id:
description: description:
- ID. - ID.
required: true required: true
type: int
mapping: mapping:
description: description:
- Show detail in certain display value for certain condition. - Show detail in certain display value for certain condition.
type: list
suboptions: suboptions:
displayname: displayname:
description: description:
- Display name. - Display name.
type: str
id: id:
description: description:
- id - id
required: true required: true
type: int
op: op:
description: description:
- Comparision operater. - Comparision operater.
type: str
choices: choices:
- none - none
- greater - greater
@ -153,56 +180,68 @@ options:
- less-equal - less-equal
- equal - equal
- between - between
value-type: value_type:
description: description:
- Value type. - Value type.
type: str
choices: choices:
- integer - integer
- string - string
value1: value1:
description: description:
- Value 1. - Value 1.
type: str
value2: value2:
description: description:
- Value 2. - Value 2.
type: str
comments: comments:
description: description:
- Comment. - Comment.
type: str
dataset: dataset:
description: description:
- Bind dataset to chart. - Bind dataset to chart.
type: str
dimension: dimension:
description: description:
- Dimension. - Dimension.
type: str
choices: choices:
- 2D - 2D
- 3D - 3D
drill-down-charts: drill_down_charts:
description: description:
- Drill down charts. - Drill down charts.
type: list
suboptions: suboptions:
chart-name: chart_name:
description: description:
- Drill down chart name. - Drill down chart name.
type: str
id: id:
description: description:
- Drill down chart ID. - Drill down chart ID.
required: true required: true
type: int
status: status:
description: description:
- Enable/disable this drill down chart. - Enable/disable this drill down chart.
type: str
choices: choices:
- enable - enable
- disable - disable
favorite: favorite:
description: description:
- Favorite. - Favorite.
type: str
choices: choices:
- no - no
- yes - yes
graph-type: graph_type:
description: description:
- Graph type. - Graph type.
type: str
choices: choices:
- none - none
- bar - bar
@ -212,88 +251,108 @@ options:
legend: legend:
description: description:
- Enable/Disable Legend area. - Enable/Disable Legend area.
type: str
choices: choices:
- enable - enable
- disable - disable
legend-font-size: legend_font_size:
description: description:
- Font size of legend area. - Font size of legend area.
type: int
name: name:
description: description:
- Chart Widget Name - Chart Widget Name
required: true required: true
type: str
period: period:
description: description:
- Time period. - Time period.
type: str
choices: choices:
- last24h - last24h
- last7d - last7d
policy: policy:
description: description:
- Used by monitor policy. - Used by monitor policy.
type: int
style: style:
description: description:
- Style. - Style.
type: str
choices: choices:
- auto - auto
- manual - manual
title: title:
description: description:
- Chart title. - Chart title.
title-font-size: type: str
title_font_size:
description: description:
- Font size of chart title. - Font size of chart title.
type: int
type: type:
description: description:
- Chart type. - Chart type.
type: str
choices: choices:
- graph - graph
- table - table
value-series: value_series:
description: description:
- Value series of pie chart. - Value series of pie chart.
type: dict
suboptions: suboptions:
databind: databind:
description: description:
- Value series value expression. - Value series value expression.
x-series: type: str
x_series:
description: description:
- X-series of chart. - X-series of chart.
type: dict
suboptions: suboptions:
caption: caption:
description: description:
- X-series caption. - X-series caption.
caption-font-size: type: str
caption_font_size:
description: description:
- X-series caption font size. - X-series caption font size.
type: int
databind: databind:
description: description:
- X-series value expression. - X-series value expression.
font-size: type: str
font_size:
description: description:
- X-series label font size. - X-series label font size.
is-category: type: int
is_category:
description: description:
- X-series represent category or not. - X-series represent category or not.
type: str
choices: choices:
- yes - yes
- no - no
label-angle: label_angle:
description: description:
- X-series label angle. - X-series label angle.
type: str
choices: choices:
- 45-degree - 45-degree
- vertical - vertical
- horizontal - horizontal
scale-direction: scale_direction:
description: description:
- Scale increase or decrease. - Scale increase or decrease.
type: str
choices: choices:
- decrease - decrease
- increase - increase
scale-format: scale_format:
description: description:
- Date/time format. - Date/time format.
type: str
choices: choices:
- YYYY-MM-DD-HH-MM - YYYY-MM-DD-HH-MM
- YYYY-MM-DD HH - YYYY-MM-DD HH
@ -302,12 +361,14 @@ options:
- YYYY - YYYY
- HH-MM - HH-MM
- MM-DD - MM-DD
scale-step: scale_step:
description: description:
- Scale step. - Scale step.
scale-unit: type: int
scale_unit:
description: description:
- Scale unit. - Scale unit.
type: str
choices: choices:
- minute - minute
- hour - hour
@ -317,40 +378,51 @@ options:
unit: unit:
description: description:
- X-series unit. - X-series unit.
y-series: type: str
y_series:
description: description:
- Y-series of chart. - Y-series of chart.
type: dict
suboptions: suboptions:
caption: caption:
description: description:
- Y-series caption. - Y-series caption.
caption-font-size: type: str
caption_font_size:
description: description:
- Y-series caption font size. - Y-series caption font size.
type: int
databind: databind:
description: description:
- Y-series value expression. - Y-series value expression.
extra-databind: type: str
extra_databind:
description: description:
- Extra Y-series value. - Extra Y-series value.
extra-y: type: str
extra_y:
description: description:
- Allow another Y-series value - Allow another Y-series value
type: str
choices: choices:
- enable - enable
- disable - disable
extra-y-legend: extra_y_legend:
description: description:
- Extra Y-series legend type/name. - Extra Y-series legend type/name.
font-size: type: str
font_size:
description: description:
- Y-series label font size. - Y-series label font size.
type: int
group: group:
description: description:
- Y-series group option. - Y-series group option.
label-angle: type: str
label_angle:
description: description:
- Y-series label angle. - Y-series label angle.
type: str
choices: choices:
- 45-degree - 45-degree
- vertical - vertical
@ -358,9 +430,11 @@ options:
unit: unit:
description: description:
- Y-series unit. - Y-series unit.
y-legend: type: str
y_legend:
description: description:
- First Y-series legend type/name. - First Y-series legend type/name.
type: str
''' '''
EXAMPLES = ''' EXAMPLES = '''
@ -370,6 +444,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Report chart widget configuration. - name: Report chart widget configuration.
fortios_report_chart: fortios_report_chart:
@ -378,75 +453,75 @@ EXAMPLES = '''
password: "{{ password }}" password: "{{ password }}"
vdom: "{{ vdom }}" vdom: "{{ vdom }}"
https: "False" https: "False"
state: "present"
report_chart: report_chart:
state: "present"
background: "<your_own_value>" background: "<your_own_value>"
category: "misc" category: "misc"
category-series: category_series:
databind: "<your_own_value>" databind: "<your_own_value>"
font-size: "7" font_size: "7"
color-palette: "<your_own_value>" color_palette: "<your_own_value>"
column: column:
- -
detail-unit: "<your_own_value>" detail_unit: "<your_own_value>"
detail-value: "<your_own_value>" detail_value: "<your_own_value>"
footer-unit: "<your_own_value>" footer_unit: "<your_own_value>"
footer-value: "<your_own_value>" footer_value: "<your_own_value>"
header-value: "<your_own_value>" header_value: "<your_own_value>"
id: "15" id: "15"
mapping: mapping:
- -
displayname: "<your_own_value>" displayname: "<your_own_value>"
id: "18" id: "18"
op: "none" op: "none"
value-type: "integer" value_type: "integer"
value1: "<your_own_value>" value1: "<your_own_value>"
value2: "<your_own_value>" value2: "<your_own_value>"
comments: "<your_own_value>" comments: "<your_own_value>"
dataset: "<your_own_value>" dataset: "<your_own_value>"
dimension: "2D" dimension: "2D"
drill-down-charts: drill_down_charts:
- -
chart-name: "<your_own_value>" chart_name: "<your_own_value>"
id: "28" id: "28"
status: "enable" status: "enable"
favorite: "no" favorite: "no"
graph-type: "none" graph_type: "none"
legend: "enable" legend: "enable"
legend-font-size: "33" legend_font_size: "33"
name: "default_name_34" name: "default_name_34"
period: "last24h" period: "last24h"
policy: "36" policy: "36"
style: "auto" style: "auto"
title: "<your_own_value>" title: "<your_own_value>"
title-font-size: "39" title_font_size: "39"
type: "graph" type: "graph"
value-series: value_series:
databind: "<your_own_value>" databind: "<your_own_value>"
x-series: x_series:
caption: "<your_own_value>" caption: "<your_own_value>"
caption-font-size: "45" caption_font_size: "45"
databind: "<your_own_value>" databind: "<your_own_value>"
font-size: "47" font_size: "47"
is-category: "yes" is_category: "yes"
label-angle: "45-degree" label_angle: "45-degree"
scale-direction: "decrease" scale_direction: "decrease"
scale-format: "YYYY-MM-DD-HH-MM" scale_format: "YYYY-MM-DD-HH-MM"
scale-step: "52" scale_step: "52"
scale-unit: "minute" scale_unit: "minute"
unit: "<your_own_value>" unit: "<your_own_value>"
y-series: y_series:
caption: "<your_own_value>" caption: "<your_own_value>"
caption-font-size: "57" caption_font_size: "57"
databind: "<your_own_value>" databind: "<your_own_value>"
extra-databind: "<your_own_value>" extra_databind: "<your_own_value>"
extra-y: "enable" extra_y: "enable"
extra-y-legend: "<your_own_value>" extra_y_legend: "<your_own_value>"
font-size: "62" font_size: "62"
group: "<your_own_value>" group: "<your_own_value>"
label-angle: "45-degree" label_angle: "45-degree"
unit: "<your_own_value>" unit: "<your_own_value>"
y-legend: "<your_own_value>" y_legend: "<your_own_value>"
''' '''
RETURN = ''' RETURN = '''
@ -509,14 +584,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
fos = None 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'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -524,18 +601,18 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_report_chart_data(json): def filter_report_chart_data(json):
option_list = ['background', 'category', 'category-series', option_list = ['background', 'category', 'category_series',
'color-palette', 'column', 'comments', 'color_palette', 'column', 'comments',
'dataset', 'dimension', 'drill-down-charts', 'dataset', 'dimension', 'drill_down_charts',
'favorite', 'graph-type', 'legend', 'favorite', 'graph_type', 'legend',
'legend-font-size', 'name', 'period', 'legend_font_size', 'name', 'period',
'policy', 'style', 'title', 'policy', 'style', 'title',
'title-font-size', 'type', 'value-series', 'title_font_size', 'type', 'value_series',
'x-series', 'y-series'] 'x_series', 'y_series']
dictionary = {} dictionary = {}
for attribute in option_list: for attribute in option_list:
@ -545,80 +622,85 @@ def filter_report_chart_data(json):
return dictionary return dictionary
def flatten_multilists_attributes(data): def underscore_to_hyphen(data):
multilist_attrs = [] if isinstance(data, list):
for elem in data:
for attr in multilist_attrs: elem = underscore_to_hyphen(elem)
try: elif isinstance(data, dict):
path = "data['" + "']['".join(elem for elem in attr) + "']" new_data = {}
current_val = eval(path) for k, v in data.items():
flattened_val = ' '.join(elem for elem in current_val) new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
exec(path + '= flattened_val') data = new_data
except BaseException:
pass
return data return data
def report_chart(data, fos): def report_chart(data, fos):
vdom = data['vdom'] vdom = data['vdom']
state = data['state']
report_chart_data = data['report_chart'] report_chart_data = data['report_chart']
flattened_data = flatten_multilists_attributes(report_chart_data) filtered_data = underscore_to_hyphen(filter_report_chart_data(report_chart_data))
filtered_data = filter_report_chart_data(flattened_data)
if report_chart_data['state'] == "present": if state == "present":
return fos.set('report', return fos.set('report',
'chart', 'chart',
data=filtered_data, data=filtered_data,
vdom=vdom) vdom=vdom)
elif report_chart_data['state'] == "absent": elif state == "absent":
return fos.delete('report', return fos.delete('report',
'chart', 'chart',
mkey=filtered_data['name'], mkey=filtered_data['name'],
vdom=vdom) vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_report(data, fos): def fortios_report(data, fos):
login(data)
if data['report_chart']: if data['report_chart']:
resp = report_chart(data, fos) resp = report_chart(data, fos)
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True}, "https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"report_chart": { "report_chart": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"background": {"required": False, "type": "str"}, "background": {"required": False, "type": "str"},
"category": {"required": False, "type": "str", "category": {"required": False, "type": "str",
"choices": ["misc", "traffic", "event", "choices": ["misc", "traffic", "event",
"virus", "webfilter", "attack", "virus", "webfilter", "attack",
"spam", "dlp", "app-ctrl", "spam", "dlp", "app-ctrl",
"vulnerability"]}, "vulnerability"]},
"category-series": {"required": False, "type": "dict", "category_series": {"required": False, "type": "dict",
"options": { "options": {
"databind": {"required": False, "type": "str"}, "databind": {"required": False, "type": "str"},
"font-size": {"required": False, "type": "int"} "font_size": {"required": False, "type": "int"}
}}, }},
"color-palette": {"required": False, "type": "str"}, "color_palette": {"required": False, "type": "str"},
"column": {"required": False, "type": "list", "column": {"required": False, "type": "list",
"options": { "options": {
"detail-unit": {"required": False, "type": "str"}, "detail_unit": {"required": False, "type": "str"},
"detail-value": {"required": False, "type": "str"}, "detail_value": {"required": False, "type": "str"},
"footer-unit": {"required": False, "type": "str"}, "footer_unit": {"required": False, "type": "str"},
"footer-value": {"required": False, "type": "str"}, "footer_value": {"required": False, "type": "str"},
"header-value": {"required": False, "type": "str"}, "header_value": {"required": False, "type": "str"},
"id": {"required": True, "type": "int"}, "id": {"required": True, "type": "int"},
"mapping": {"required": False, "type": "list", "mapping": {"required": False, "type": "list",
"options": { "options": {
@ -628,7 +710,7 @@ def main():
"choices": ["none", "greater", "greater-equal", "choices": ["none", "greater", "greater-equal",
"less", "less-equal", "equal", "less", "less-equal", "equal",
"between"]}, "between"]},
"value-type": {"required": False, "type": "str", "value_type": {"required": False, "type": "str",
"choices": ["integer", "string"]}, "choices": ["integer", "string"]},
"value1": {"required": False, "type": "str"}, "value1": {"required": False, "type": "str"},
"value2": {"required": False, "type": "str"} "value2": {"required": False, "type": "str"}
@ -638,21 +720,21 @@ def main():
"dataset": {"required": False, "type": "str"}, "dataset": {"required": False, "type": "str"},
"dimension": {"required": False, "type": "str", "dimension": {"required": False, "type": "str",
"choices": ["2D", "3D"]}, "choices": ["2D", "3D"]},
"drill-down-charts": {"required": False, "type": "list", "drill_down_charts": {"required": False, "type": "list",
"options": { "options": {
"chart-name": {"required": False, "type": "str"}, "chart_name": {"required": False, "type": "str"},
"id": {"required": True, "type": "int"}, "id": {"required": True, "type": "int"},
"status": {"required": False, "type": "str", "status": {"required": False, "type": "str",
"choices": ["enable", "disable"]} "choices": ["enable", "disable"]}
}}, }},
"favorite": {"required": False, "type": "str", "favorite": {"required": False, "type": "str",
"choices": ["no", "yes"]}, "choices": ["no", "yes"]},
"graph-type": {"required": False, "type": "str", "graph_type": {"required": False, "type": "str",
"choices": ["none", "bar", "pie", "choices": ["none", "bar", "pie",
"line", "flow"]}, "line", "flow"]},
"legend": {"required": False, "type": "str", "legend": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"legend-font-size": {"required": False, "type": "int"}, "legend_font_size": {"required": False, "type": "int"},
"name": {"required": True, "type": "str"}, "name": {"required": True, "type": "str"},
"period": {"required": False, "type": "str", "period": {"required": False, "type": "str",
"choices": ["last24h", "last7d"]}, "choices": ["last24h", "last7d"]},
@ -660,50 +742,50 @@ def main():
"style": {"required": False, "type": "str", "style": {"required": False, "type": "str",
"choices": ["auto", "manual"]}, "choices": ["auto", "manual"]},
"title": {"required": False, "type": "str"}, "title": {"required": False, "type": "str"},
"title-font-size": {"required": False, "type": "int"}, "title_font_size": {"required": False, "type": "int"},
"type": {"required": False, "type": "str", "type": {"required": False, "type": "str",
"choices": ["graph", "table"]}, "choices": ["graph", "table"]},
"value-series": {"required": False, "type": "dict", "value_series": {"required": False, "type": "dict",
"options": { "options": {
"databind": {"required": False, "type": "str"} "databind": {"required": False, "type": "str"}
}}, }},
"x-series": {"required": False, "type": "dict", "x_series": {"required": False, "type": "dict",
"options": { "options": {
"caption": {"required": False, "type": "str"}, "caption": {"required": False, "type": "str"},
"caption-font-size": {"required": False, "type": "int"}, "caption_font_size": {"required": False, "type": "int"},
"databind": {"required": False, "type": "str"}, "databind": {"required": False, "type": "str"},
"font-size": {"required": False, "type": "int"}, "font_size": {"required": False, "type": "int"},
"is-category": {"required": False, "type": "str", "is_category": {"required": False, "type": "str",
"choices": ["yes", "no"]}, "choices": ["yes", "no"]},
"label-angle": {"required": False, "type": "str", "label_angle": {"required": False, "type": "str",
"choices": ["45-degree", "vertical", "horizontal"]}, "choices": ["45-degree", "vertical", "horizontal"]},
"scale-direction": {"required": False, "type": "str", "scale_direction": {"required": False, "type": "str",
"choices": ["decrease", "increase"]}, "choices": ["decrease", "increase"]},
"scale-format": {"required": False, "type": "str", "scale_format": {"required": False, "type": "str",
"choices": ["YYYY-MM-DD-HH-MM", "YYYY-MM-DD HH", "YYYY-MM-DD", "choices": ["YYYY-MM-DD-HH-MM", "YYYY-MM-DD HH", "YYYY-MM-DD",
"YYYY-MM", "YYYY", "HH-MM", "YYYY-MM", "YYYY", "HH-MM",
"MM-DD"]}, "MM-DD"]},
"scale-step": {"required": False, "type": "int"}, "scale_step": {"required": False, "type": "int"},
"scale-unit": {"required": False, "type": "str", "scale_unit": {"required": False, "type": "str",
"choices": ["minute", "hour", "day", "choices": ["minute", "hour", "day",
"month", "year"]}, "month", "year"]},
"unit": {"required": False, "type": "str"} "unit": {"required": False, "type": "str"}
}}, }},
"y-series": {"required": False, "type": "dict", "y_series": {"required": False, "type": "dict",
"options": { "options": {
"caption": {"required": False, "type": "str"}, "caption": {"required": False, "type": "str"},
"caption-font-size": {"required": False, "type": "int"}, "caption_font_size": {"required": False, "type": "int"},
"databind": {"required": False, "type": "str"}, "databind": {"required": False, "type": "str"},
"extra-databind": {"required": False, "type": "str"}, "extra_databind": {"required": False, "type": "str"},
"extra-y": {"required": False, "type": "str", "extra_y": {"required": False, "type": "str",
"choices": ["enable", "disable"]}, "choices": ["enable", "disable"]},
"extra-y-legend": {"required": False, "type": "str"}, "extra_y_legend": {"required": False, "type": "str"},
"font-size": {"required": False, "type": "int"}, "font_size": {"required": False, "type": "int"},
"group": {"required": False, "type": "str"}, "group": {"required": False, "type": "str"},
"label-angle": {"required": False, "type": "str", "label_angle": {"required": False, "type": "str",
"choices": ["45-degree", "vertical", "horizontal"]}, "choices": ["45-degree", "vertical", "horizontal"]},
"unit": {"required": False, "type": "str"}, "unit": {"required": False, "type": "str"},
"y-legend": {"required": False, "type": "str"} "y_legend": {"required": False, "type": "str"}
}} }}
} }
@ -712,15 +794,31 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos # legacy_mode refers to using fortiosapi instead of HTTPAPI
fos = FortiOSAPI() 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_report(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_report(module.params, fos) login(module.params, fos)
is_error, has_changed, result = fortios_report(module.params, fos)
fos.logout()
if not is_error: if not is_error:
module.exit_json(changed=has_changed, meta=result) 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 # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # 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 __metaclass__ = type
@ -29,10 +26,10 @@ DOCUMENTATION = '''
module: fortios_report_dataset module: fortios_report_dataset
short_description: Report dataset configuration in Fortinet's FortiOS and FortiGate. short_description: Report dataset configuration in Fortinet's FortiOS and FortiGate.
description: description:
- This module is able to configure a FortiGate or FortiOS by allowing the - This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the
user to set and modify report feature and dataset category. user to set and modify report feature and dataset category.
Examples include all parameters and values need to be adjusted to datasources before usage. Examples include all parameters and values need to be adjusted to datasources before usage.
Tested with FOS v6.0.2 Tested with FOS v6.0.5
version_added: "2.8" version_added: "2.8"
author: author:
- Miguel Angel Munoz (@mamunozgonzalez) - Miguel Angel Munoz (@mamunozgonzalez)
@ -44,57 +41,75 @@ requirements:
- fortiosapi>=0.9.8 - fortiosapi>=0.9.8
options: options:
host: host:
description: description:
- FortiOS or FortiGate ip address. - FortiOS or FortiGate IP address.
required: true type: str
required: false
username: username:
description: description:
- FortiOS or FortiGate username. - FortiOS or FortiGate username.
required: true type: str
required: false
password: password:
description: description:
- FortiOS or FortiGate password. - FortiOS or FortiGate password.
type: str
default: "" default: ""
vdom: vdom:
description: description:
- Virtual domain, among those defined previously. A vdom is a - Virtual domain, among those defined previously. A vdom is a
virtual instance of the FortiGate that can be configured and virtual instance of the FortiGate that can be configured and
used as a different unit. used as a different unit.
type: str
default: root default: root
https: https:
description: description:
- Indicates if the requests towards FortiGate must use HTTPS - Indicates if the requests towards FortiGate must use HTTPS protocol.
protocol type: bool
default: true
ssl_verify:
description:
- Ensures FortiGate certificate must be verified by a proper CA.
type: bool type: bool
default: true default: true
version_added: 2.9
state:
description:
- Indicates whether to create or remove the object.
type: str
required: true
choices:
- present
- absent
version_added: 2.9
report_dataset: report_dataset:
description: description:
- Report dataset configuration. - Report dataset configuration.
default: null default: null
type: dict
suboptions: suboptions:
state:
description:
- Indicates whether to create or remove the object
choices:
- present
- absent
field: field:
description: description:
- Fields. - Fields.
type: list
suboptions: suboptions:
displayname: displayname:
description: description:
- Display name. - Display name.
type: str
id: id:
description: description:
- Field ID (1 to number of columns in SQL result). - Field ID (1 to number of columns in SQL result).
required: true required: true
type: int
name: name:
description: description:
- Name. - Name.
type: str
type: type:
description: description:
- Field type. - Field type.
type: str
choices: choices:
- text - text
- integer - integer
@ -103,35 +118,43 @@ options:
description: description:
- Name. - Name.
required: true required: true
type: str
parameters: parameters:
description: description:
- Parameters. - Parameters.
type: list
suboptions: suboptions:
data-type: data_type:
description: description:
- Data type. - Data type.
type: str
choices: choices:
- text - text
- integer - integer
- double - double
- long-integer - long-integer
- date-time - date-time
display-name: display_name:
description: description:
- Display name. - Display name.
type: str
field: field:
description: description:
- SQL field name. - SQL field name.
type: str
id: id:
description: description:
- Parameter ID (1 to number of columns in SQL result). - Parameter ID (1 to number of columns in SQL result).
required: true required: true
type: int
policy: policy:
description: description:
- Used by monitor policy. - Used by monitor policy.
type: int
query: query:
description: description:
- SQL query statement. - SQL query statement.
type: str
''' '''
EXAMPLES = ''' EXAMPLES = '''
@ -141,6 +164,7 @@ EXAMPLES = '''
username: "admin" username: "admin"
password: "" password: ""
vdom: "root" vdom: "root"
ssl_verify: "False"
tasks: tasks:
- name: Report dataset configuration. - name: Report dataset configuration.
fortios_report_dataset: fortios_report_dataset:
@ -149,8 +173,8 @@ EXAMPLES = '''
password: "{{ password }}" password: "{{ password }}"
vdom: "{{ vdom }}" vdom: "{{ vdom }}"
https: "False" https: "False"
state: "present"
report_dataset: report_dataset:
state: "present"
field: field:
- -
displayname: "<your_own_value>" displayname: "<your_own_value>"
@ -160,8 +184,8 @@ EXAMPLES = '''
name: "default_name_8" name: "default_name_8"
parameters: parameters:
- -
data-type: "text" data_type: "text"
display-name: "<your_own_value>" display_name: "<your_own_value>"
field: "<your_own_value>" field: "<your_own_value>"
id: "13" id: "13"
policy: "14" policy: "14"
@ -228,14 +252,16 @@ version:
''' '''
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import Connection
fos = None 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'] host = data['host']
username = data['username'] username = data['username']
password = data['password'] password = data['password']
ssl_verify = data['ssl_verify']
fos.debug('on') fos.debug('on')
if 'https' in data and not data['https']: if 'https' in data and not data['https']:
@ -243,7 +269,7 @@ def login(data):
else: else:
fos.https('on') fos.https('on')
fos.login(host, username, password) fos.login(host, username, password, verify=ssl_verify)
def filter_report_dataset_data(json): def filter_report_dataset_data(json):
@ -258,61 +284,66 @@ def filter_report_dataset_data(json):
return dictionary return dictionary
def flatten_multilists_attributes(data): def underscore_to_hyphen(data):
multilist_attrs = [] if isinstance(data, list):
for elem in data:
for attr in multilist_attrs: elem = underscore_to_hyphen(elem)
try: elif isinstance(data, dict):
path = "data['" + "']['".join(elem for elem in attr) + "']" new_data = {}
current_val = eval(path) for k, v in data.items():
flattened_val = ' '.join(elem for elem in current_val) new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
exec(path + '= flattened_val') data = new_data
except BaseException:
pass
return data return data
def report_dataset(data, fos): def report_dataset(data, fos):
vdom = data['vdom'] vdom = data['vdom']
state = data['state']
report_dataset_data = data['report_dataset'] report_dataset_data = data['report_dataset']
flattened_data = flatten_multilists_attributes(report_dataset_data) filtered_data = underscore_to_hyphen(filter_report_dataset_data(report_dataset_data))
filtered_data = filter_report_dataset_data(flattened_data)
if report_dataset_data['state'] == "present": if state == "present":
return fos.set('report', return fos.set('report',
'dataset', 'dataset',
data=filtered_data, data=filtered_data,
vdom=vdom) vdom=vdom)
elif report_dataset_data['state'] == "absent": elif state == "absent":
return fos.delete('report', return fos.delete('report',
'dataset', 'dataset',
mkey=filtered_data['name'], mkey=filtered_data['name'],
vdom=vdom) vdom=vdom)
def is_successful_status(status):
return status['status'] == "success" or \
status['http_method'] == "DELETE" and status['http_status'] == 404
def fortios_report(data, fos): def fortios_report(data, fos):
login(data)
if data['report_dataset']: if data['report_dataset']:
resp = report_dataset(data, fos) resp = report_dataset(data, fos)
fos.logout() return not is_successful_status(resp), \
return not resp['status'] == "success", resp['status'] == "success", resp resp['status'] == "success", \
resp
def main(): def main():
fields = { fields = {
"host": {"required": True, "type": "str"}, "host": {"required": False, "type": "str"},
"username": {"required": True, "type": "str"}, "username": {"required": False, "type": "str"},
"password": {"required": False, "type": "str", "no_log": True}, "password": {"required": False, "type": "str", "default": "", "no_log": True},
"vdom": {"required": False, "type": "str", "default": "root"}, "vdom": {"required": False, "type": "str", "default": "root"},
"https": {"required": False, "type": "bool", "default": True}, "https": {"required": False, "type": "bool", "default": True},
"ssl_verify": {"required": False, "type": "bool", "default": True},
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"report_dataset": { "report_dataset": {
"required": False, "type": "dict", "required": False, "type": "dict", "default": None,
"options": { "options": {
"state": {"required": True, "type": "str",
"choices": ["present", "absent"]},
"field": {"required": False, "type": "list", "field": {"required": False, "type": "list",
"options": { "options": {
"displayname": {"required": False, "type": "str"}, "displayname": {"required": False, "type": "str"},
@ -324,10 +355,10 @@ def main():
"name": {"required": True, "type": "str"}, "name": {"required": True, "type": "str"},
"parameters": {"required": False, "type": "list", "parameters": {"required": False, "type": "list",
"options": { "options": {
"data-type": {"required": False, "type": "str", "data_type": {"required": False, "type": "str",
"choices": ["text", "integer", "double", "choices": ["text", "integer", "double",
"long-integer", "date-time"]}, "long-integer", "date-time"]},
"display-name": {"required": False, "type": "str"}, "display_name": {"required": False, "type": "str"},
"field": {"required": False, "type": "str"}, "field": {"required": False, "type": "str"},
"id": {"required": True, "type": "int"} "id": {"required": True, "type": "int"}
}}, }},
@ -340,15 +371,31 @@ def main():
module = AnsibleModule(argument_spec=fields, module = AnsibleModule(argument_spec=fields,
supports_check_mode=False) supports_check_mode=False)
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
global fos # legacy_mode refers to using fortiosapi instead of HTTPAPI
fos = FortiOSAPI() 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_report(module.params, fos)
else:
module.fail_json(**FAIL_SOCKET_MSG)
else:
try:
from fortiosapi import FortiOSAPI
except ImportError:
module.fail_json(msg="fortiosapi module is required")
fos = FortiOSAPI()
is_error, has_changed, result = fortios_report(module.params, fos) login(module.params, fos)
is_error, has_changed, result = fortios_report(module.params, fos)
fos.logout()
if not is_error: if not is_error:
module.exit_json(changed=has_changed, meta=result) module.exit_json(changed=has_changed, meta=result)

@ -3694,44 +3694,7 @@ lib/ansible/modules/network/fortios/fortios_firewall_policy.py validate-modules:
lib/ansible/modules/network/fortios/fortios_firewall_sniffer.py validate-modules:E336 lib/ansible/modules/network/fortios/fortios_firewall_sniffer.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_ipv4_policy.py validate-modules:E337 lib/ansible/modules/network/fortios/fortios_ipv4_policy.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_ipv4_policy.py validate-modules:E338 lib/ansible/modules/network/fortios/fortios_ipv4_policy.py validate-modules:E338
lib/ansible/modules/network/fortios/fortios_log_memory_global_setting.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_log_memory_global_setting.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_log_memory_setting.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_log_null_device_filter.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_log_null_device_filter.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_log_null_device_setting.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_log_setting.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_log_setting.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_log_syslogd2_filter.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_log_syslogd2_filter.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_log_syslogd2_setting.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_log_syslogd2_setting.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_log_syslogd3_filter.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_log_syslogd3_filter.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_log_syslogd3_setting.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_log_syslogd3_setting.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_log_syslogd4_filter.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_log_syslogd4_filter.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_log_syslogd4_setting.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_log_syslogd4_setting.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_log_syslogd_filter.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_log_syslogd_filter.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_log_syslogd_override_filter.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_log_syslogd_override_filter.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_log_syslogd_override_setting.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_log_syslogd_override_setting.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_log_syslogd_setting.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_log_syslogd_setting.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_log_threat_weight.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_log_threat_weight.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_log_webtrends_filter.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_log_webtrends_filter.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_log_webtrends_setting.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_report_chart.py validate-modules:E326 lib/ansible/modules/network/fortios/fortios_report_chart.py validate-modules:E326
lib/ansible/modules/network/fortios/fortios_report_chart.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_report_chart.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_report_dataset.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_report_dataset.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_report_layout.py validate-modules:E336 lib/ansible/modules/network/fortios/fortios_report_layout.py validate-modules:E336
lib/ansible/modules/network/fortios/fortios_report_layout.py validate-modules:E337 lib/ansible/modules/network/fortios/fortios_report_layout.py validate-modules:E337
lib/ansible/modules/network/fortios/fortios_report_setting.py validate-modules:E336 lib/ansible/modules/network/fortios/fortios_report_setting.py validate-modules:E336

@ -0,0 +1,175 @@
# 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_log_memory_global_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_log_memory_global_setting.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_log_memory_global_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',
'log_memory_global_setting': {
'full_final_warning_threshold': '3',
'full_first_warning_threshold': '4',
'full_second_warning_threshold': '5',
'max_size': '6'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_memory_global_setting.fortios_log_memory(input_data, fos_instance)
expected_data = {
'full-final-warning-threshold': '3',
'full-first-warning-threshold': '4',
'full-second-warning-threshold': '5',
'max-size': '6'
}
set_method_mock.assert_called_with('log.memory', 'global-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_log_memory_global_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',
'log_memory_global_setting': {
'full_final_warning_threshold': '3',
'full_first_warning_threshold': '4',
'full_second_warning_threshold': '5',
'max_size': '6'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_memory_global_setting.fortios_log_memory(input_data, fos_instance)
expected_data = {
'full-final-warning-threshold': '3',
'full-first-warning-threshold': '4',
'full-second-warning-threshold': '5',
'max-size': '6'
}
set_method_mock.assert_called_with('log.memory', 'global-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_log_memory_global_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',
'log_memory_global_setting': {
'full_final_warning_threshold': '3',
'full_first_warning_threshold': '4',
'full_second_warning_threshold': '5',
'max_size': '6'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_memory_global_setting.fortios_log_memory(input_data, fos_instance)
expected_data = {
'full-final-warning-threshold': '3',
'full-first-warning-threshold': '4',
'full-second-warning-threshold': '5',
'max-size': '6'
}
set_method_mock.assert_called_with('log.memory', 'global-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_log_memory_global_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',
'log_memory_global_setting': {
'random_attribute_not_valid': 'tag',
'full_final_warning_threshold': '3',
'full_first_warning_threshold': '4',
'full_second_warning_threshold': '5',
'max_size': '6'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_memory_global_setting.fortios_log_memory(input_data, fos_instance)
expected_data = {
'full-final-warning-threshold': '3',
'full-first-warning-threshold': '4',
'full-second-warning-threshold': '5',
'max-size': '6'
}
set_method_mock.assert_called_with('log.memory', 'global-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,159 @@
# 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_log_memory_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_log_memory_setting.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_log_memory_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',
'log_memory_setting': {
'diskfull': 'overwrite',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_memory_setting.fortios_log_memory(input_data, fos_instance)
expected_data = {
'diskfull': 'overwrite',
'status': 'enable'
}
set_method_mock.assert_called_with('log.memory', '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_log_memory_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',
'log_memory_setting': {
'diskfull': 'overwrite',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_memory_setting.fortios_log_memory(input_data, fos_instance)
expected_data = {
'diskfull': 'overwrite',
'status': 'enable'
}
set_method_mock.assert_called_with('log.memory', '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_log_memory_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',
'log_memory_setting': {
'diskfull': 'overwrite',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_memory_setting.fortios_log_memory(input_data, fos_instance)
expected_data = {
'diskfull': 'overwrite',
'status': 'enable'
}
set_method_mock.assert_called_with('log.memory', '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_log_memory_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',
'log_memory_setting': {
'random_attribute_not_valid': 'tag',
'diskfull': 'overwrite',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_memory_setting.fortios_log_memory(input_data, fos_instance)
expected_data = {
'diskfull': 'overwrite',
'status': 'enable'
}
set_method_mock.assert_called_with('log.memory', '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,255 @@
# 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_log_null_device_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_log_null_device_filter.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_log_null_device_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',
'log_null_device_filter': {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter_type': 'include',
'forward_traffic': 'enable',
'gtp': 'enable',
'local_traffic': 'enable',
'multicast_traffic': 'enable',
'netscan_discovery': 'test_value_11,',
'netscan_vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer_traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_null_device_filter.fortios_log_null_device(input_data, fos_instance)
expected_data = {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter-type': 'include',
'forward-traffic': 'enable',
'gtp': 'enable',
'local-traffic': 'enable',
'multicast-traffic': 'enable',
'netscan-discovery': 'test_value_11,',
'netscan-vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer-traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
}
set_method_mock.assert_called_with('log.null-device', '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_log_null_device_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',
'log_null_device_filter': {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter_type': 'include',
'forward_traffic': 'enable',
'gtp': 'enable',
'local_traffic': 'enable',
'multicast_traffic': 'enable',
'netscan_discovery': 'test_value_11,',
'netscan_vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer_traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_null_device_filter.fortios_log_null_device(input_data, fos_instance)
expected_data = {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter-type': 'include',
'forward-traffic': 'enable',
'gtp': 'enable',
'local-traffic': 'enable',
'multicast-traffic': 'enable',
'netscan-discovery': 'test_value_11,',
'netscan-vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer-traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
}
set_method_mock.assert_called_with('log.null-device', '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_log_null_device_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',
'log_null_device_filter': {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter_type': 'include',
'forward_traffic': 'enable',
'gtp': 'enable',
'local_traffic': 'enable',
'multicast_traffic': 'enable',
'netscan_discovery': 'test_value_11,',
'netscan_vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer_traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_null_device_filter.fortios_log_null_device(input_data, fos_instance)
expected_data = {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter-type': 'include',
'forward-traffic': 'enable',
'gtp': 'enable',
'local-traffic': 'enable',
'multicast-traffic': 'enable',
'netscan-discovery': 'test_value_11,',
'netscan-vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer-traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
}
set_method_mock.assert_called_with('log.null-device', '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_log_null_device_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',
'log_null_device_filter': {
'random_attribute_not_valid': 'tag',
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter_type': 'include',
'forward_traffic': 'enable',
'gtp': 'enable',
'local_traffic': 'enable',
'multicast_traffic': 'enable',
'netscan_discovery': 'test_value_11,',
'netscan_vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer_traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_null_device_filter.fortios_log_null_device(input_data, fos_instance)
expected_data = {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter-type': 'include',
'forward-traffic': 'enable',
'gtp': 'enable',
'local-traffic': 'enable',
'multicast-traffic': 'enable',
'netscan-discovery': 'test_value_11,',
'netscan-vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer-traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
}
set_method_mock.assert_called_with('log.null-device', '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,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_log_null_device_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_log_null_device_setting.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_log_null_device_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',
'log_null_device_setting': {
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_null_device_setting.fortios_log_null_device(input_data, fos_instance)
expected_data = {
'status': 'enable'
}
set_method_mock.assert_called_with('log.null-device', '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_log_null_device_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',
'log_null_device_setting': {
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_null_device_setting.fortios_log_null_device(input_data, fos_instance)
expected_data = {
'status': 'enable'
}
set_method_mock.assert_called_with('log.null-device', '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_log_null_device_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',
'log_null_device_setting': {
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_null_device_setting.fortios_log_null_device(input_data, fos_instance)
expected_data = {
'status': 'enable'
}
set_method_mock.assert_called_with('log.null-device', '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_log_null_device_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',
'log_null_device_setting': {
'random_attribute_not_valid': 'tag',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_null_device_setting.fortios_log_null_device(input_data, fos_instance)
expected_data = {
'status': 'enable'
}
set_method_mock.assert_called_with('log.null-device', '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,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_log_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_log_setting.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_log_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',
'log_setting': {
'brief_traffic_format': 'enable',
'daemon_log': 'enable',
'expolicy_implicit_log': 'enable',
'fwpolicy_implicit_log': 'enable',
'fwpolicy6_implicit_log': 'enable',
'local_in_allow': 'enable',
'local_in_deny_broadcast': 'enable',
'local_in_deny_unicast': 'enable',
'local_out': 'enable',
'log_invalid_packet': 'enable',
'log_policy_comment': 'enable',
'log_policy_name': 'enable',
'log_user_in_upper': 'enable',
'neighbor_event': 'enable',
'resolve_ip': 'enable',
'resolve_port': 'enable',
'user_anonymize': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_setting.fortios_log(input_data, fos_instance)
expected_data = {
'brief-traffic-format': 'enable',
'daemon-log': 'enable',
'expolicy-implicit-log': 'enable',
'fwpolicy-implicit-log': 'enable',
'fwpolicy6-implicit-log': 'enable',
'local-in-allow': 'enable',
'local-in-deny-broadcast': 'enable',
'local-in-deny-unicast': 'enable',
'local-out': 'enable',
'log-invalid-packet': 'enable',
'log-policy-comment': 'enable',
'log-policy-name': 'enable',
'log-user-in-upper': 'enable',
'neighbor-event': 'enable',
'resolve-ip': 'enable',
'resolve-port': 'enable',
'user-anonymize': 'enable'
}
set_method_mock.assert_called_with('log', '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_log_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',
'log_setting': {
'brief_traffic_format': 'enable',
'daemon_log': 'enable',
'expolicy_implicit_log': 'enable',
'fwpolicy_implicit_log': 'enable',
'fwpolicy6_implicit_log': 'enable',
'local_in_allow': 'enable',
'local_in_deny_broadcast': 'enable',
'local_in_deny_unicast': 'enable',
'local_out': 'enable',
'log_invalid_packet': 'enable',
'log_policy_comment': 'enable',
'log_policy_name': 'enable',
'log_user_in_upper': 'enable',
'neighbor_event': 'enable',
'resolve_ip': 'enable',
'resolve_port': 'enable',
'user_anonymize': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_setting.fortios_log(input_data, fos_instance)
expected_data = {
'brief-traffic-format': 'enable',
'daemon-log': 'enable',
'expolicy-implicit-log': 'enable',
'fwpolicy-implicit-log': 'enable',
'fwpolicy6-implicit-log': 'enable',
'local-in-allow': 'enable',
'local-in-deny-broadcast': 'enable',
'local-in-deny-unicast': 'enable',
'local-out': 'enable',
'log-invalid-packet': 'enable',
'log-policy-comment': 'enable',
'log-policy-name': 'enable',
'log-user-in-upper': 'enable',
'neighbor-event': 'enable',
'resolve-ip': 'enable',
'resolve-port': 'enable',
'user-anonymize': 'enable'
}
set_method_mock.assert_called_with('log', '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_log_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',
'log_setting': {
'brief_traffic_format': 'enable',
'daemon_log': 'enable',
'expolicy_implicit_log': 'enable',
'fwpolicy_implicit_log': 'enable',
'fwpolicy6_implicit_log': 'enable',
'local_in_allow': 'enable',
'local_in_deny_broadcast': 'enable',
'local_in_deny_unicast': 'enable',
'local_out': 'enable',
'log_invalid_packet': 'enable',
'log_policy_comment': 'enable',
'log_policy_name': 'enable',
'log_user_in_upper': 'enable',
'neighbor_event': 'enable',
'resolve_ip': 'enable',
'resolve_port': 'enable',
'user_anonymize': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_setting.fortios_log(input_data, fos_instance)
expected_data = {
'brief-traffic-format': 'enable',
'daemon-log': 'enable',
'expolicy-implicit-log': 'enable',
'fwpolicy-implicit-log': 'enable',
'fwpolicy6-implicit-log': 'enable',
'local-in-allow': 'enable',
'local-in-deny-broadcast': 'enable',
'local-in-deny-unicast': 'enable',
'local-out': 'enable',
'log-invalid-packet': 'enable',
'log-policy-comment': 'enable',
'log-policy-name': 'enable',
'log-user-in-upper': 'enable',
'neighbor-event': 'enable',
'resolve-ip': 'enable',
'resolve-port': 'enable',
'user-anonymize': 'enable'
}
set_method_mock.assert_called_with('log', '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_log_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',
'log_setting': {
'random_attribute_not_valid': 'tag',
'brief_traffic_format': 'enable',
'daemon_log': 'enable',
'expolicy_implicit_log': 'enable',
'fwpolicy_implicit_log': 'enable',
'fwpolicy6_implicit_log': 'enable',
'local_in_allow': 'enable',
'local_in_deny_broadcast': 'enable',
'local_in_deny_unicast': 'enable',
'local_out': 'enable',
'log_invalid_packet': 'enable',
'log_policy_comment': 'enable',
'log_policy_name': 'enable',
'log_user_in_upper': 'enable',
'neighbor_event': 'enable',
'resolve_ip': 'enable',
'resolve_port': 'enable',
'user_anonymize': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_setting.fortios_log(input_data, fos_instance)
expected_data = {
'brief-traffic-format': 'enable',
'daemon-log': 'enable',
'expolicy-implicit-log': 'enable',
'fwpolicy-implicit-log': 'enable',
'fwpolicy6-implicit-log': 'enable',
'local-in-allow': 'enable',
'local-in-deny-broadcast': 'enable',
'local-in-deny-unicast': 'enable',
'local-out': 'enable',
'log-invalid-packet': 'enable',
'log-policy-comment': 'enable',
'log-policy-name': 'enable',
'log-user-in-upper': 'enable',
'neighbor-event': 'enable',
'resolve-ip': 'enable',
'resolve-port': 'enable',
'user-anonymize': 'enable'
}
set_method_mock.assert_called_with('log', '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,255 @@
# 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_log_syslogd2_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_log_syslogd2_filter.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_log_syslogd2_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',
'log_syslogd2_filter': {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter_type': 'include',
'forward_traffic': 'enable',
'gtp': 'enable',
'local_traffic': 'enable',
'multicast_traffic': 'enable',
'netscan_discovery': 'test_value_11,',
'netscan_vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer_traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd2_filter.fortios_log_syslogd2(input_data, fos_instance)
expected_data = {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter-type': 'include',
'forward-traffic': 'enable',
'gtp': 'enable',
'local-traffic': 'enable',
'multicast-traffic': 'enable',
'netscan-discovery': 'test_value_11,',
'netscan-vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer-traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
}
set_method_mock.assert_called_with('log.syslogd2', '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_log_syslogd2_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',
'log_syslogd2_filter': {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter_type': 'include',
'forward_traffic': 'enable',
'gtp': 'enable',
'local_traffic': 'enable',
'multicast_traffic': 'enable',
'netscan_discovery': 'test_value_11,',
'netscan_vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer_traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd2_filter.fortios_log_syslogd2(input_data, fos_instance)
expected_data = {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter-type': 'include',
'forward-traffic': 'enable',
'gtp': 'enable',
'local-traffic': 'enable',
'multicast-traffic': 'enable',
'netscan-discovery': 'test_value_11,',
'netscan-vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer-traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
}
set_method_mock.assert_called_with('log.syslogd2', '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_log_syslogd2_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',
'log_syslogd2_filter': {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter_type': 'include',
'forward_traffic': 'enable',
'gtp': 'enable',
'local_traffic': 'enable',
'multicast_traffic': 'enable',
'netscan_discovery': 'test_value_11,',
'netscan_vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer_traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd2_filter.fortios_log_syslogd2(input_data, fos_instance)
expected_data = {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter-type': 'include',
'forward-traffic': 'enable',
'gtp': 'enable',
'local-traffic': 'enable',
'multicast-traffic': 'enable',
'netscan-discovery': 'test_value_11,',
'netscan-vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer-traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
}
set_method_mock.assert_called_with('log.syslogd2', '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_log_syslogd2_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',
'log_syslogd2_filter': {
'random_attribute_not_valid': 'tag',
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter_type': 'include',
'forward_traffic': 'enable',
'gtp': 'enable',
'local_traffic': 'enable',
'multicast_traffic': 'enable',
'netscan_discovery': 'test_value_11,',
'netscan_vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer_traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd2_filter.fortios_log_syslogd2(input_data, fos_instance)
expected_data = {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter-type': 'include',
'forward-traffic': 'enable',
'gtp': 'enable',
'local-traffic': 'enable',
'multicast-traffic': 'enable',
'netscan-discovery': 'test_value_11,',
'netscan-vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer-traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
}
set_method_mock.assert_called_with('log.syslogd2', '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,223 @@
# 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_log_syslogd2_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_log_syslogd2_setting.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_log_syslogd2_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',
'log_syslogd2_setting': {
'certificate': 'test_value_3',
'enc_algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'port': '8',
'server': '192.168.100.9',
'source_ip': '84.230.14.10',
'ssl_min_proto_version': 'default',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd2_setting.fortios_log_syslogd2(input_data, fos_instance)
expected_data = {
'certificate': 'test_value_3',
'enc-algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'port': '8',
'server': '192.168.100.9',
'source-ip': '84.230.14.10',
'ssl-min-proto-version': 'default',
'status': 'enable'
}
set_method_mock.assert_called_with('log.syslogd2', '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_log_syslogd2_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',
'log_syslogd2_setting': {
'certificate': 'test_value_3',
'enc_algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'port': '8',
'server': '192.168.100.9',
'source_ip': '84.230.14.10',
'ssl_min_proto_version': 'default',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd2_setting.fortios_log_syslogd2(input_data, fos_instance)
expected_data = {
'certificate': 'test_value_3',
'enc-algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'port': '8',
'server': '192.168.100.9',
'source-ip': '84.230.14.10',
'ssl-min-proto-version': 'default',
'status': 'enable'
}
set_method_mock.assert_called_with('log.syslogd2', '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_log_syslogd2_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',
'log_syslogd2_setting': {
'certificate': 'test_value_3',
'enc_algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'port': '8',
'server': '192.168.100.9',
'source_ip': '84.230.14.10',
'ssl_min_proto_version': 'default',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd2_setting.fortios_log_syslogd2(input_data, fos_instance)
expected_data = {
'certificate': 'test_value_3',
'enc-algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'port': '8',
'server': '192.168.100.9',
'source-ip': '84.230.14.10',
'ssl-min-proto-version': 'default',
'status': 'enable'
}
set_method_mock.assert_called_with('log.syslogd2', '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_log_syslogd2_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',
'log_syslogd2_setting': {
'random_attribute_not_valid': 'tag',
'certificate': 'test_value_3',
'enc_algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'port': '8',
'server': '192.168.100.9',
'source_ip': '84.230.14.10',
'ssl_min_proto_version': 'default',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd2_setting.fortios_log_syslogd2(input_data, fos_instance)
expected_data = {
'certificate': 'test_value_3',
'enc-algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'port': '8',
'server': '192.168.100.9',
'source-ip': '84.230.14.10',
'ssl-min-proto-version': 'default',
'status': 'enable'
}
set_method_mock.assert_called_with('log.syslogd2', '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,255 @@
# 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_log_syslogd3_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_log_syslogd3_filter.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_log_syslogd3_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',
'log_syslogd3_filter': {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter_type': 'include',
'forward_traffic': 'enable',
'gtp': 'enable',
'local_traffic': 'enable',
'multicast_traffic': 'enable',
'netscan_discovery': 'test_value_11,',
'netscan_vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer_traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd3_filter.fortios_log_syslogd3(input_data, fos_instance)
expected_data = {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter-type': 'include',
'forward-traffic': 'enable',
'gtp': 'enable',
'local-traffic': 'enable',
'multicast-traffic': 'enable',
'netscan-discovery': 'test_value_11,',
'netscan-vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer-traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
}
set_method_mock.assert_called_with('log.syslogd3', '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_log_syslogd3_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',
'log_syslogd3_filter': {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter_type': 'include',
'forward_traffic': 'enable',
'gtp': 'enable',
'local_traffic': 'enable',
'multicast_traffic': 'enable',
'netscan_discovery': 'test_value_11,',
'netscan_vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer_traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd3_filter.fortios_log_syslogd3(input_data, fos_instance)
expected_data = {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter-type': 'include',
'forward-traffic': 'enable',
'gtp': 'enable',
'local-traffic': 'enable',
'multicast-traffic': 'enable',
'netscan-discovery': 'test_value_11,',
'netscan-vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer-traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
}
set_method_mock.assert_called_with('log.syslogd3', '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_log_syslogd3_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',
'log_syslogd3_filter': {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter_type': 'include',
'forward_traffic': 'enable',
'gtp': 'enable',
'local_traffic': 'enable',
'multicast_traffic': 'enable',
'netscan_discovery': 'test_value_11,',
'netscan_vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer_traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd3_filter.fortios_log_syslogd3(input_data, fos_instance)
expected_data = {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter-type': 'include',
'forward-traffic': 'enable',
'gtp': 'enable',
'local-traffic': 'enable',
'multicast-traffic': 'enable',
'netscan-discovery': 'test_value_11,',
'netscan-vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer-traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
}
set_method_mock.assert_called_with('log.syslogd3', '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_log_syslogd3_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',
'log_syslogd3_filter': {
'random_attribute_not_valid': 'tag',
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter_type': 'include',
'forward_traffic': 'enable',
'gtp': 'enable',
'local_traffic': 'enable',
'multicast_traffic': 'enable',
'netscan_discovery': 'test_value_11,',
'netscan_vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer_traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd3_filter.fortios_log_syslogd3(input_data, fos_instance)
expected_data = {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter-type': 'include',
'forward-traffic': 'enable',
'gtp': 'enable',
'local-traffic': 'enable',
'multicast-traffic': 'enable',
'netscan-discovery': 'test_value_11,',
'netscan-vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer-traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
}
set_method_mock.assert_called_with('log.syslogd3', '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,223 @@
# 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_log_syslogd3_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_log_syslogd3_setting.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_log_syslogd3_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',
'log_syslogd3_setting': {
'certificate': 'test_value_3',
'enc_algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'port': '8',
'server': '192.168.100.9',
'source_ip': '84.230.14.10',
'ssl_min_proto_version': 'default',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd3_setting.fortios_log_syslogd3(input_data, fos_instance)
expected_data = {
'certificate': 'test_value_3',
'enc-algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'port': '8',
'server': '192.168.100.9',
'source-ip': '84.230.14.10',
'ssl-min-proto-version': 'default',
'status': 'enable'
}
set_method_mock.assert_called_with('log.syslogd3', '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_log_syslogd3_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',
'log_syslogd3_setting': {
'certificate': 'test_value_3',
'enc_algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'port': '8',
'server': '192.168.100.9',
'source_ip': '84.230.14.10',
'ssl_min_proto_version': 'default',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd3_setting.fortios_log_syslogd3(input_data, fos_instance)
expected_data = {
'certificate': 'test_value_3',
'enc-algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'port': '8',
'server': '192.168.100.9',
'source-ip': '84.230.14.10',
'ssl-min-proto-version': 'default',
'status': 'enable'
}
set_method_mock.assert_called_with('log.syslogd3', '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_log_syslogd3_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',
'log_syslogd3_setting': {
'certificate': 'test_value_3',
'enc_algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'port': '8',
'server': '192.168.100.9',
'source_ip': '84.230.14.10',
'ssl_min_proto_version': 'default',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd3_setting.fortios_log_syslogd3(input_data, fos_instance)
expected_data = {
'certificate': 'test_value_3',
'enc-algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'port': '8',
'server': '192.168.100.9',
'source-ip': '84.230.14.10',
'ssl-min-proto-version': 'default',
'status': 'enable'
}
set_method_mock.assert_called_with('log.syslogd3', '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_log_syslogd3_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',
'log_syslogd3_setting': {
'random_attribute_not_valid': 'tag',
'certificate': 'test_value_3',
'enc_algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'port': '8',
'server': '192.168.100.9',
'source_ip': '84.230.14.10',
'ssl_min_proto_version': 'default',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd3_setting.fortios_log_syslogd3(input_data, fos_instance)
expected_data = {
'certificate': 'test_value_3',
'enc-algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'port': '8',
'server': '192.168.100.9',
'source-ip': '84.230.14.10',
'ssl-min-proto-version': 'default',
'status': 'enable'
}
set_method_mock.assert_called_with('log.syslogd3', '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,255 @@
# 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_log_syslogd4_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_log_syslogd4_filter.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_log_syslogd4_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',
'log_syslogd4_filter': {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter_type': 'include',
'forward_traffic': 'enable',
'gtp': 'enable',
'local_traffic': 'enable',
'multicast_traffic': 'enable',
'netscan_discovery': 'test_value_11,',
'netscan_vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer_traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd4_filter.fortios_log_syslogd4(input_data, fos_instance)
expected_data = {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter-type': 'include',
'forward-traffic': 'enable',
'gtp': 'enable',
'local-traffic': 'enable',
'multicast-traffic': 'enable',
'netscan-discovery': 'test_value_11,',
'netscan-vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer-traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
}
set_method_mock.assert_called_with('log.syslogd4', '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_log_syslogd4_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',
'log_syslogd4_filter': {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter_type': 'include',
'forward_traffic': 'enable',
'gtp': 'enable',
'local_traffic': 'enable',
'multicast_traffic': 'enable',
'netscan_discovery': 'test_value_11,',
'netscan_vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer_traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd4_filter.fortios_log_syslogd4(input_data, fos_instance)
expected_data = {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter-type': 'include',
'forward-traffic': 'enable',
'gtp': 'enable',
'local-traffic': 'enable',
'multicast-traffic': 'enable',
'netscan-discovery': 'test_value_11,',
'netscan-vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer-traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
}
set_method_mock.assert_called_with('log.syslogd4', '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_log_syslogd4_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',
'log_syslogd4_filter': {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter_type': 'include',
'forward_traffic': 'enable',
'gtp': 'enable',
'local_traffic': 'enable',
'multicast_traffic': 'enable',
'netscan_discovery': 'test_value_11,',
'netscan_vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer_traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd4_filter.fortios_log_syslogd4(input_data, fos_instance)
expected_data = {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter-type': 'include',
'forward-traffic': 'enable',
'gtp': 'enable',
'local-traffic': 'enable',
'multicast-traffic': 'enable',
'netscan-discovery': 'test_value_11,',
'netscan-vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer-traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
}
set_method_mock.assert_called_with('log.syslogd4', '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_log_syslogd4_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',
'log_syslogd4_filter': {
'random_attribute_not_valid': 'tag',
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter_type': 'include',
'forward_traffic': 'enable',
'gtp': 'enable',
'local_traffic': 'enable',
'multicast_traffic': 'enable',
'netscan_discovery': 'test_value_11,',
'netscan_vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer_traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd4_filter.fortios_log_syslogd4(input_data, fos_instance)
expected_data = {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter-type': 'include',
'forward-traffic': 'enable',
'gtp': 'enable',
'local-traffic': 'enable',
'multicast-traffic': 'enable',
'netscan-discovery': 'test_value_11,',
'netscan-vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer-traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
}
set_method_mock.assert_called_with('log.syslogd4', '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,223 @@
# 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_log_syslogd4_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_log_syslogd4_setting.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_log_syslogd4_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',
'log_syslogd4_setting': {
'certificate': 'test_value_3',
'enc_algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'port': '8',
'server': '192.168.100.9',
'source_ip': '84.230.14.10',
'ssl_min_proto_version': 'default',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd4_setting.fortios_log_syslogd4(input_data, fos_instance)
expected_data = {
'certificate': 'test_value_3',
'enc-algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'port': '8',
'server': '192.168.100.9',
'source-ip': '84.230.14.10',
'ssl-min-proto-version': 'default',
'status': 'enable'
}
set_method_mock.assert_called_with('log.syslogd4', '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_log_syslogd4_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',
'log_syslogd4_setting': {
'certificate': 'test_value_3',
'enc_algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'port': '8',
'server': '192.168.100.9',
'source_ip': '84.230.14.10',
'ssl_min_proto_version': 'default',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd4_setting.fortios_log_syslogd4(input_data, fos_instance)
expected_data = {
'certificate': 'test_value_3',
'enc-algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'port': '8',
'server': '192.168.100.9',
'source-ip': '84.230.14.10',
'ssl-min-proto-version': 'default',
'status': 'enable'
}
set_method_mock.assert_called_with('log.syslogd4', '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_log_syslogd4_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',
'log_syslogd4_setting': {
'certificate': 'test_value_3',
'enc_algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'port': '8',
'server': '192.168.100.9',
'source_ip': '84.230.14.10',
'ssl_min_proto_version': 'default',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd4_setting.fortios_log_syslogd4(input_data, fos_instance)
expected_data = {
'certificate': 'test_value_3',
'enc-algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'port': '8',
'server': '192.168.100.9',
'source-ip': '84.230.14.10',
'ssl-min-proto-version': 'default',
'status': 'enable'
}
set_method_mock.assert_called_with('log.syslogd4', '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_log_syslogd4_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',
'log_syslogd4_setting': {
'random_attribute_not_valid': 'tag',
'certificate': 'test_value_3',
'enc_algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'port': '8',
'server': '192.168.100.9',
'source_ip': '84.230.14.10',
'ssl_min_proto_version': 'default',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd4_setting.fortios_log_syslogd4(input_data, fos_instance)
expected_data = {
'certificate': 'test_value_3',
'enc-algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'port': '8',
'server': '192.168.100.9',
'source-ip': '84.230.14.10',
'ssl-min-proto-version': 'default',
'status': 'enable'
}
set_method_mock.assert_called_with('log.syslogd4', '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,255 @@
# 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_log_syslogd_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_log_syslogd_filter.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_log_syslogd_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',
'log_syslogd_filter': {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter_type': 'include',
'forward_traffic': 'enable',
'gtp': 'enable',
'local_traffic': 'enable',
'multicast_traffic': 'enable',
'netscan_discovery': 'test_value_11,',
'netscan_vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer_traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd_filter.fortios_log_syslogd(input_data, fos_instance)
expected_data = {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter-type': 'include',
'forward-traffic': 'enable',
'gtp': 'enable',
'local-traffic': 'enable',
'multicast-traffic': 'enable',
'netscan-discovery': 'test_value_11,',
'netscan-vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer-traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
}
set_method_mock.assert_called_with('log.syslogd', '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_log_syslogd_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',
'log_syslogd_filter': {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter_type': 'include',
'forward_traffic': 'enable',
'gtp': 'enable',
'local_traffic': 'enable',
'multicast_traffic': 'enable',
'netscan_discovery': 'test_value_11,',
'netscan_vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer_traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd_filter.fortios_log_syslogd(input_data, fos_instance)
expected_data = {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter-type': 'include',
'forward-traffic': 'enable',
'gtp': 'enable',
'local-traffic': 'enable',
'multicast-traffic': 'enable',
'netscan-discovery': 'test_value_11,',
'netscan-vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer-traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
}
set_method_mock.assert_called_with('log.syslogd', '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_log_syslogd_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',
'log_syslogd_filter': {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter_type': 'include',
'forward_traffic': 'enable',
'gtp': 'enable',
'local_traffic': 'enable',
'multicast_traffic': 'enable',
'netscan_discovery': 'test_value_11,',
'netscan_vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer_traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd_filter.fortios_log_syslogd(input_data, fos_instance)
expected_data = {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter-type': 'include',
'forward-traffic': 'enable',
'gtp': 'enable',
'local-traffic': 'enable',
'multicast-traffic': 'enable',
'netscan-discovery': 'test_value_11,',
'netscan-vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer-traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
}
set_method_mock.assert_called_with('log.syslogd', '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_log_syslogd_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',
'log_syslogd_filter': {
'random_attribute_not_valid': 'tag',
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter_type': 'include',
'forward_traffic': 'enable',
'gtp': 'enable',
'local_traffic': 'enable',
'multicast_traffic': 'enable',
'netscan_discovery': 'test_value_11,',
'netscan_vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer_traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd_filter.fortios_log_syslogd(input_data, fos_instance)
expected_data = {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter-type': 'include',
'forward-traffic': 'enable',
'gtp': 'enable',
'local-traffic': 'enable',
'multicast-traffic': 'enable',
'netscan-discovery': 'test_value_11,',
'netscan-vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer-traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
}
set_method_mock.assert_called_with('log.syslogd', '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,255 @@
# 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_log_syslogd_override_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_log_syslogd_override_filter.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_log_syslogd_override_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',
'log_syslogd_override_filter': {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter_type': 'include',
'forward_traffic': 'enable',
'gtp': 'enable',
'local_traffic': 'enable',
'multicast_traffic': 'enable',
'netscan_discovery': 'test_value_11,',
'netscan_vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer_traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd_override_filter.fortios_log_syslogd(input_data, fos_instance)
expected_data = {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter-type': 'include',
'forward-traffic': 'enable',
'gtp': 'enable',
'local-traffic': 'enable',
'multicast-traffic': 'enable',
'netscan-discovery': 'test_value_11,',
'netscan-vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer-traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
}
set_method_mock.assert_called_with('log.syslogd', 'override-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_log_syslogd_override_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',
'log_syslogd_override_filter': {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter_type': 'include',
'forward_traffic': 'enable',
'gtp': 'enable',
'local_traffic': 'enable',
'multicast_traffic': 'enable',
'netscan_discovery': 'test_value_11,',
'netscan_vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer_traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd_override_filter.fortios_log_syslogd(input_data, fos_instance)
expected_data = {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter-type': 'include',
'forward-traffic': 'enable',
'gtp': 'enable',
'local-traffic': 'enable',
'multicast-traffic': 'enable',
'netscan-discovery': 'test_value_11,',
'netscan-vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer-traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
}
set_method_mock.assert_called_with('log.syslogd', 'override-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_log_syslogd_override_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',
'log_syslogd_override_filter': {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter_type': 'include',
'forward_traffic': 'enable',
'gtp': 'enable',
'local_traffic': 'enable',
'multicast_traffic': 'enable',
'netscan_discovery': 'test_value_11,',
'netscan_vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer_traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd_override_filter.fortios_log_syslogd(input_data, fos_instance)
expected_data = {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter-type': 'include',
'forward-traffic': 'enable',
'gtp': 'enable',
'local-traffic': 'enable',
'multicast-traffic': 'enable',
'netscan-discovery': 'test_value_11,',
'netscan-vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer-traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
}
set_method_mock.assert_called_with('log.syslogd', 'override-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_log_syslogd_override_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',
'log_syslogd_override_filter': {
'random_attribute_not_valid': 'tag',
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter_type': 'include',
'forward_traffic': 'enable',
'gtp': 'enable',
'local_traffic': 'enable',
'multicast_traffic': 'enable',
'netscan_discovery': 'test_value_11,',
'netscan_vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer_traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd_override_filter.fortios_log_syslogd(input_data, fos_instance)
expected_data = {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter-type': 'include',
'forward-traffic': 'enable',
'gtp': 'enable',
'local-traffic': 'enable',
'multicast-traffic': 'enable',
'netscan-discovery': 'test_value_11,',
'netscan-vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer-traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
}
set_method_mock.assert_called_with('log.syslogd', 'override-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,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_log_syslogd_override_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_log_syslogd_override_setting.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_log_syslogd_override_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',
'log_syslogd_override_setting': {
'certificate': 'test_value_3',
'enc_algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'override': 'enable',
'port': '9',
'server': '192.168.100.10',
'source_ip': '84.230.14.11',
'ssl_min_proto_version': 'default',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd_override_setting.fortios_log_syslogd(input_data, fos_instance)
expected_data = {
'certificate': 'test_value_3',
'enc-algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'override': 'enable',
'port': '9',
'server': '192.168.100.10',
'source-ip': '84.230.14.11',
'ssl-min-proto-version': 'default',
'status': 'enable'
}
set_method_mock.assert_called_with('log.syslogd', 'override-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_log_syslogd_override_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',
'log_syslogd_override_setting': {
'certificate': 'test_value_3',
'enc_algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'override': 'enable',
'port': '9',
'server': '192.168.100.10',
'source_ip': '84.230.14.11',
'ssl_min_proto_version': 'default',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd_override_setting.fortios_log_syslogd(input_data, fos_instance)
expected_data = {
'certificate': 'test_value_3',
'enc-algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'override': 'enable',
'port': '9',
'server': '192.168.100.10',
'source-ip': '84.230.14.11',
'ssl-min-proto-version': 'default',
'status': 'enable'
}
set_method_mock.assert_called_with('log.syslogd', 'override-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_log_syslogd_override_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',
'log_syslogd_override_setting': {
'certificate': 'test_value_3',
'enc_algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'override': 'enable',
'port': '9',
'server': '192.168.100.10',
'source_ip': '84.230.14.11',
'ssl_min_proto_version': 'default',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd_override_setting.fortios_log_syslogd(input_data, fos_instance)
expected_data = {
'certificate': 'test_value_3',
'enc-algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'override': 'enable',
'port': '9',
'server': '192.168.100.10',
'source-ip': '84.230.14.11',
'ssl-min-proto-version': 'default',
'status': 'enable'
}
set_method_mock.assert_called_with('log.syslogd', 'override-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_log_syslogd_override_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',
'log_syslogd_override_setting': {
'random_attribute_not_valid': 'tag',
'certificate': 'test_value_3',
'enc_algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'override': 'enable',
'port': '9',
'server': '192.168.100.10',
'source_ip': '84.230.14.11',
'ssl_min_proto_version': 'default',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd_override_setting.fortios_log_syslogd(input_data, fos_instance)
expected_data = {
'certificate': 'test_value_3',
'enc-algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'override': 'enable',
'port': '9',
'server': '192.168.100.10',
'source-ip': '84.230.14.11',
'ssl-min-proto-version': 'default',
'status': 'enable'
}
set_method_mock.assert_called_with('log.syslogd', 'override-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,223 @@
# 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_log_syslogd_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_log_syslogd_setting.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_log_syslogd_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',
'log_syslogd_setting': {
'certificate': 'test_value_3',
'enc_algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'port': '8',
'server': '192.168.100.9',
'source_ip': '84.230.14.10',
'ssl_min_proto_version': 'default',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd_setting.fortios_log_syslogd(input_data, fos_instance)
expected_data = {
'certificate': 'test_value_3',
'enc-algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'port': '8',
'server': '192.168.100.9',
'source-ip': '84.230.14.10',
'ssl-min-proto-version': 'default',
'status': 'enable'
}
set_method_mock.assert_called_with('log.syslogd', '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_log_syslogd_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',
'log_syslogd_setting': {
'certificate': 'test_value_3',
'enc_algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'port': '8',
'server': '192.168.100.9',
'source_ip': '84.230.14.10',
'ssl_min_proto_version': 'default',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd_setting.fortios_log_syslogd(input_data, fos_instance)
expected_data = {
'certificate': 'test_value_3',
'enc-algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'port': '8',
'server': '192.168.100.9',
'source-ip': '84.230.14.10',
'ssl-min-proto-version': 'default',
'status': 'enable'
}
set_method_mock.assert_called_with('log.syslogd', '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_log_syslogd_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',
'log_syslogd_setting': {
'certificate': 'test_value_3',
'enc_algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'port': '8',
'server': '192.168.100.9',
'source_ip': '84.230.14.10',
'ssl_min_proto_version': 'default',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd_setting.fortios_log_syslogd(input_data, fos_instance)
expected_data = {
'certificate': 'test_value_3',
'enc-algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'port': '8',
'server': '192.168.100.9',
'source-ip': '84.230.14.10',
'ssl-min-proto-version': 'default',
'status': 'enable'
}
set_method_mock.assert_called_with('log.syslogd', '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_log_syslogd_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',
'log_syslogd_setting': {
'random_attribute_not_valid': 'tag',
'certificate': 'test_value_3',
'enc_algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'port': '8',
'server': '192.168.100.9',
'source_ip': '84.230.14.10',
'ssl_min_proto_version': 'default',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_syslogd_setting.fortios_log_syslogd(input_data, fos_instance)
expected_data = {
'certificate': 'test_value_3',
'enc-algorithm': 'high-medium',
'facility': 'kernel',
'format': 'default',
'mode': 'udp',
'port': '8',
'server': '192.168.100.9',
'source-ip': '84.230.14.10',
'ssl-min-proto-version': 'default',
'status': 'enable'
}
set_method_mock.assert_called_with('log.syslogd', '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,175 @@
# 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_log_threat_weight
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_log_threat_weight.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_log_threat_weight_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',
'log_threat_weight': {'blocked_connection': 'disable',
'failed_connection': 'disable',
'status': 'enable',
'url_block_detected': 'disable',
},
'vdom': 'root'}
is_error, changed, response = fortios_log_threat_weight.fortios_log(input_data, fos_instance)
expected_data = {'blocked-connection': 'disable',
'failed-connection': 'disable',
'status': 'enable',
'url-block-detected': 'disable',
}
set_method_mock.assert_called_with('log', 'threat-weight', 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_log_threat_weight_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',
'log_threat_weight': {'blocked_connection': 'disable',
'failed_connection': 'disable',
'status': 'enable',
'url_block_detected': 'disable',
},
'vdom': 'root'}
is_error, changed, response = fortios_log_threat_weight.fortios_log(input_data, fos_instance)
expected_data = {'blocked-connection': 'disable',
'failed-connection': 'disable',
'status': 'enable',
'url-block-detected': 'disable',
}
set_method_mock.assert_called_with('log', 'threat-weight', 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_log_threat_weight_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',
'log_threat_weight': {'blocked_connection': 'disable',
'failed_connection': 'disable',
'status': 'enable',
'url_block_detected': 'disable',
},
'vdom': 'root'}
is_error, changed, response = fortios_log_threat_weight.fortios_log(input_data, fos_instance)
expected_data = {'blocked-connection': 'disable',
'failed-connection': 'disable',
'status': 'enable',
'url-block-detected': 'disable',
}
set_method_mock.assert_called_with('log', 'threat-weight', 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_log_threat_weight_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',
'log_threat_weight': {
'random_attribute_not_valid': 'tag', 'blocked_connection': 'disable',
'failed_connection': 'disable',
'status': 'enable',
'url_block_detected': 'disable',
},
'vdom': 'root'}
is_error, changed, response = fortios_log_threat_weight.fortios_log(input_data, fos_instance)
expected_data = {'blocked-connection': 'disable',
'failed-connection': 'disable',
'status': 'enable',
'url-block-detected': 'disable',
}
set_method_mock.assert_called_with('log', 'threat-weight', 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,255 @@
# 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_log_webtrends_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_log_webtrends_filter.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_log_webtrends_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',
'log_webtrends_filter': {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter_type': 'include',
'forward_traffic': 'enable',
'gtp': 'enable',
'local_traffic': 'enable',
'multicast_traffic': 'enable',
'netscan_discovery': 'test_value_11,',
'netscan_vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer_traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_webtrends_filter.fortios_log_webtrends(input_data, fos_instance)
expected_data = {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter-type': 'include',
'forward-traffic': 'enable',
'gtp': 'enable',
'local-traffic': 'enable',
'multicast-traffic': 'enable',
'netscan-discovery': 'test_value_11,',
'netscan-vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer-traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
}
set_method_mock.assert_called_with('log.webtrends', '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_log_webtrends_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',
'log_webtrends_filter': {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter_type': 'include',
'forward_traffic': 'enable',
'gtp': 'enable',
'local_traffic': 'enable',
'multicast_traffic': 'enable',
'netscan_discovery': 'test_value_11,',
'netscan_vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer_traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_webtrends_filter.fortios_log_webtrends(input_data, fos_instance)
expected_data = {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter-type': 'include',
'forward-traffic': 'enable',
'gtp': 'enable',
'local-traffic': 'enable',
'multicast-traffic': 'enable',
'netscan-discovery': 'test_value_11,',
'netscan-vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer-traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
}
set_method_mock.assert_called_with('log.webtrends', '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_log_webtrends_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',
'log_webtrends_filter': {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter_type': 'include',
'forward_traffic': 'enable',
'gtp': 'enable',
'local_traffic': 'enable',
'multicast_traffic': 'enable',
'netscan_discovery': 'test_value_11,',
'netscan_vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer_traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_webtrends_filter.fortios_log_webtrends(input_data, fos_instance)
expected_data = {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter-type': 'include',
'forward-traffic': 'enable',
'gtp': 'enable',
'local-traffic': 'enable',
'multicast-traffic': 'enable',
'netscan-discovery': 'test_value_11,',
'netscan-vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer-traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
}
set_method_mock.assert_called_with('log.webtrends', '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_log_webtrends_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',
'log_webtrends_filter': {
'random_attribute_not_valid': 'tag',
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter_type': 'include',
'forward_traffic': 'enable',
'gtp': 'enable',
'local_traffic': 'enable',
'multicast_traffic': 'enable',
'netscan_discovery': 'test_value_11,',
'netscan_vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer_traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_webtrends_filter.fortios_log_webtrends(input_data, fos_instance)
expected_data = {
'anomaly': 'enable',
'dns': 'enable',
'filter': 'test_value_5',
'filter-type': 'include',
'forward-traffic': 'enable',
'gtp': 'enable',
'local-traffic': 'enable',
'multicast-traffic': 'enable',
'netscan-discovery': 'test_value_11,',
'netscan-vulnerability': 'test_value_12,',
'severity': 'emergency',
'sniffer-traffic': 'enable',
'ssh': 'enable',
'voip': 'enable'
}
set_method_mock.assert_called_with('log.webtrends', '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,159 @@
# 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_log_webtrends_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_log_webtrends_setting.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_log_webtrends_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',
'log_webtrends_setting': {
'server': '192.168.100.3',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_webtrends_setting.fortios_log_webtrends(input_data, fos_instance)
expected_data = {
'server': '192.168.100.3',
'status': 'enable'
}
set_method_mock.assert_called_with('log.webtrends', '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_log_webtrends_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',
'log_webtrends_setting': {
'server': '192.168.100.3',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_webtrends_setting.fortios_log_webtrends(input_data, fos_instance)
expected_data = {
'server': '192.168.100.3',
'status': 'enable'
}
set_method_mock.assert_called_with('log.webtrends', '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_log_webtrends_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',
'log_webtrends_setting': {
'server': '192.168.100.3',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_webtrends_setting.fortios_log_webtrends(input_data, fos_instance)
expected_data = {
'server': '192.168.100.3',
'status': 'enable'
}
set_method_mock.assert_called_with('log.webtrends', '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_log_webtrends_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',
'log_webtrends_setting': {
'random_attribute_not_valid': 'tag',
'server': '192.168.100.3',
'status': 'enable'
},
'vdom': 'root'}
is_error, changed, response = fortios_log_webtrends_setting.fortios_log_webtrends(input_data, fos_instance)
expected_data = {
'server': '192.168.100.3',
'status': 'enable'
}
set_method_mock.assert_called_with('log.webtrends', '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,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_report_chart
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_report_chart.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_report_chart_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',
'report_chart': {
'background': 'test_value_3',
'category': 'misc',
'color_palette': 'test_value_5',
'comments': 'test_value_6',
'dataset': 'test_value_7',
'dimension': '2D',
'favorite': 'no',
'graph_type': 'none',
'legend': 'enable',
'legend_font_size': '12',
'name': 'default_name_13',
'period': 'last24h',
'policy': '15',
'style': 'auto',
'title': 'test_value_17',
'title_font_size': '18',
'type': 'graph',
},
'vdom': 'root'}
is_error, changed, response = fortios_report_chart.fortios_report(input_data, fos_instance)
expected_data = {
'background': 'test_value_3',
'category': 'misc',
'color-palette': 'test_value_5',
'comments': 'test_value_6',
'dataset': 'test_value_7',
'dimension': '2D',
'favorite': 'no',
'graph-type': 'none',
'legend': 'enable',
'legend-font-size': '12',
'name': 'default_name_13',
'period': 'last24h',
'policy': '15',
'style': 'auto',
'title': 'test_value_17',
'title-font-size': '18',
'type': 'graph',
}
set_method_mock.assert_called_with('report', 'chart', 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_report_chart_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',
'report_chart': {
'background': 'test_value_3',
'category': 'misc',
'color_palette': 'test_value_5',
'comments': 'test_value_6',
'dataset': 'test_value_7',
'dimension': '2D',
'favorite': 'no',
'graph_type': 'none',
'legend': 'enable',
'legend_font_size': '12',
'name': 'default_name_13',
'period': 'last24h',
'policy': '15',
'style': 'auto',
'title': 'test_value_17',
'title_font_size': '18',
'type': 'graph',
},
'vdom': 'root'}
is_error, changed, response = fortios_report_chart.fortios_report(input_data, fos_instance)
expected_data = {
'background': 'test_value_3',
'category': 'misc',
'color-palette': 'test_value_5',
'comments': 'test_value_6',
'dataset': 'test_value_7',
'dimension': '2D',
'favorite': 'no',
'graph-type': 'none',
'legend': 'enable',
'legend-font-size': '12',
'name': 'default_name_13',
'period': 'last24h',
'policy': '15',
'style': 'auto',
'title': 'test_value_17',
'title-font-size': '18',
'type': 'graph',
}
set_method_mock.assert_called_with('report', 'chart', 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_report_chart_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',
'report_chart': {
'background': 'test_value_3',
'category': 'misc',
'color_palette': 'test_value_5',
'comments': 'test_value_6',
'dataset': 'test_value_7',
'dimension': '2D',
'favorite': 'no',
'graph_type': 'none',
'legend': 'enable',
'legend_font_size': '12',
'name': 'default_name_13',
'period': 'last24h',
'policy': '15',
'style': 'auto',
'title': 'test_value_17',
'title_font_size': '18',
'type': 'graph',
},
'vdom': 'root'}
is_error, changed, response = fortios_report_chart.fortios_report(input_data, fos_instance)
delete_method_mock.assert_called_with('report', 'chart', 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_report_chart_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',
'report_chart': {
'background': 'test_value_3',
'category': 'misc',
'color_palette': 'test_value_5',
'comments': 'test_value_6',
'dataset': 'test_value_7',
'dimension': '2D',
'favorite': 'no',
'graph_type': 'none',
'legend': 'enable',
'legend_font_size': '12',
'name': 'default_name_13',
'period': 'last24h',
'policy': '15',
'style': 'auto',
'title': 'test_value_17',
'title_font_size': '18',
'type': 'graph',
},
'vdom': 'root'}
is_error, changed, response = fortios_report_chart.fortios_report(input_data, fos_instance)
delete_method_mock.assert_called_with('report', 'chart', 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_report_chart_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',
'report_chart': {
'background': 'test_value_3',
'category': 'misc',
'color_palette': 'test_value_5',
'comments': 'test_value_6',
'dataset': 'test_value_7',
'dimension': '2D',
'favorite': 'no',
'graph_type': 'none',
'legend': 'enable',
'legend_font_size': '12',
'name': 'default_name_13',
'period': 'last24h',
'policy': '15',
'style': 'auto',
'title': 'test_value_17',
'title_font_size': '18',
'type': 'graph',
},
'vdom': 'root'}
is_error, changed, response = fortios_report_chart.fortios_report(input_data, fos_instance)
expected_data = {
'background': 'test_value_3',
'category': 'misc',
'color-palette': 'test_value_5',
'comments': 'test_value_6',
'dataset': 'test_value_7',
'dimension': '2D',
'favorite': 'no',
'graph-type': 'none',
'legend': 'enable',
'legend-font-size': '12',
'name': 'default_name_13',
'period': 'last24h',
'policy': '15',
'style': 'auto',
'title': 'test_value_17',
'title-font-size': '18',
'type': 'graph',
}
set_method_mock.assert_called_with('report', 'chart', 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_report_chart_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',
'report_chart': {
'random_attribute_not_valid': 'tag',
'background': 'test_value_3',
'category': 'misc',
'color_palette': 'test_value_5',
'comments': 'test_value_6',
'dataset': 'test_value_7',
'dimension': '2D',
'favorite': 'no',
'graph_type': 'none',
'legend': 'enable',
'legend_font_size': '12',
'name': 'default_name_13',
'period': 'last24h',
'policy': '15',
'style': 'auto',
'title': 'test_value_17',
'title_font_size': '18',
'type': 'graph',
},
'vdom': 'root'}
is_error, changed, response = fortios_report_chart.fortios_report(input_data, fos_instance)
expected_data = {
'background': 'test_value_3',
'category': 'misc',
'color-palette': 'test_value_5',
'comments': 'test_value_6',
'dataset': 'test_value_7',
'dimension': '2D',
'favorite': 'no',
'graph-type': 'none',
'legend': 'enable',
'legend-font-size': '12',
'name': 'default_name_13',
'period': 'last24h',
'policy': '15',
'style': 'auto',
'title': 'test_value_17',
'title-font-size': '18',
'type': 'graph',
}
set_method_mock.assert_called_with('report', 'chart', 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_report_dataset
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_report_dataset.Connection')
return connection_class_mock
fos_instance = FortiOSHandler(connection_mock)
def test_report_dataset_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',
'report_dataset': {'name': 'default_name_3',
'policy': '4',
'query': 'test_value_5'
},
'vdom': 'root'}
is_error, changed, response = fortios_report_dataset.fortios_report(input_data, fos_instance)
expected_data = {'name': 'default_name_3',
'policy': '4',
'query': 'test_value_5'
}
set_method_mock.assert_called_with('report', 'dataset', 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_report_dataset_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',
'report_dataset': {'name': 'default_name_3',
'policy': '4',
'query': 'test_value_5'
},
'vdom': 'root'}
is_error, changed, response = fortios_report_dataset.fortios_report(input_data, fos_instance)
expected_data = {'name': 'default_name_3',
'policy': '4',
'query': 'test_value_5'
}
set_method_mock.assert_called_with('report', 'dataset', 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_report_dataset_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',
'report_dataset': {'name': 'default_name_3',
'policy': '4',
'query': 'test_value_5'
},
'vdom': 'root'}
is_error, changed, response = fortios_report_dataset.fortios_report(input_data, fos_instance)
delete_method_mock.assert_called_with('report', 'dataset', 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_report_dataset_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',
'report_dataset': {'name': 'default_name_3',
'policy': '4',
'query': 'test_value_5'
},
'vdom': 'root'}
is_error, changed, response = fortios_report_dataset.fortios_report(input_data, fos_instance)
delete_method_mock.assert_called_with('report', 'dataset', 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_report_dataset_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',
'report_dataset': {'name': 'default_name_3',
'policy': '4',
'query': 'test_value_5'
},
'vdom': 'root'}
is_error, changed, response = fortios_report_dataset.fortios_report(input_data, fos_instance)
expected_data = {'name': 'default_name_3',
'policy': '4',
'query': 'test_value_5'
}
set_method_mock.assert_called_with('report', 'dataset', 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_report_dataset_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',
'report_dataset': {
'random_attribute_not_valid': 'tag', 'name': 'default_name_3',
'policy': '4',
'query': 'test_value_5'
},
'vdom': 'root'}
is_error, changed, response = fortios_report_dataset.fortios_report(input_data, fos_instance)
expected_data = {'name': 'default_name_3',
'policy': '4',
'query': 'test_value_5'
}
set_method_mock.assert_called_with('report', 'dataset', 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