From a6b124cccc74f5501e0fe7335afe9f1a60fcc3b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Angel=20Mu=C3=B1oz=20Gonz=C3=A1lez?= Date: Sun, 25 Aug 2019 09:24:45 +0200 Subject: [PATCH] FortiOS modules for 2.9 - 7 (#61217) --- .../fortios_log_memory_global_setting.py | 152 ++++--- .../fortios/fortios_log_memory_setting.py | 116 +++-- .../fortios/fortios_log_null_device_filter.py | 176 +++++--- .../fortios_log_null_device_setting.py | 115 +++-- .../network/fortios/fortios_log_setting.py | 260 ++++++----- .../fortios/fortios_log_syslogd2_filter.py | 176 +++++--- .../fortios/fortios_log_syslogd2_setting.py | 165 ++++--- .../fortios/fortios_log_syslogd3_filter.py | 176 +++++--- .../fortios/fortios_log_syslogd3_setting.py | 165 ++++--- .../fortios/fortios_log_syslogd4_filter.py | 176 +++++--- .../fortios/fortios_log_syslogd4_setting.py | 165 ++++--- .../fortios/fortios_log_syslogd_filter.py | 176 +++++--- .../fortios_log_syslogd_override_filter.py | 176 +++++--- .../fortios_log_syslogd_override_setting.py | 164 ++++--- .../fortios/fortios_log_syslogd_setting.py | 165 ++++--- .../fortios/fortios_log_threat_weight.py | 270 ++++++++---- .../fortios/fortios_log_webtrends_filter.py | 159 +++++-- .../fortios/fortios_log_webtrends_setting.py | 116 +++-- .../network/fortios/fortios_report_chart.py | 410 +++++++++++------- .../network/fortios/fortios_report_dataset.py | 165 ++++--- test/sanity/ignore.txt | 37 -- .../test_fortios_log_memory_global_setting.py | 175 ++++++++ .../test_fortios_log_memory_setting.py | 159 +++++++ .../test_fortios_log_null_device_filter.py | 255 +++++++++++ .../test_fortios_log_null_device_setting.py | 151 +++++++ .../fortios/test_fortios_log_setting.py | 279 ++++++++++++ .../test_fortios_log_syslogd2_filter.py | 255 +++++++++++ .../test_fortios_log_syslogd2_setting.py | 223 ++++++++++ .../test_fortios_log_syslogd3_filter.py | 255 +++++++++++ .../test_fortios_log_syslogd3_setting.py | 223 ++++++++++ .../test_fortios_log_syslogd4_filter.py | 255 +++++++++++ .../test_fortios_log_syslogd4_setting.py | 223 ++++++++++ .../test_fortios_log_syslogd_filter.py | 255 +++++++++++ ...est_fortios_log_syslogd_override_filter.py | 255 +++++++++++ ...st_fortios_log_syslogd_override_setting.py | 231 ++++++++++ .../test_fortios_log_syslogd_setting.py | 223 ++++++++++ .../fortios/test_fortios_log_threat_weight.py | 175 ++++++++ .../test_fortios_log_webtrends_filter.py | 255 +++++++++++ .../test_fortios_log_webtrends_setting.py | 159 +++++++ .../fortios/test_fortios_report_chart.py | 369 ++++++++++++++++ .../fortios/test_fortios_report_dataset.py | 209 +++++++++ 41 files changed, 6915 insertions(+), 1349 deletions(-) create mode 100644 test/units/modules/network/fortios/test_fortios_log_memory_global_setting.py create mode 100644 test/units/modules/network/fortios/test_fortios_log_memory_setting.py create mode 100644 test/units/modules/network/fortios/test_fortios_log_null_device_filter.py create mode 100644 test/units/modules/network/fortios/test_fortios_log_null_device_setting.py create mode 100644 test/units/modules/network/fortios/test_fortios_log_setting.py create mode 100644 test/units/modules/network/fortios/test_fortios_log_syslogd2_filter.py create mode 100644 test/units/modules/network/fortios/test_fortios_log_syslogd2_setting.py create mode 100644 test/units/modules/network/fortios/test_fortios_log_syslogd3_filter.py create mode 100644 test/units/modules/network/fortios/test_fortios_log_syslogd3_setting.py create mode 100644 test/units/modules/network/fortios/test_fortios_log_syslogd4_filter.py create mode 100644 test/units/modules/network/fortios/test_fortios_log_syslogd4_setting.py create mode 100644 test/units/modules/network/fortios/test_fortios_log_syslogd_filter.py create mode 100644 test/units/modules/network/fortios/test_fortios_log_syslogd_override_filter.py create mode 100644 test/units/modules/network/fortios/test_fortios_log_syslogd_override_setting.py create mode 100644 test/units/modules/network/fortios/test_fortios_log_syslogd_setting.py create mode 100644 test/units/modules/network/fortios/test_fortios_log_threat_weight.py create mode 100644 test/units/modules/network/fortios/test_fortios_log_webtrends_filter.py create mode 100644 test/units/modules/network/fortios/test_fortios_log_webtrends_setting.py create mode 100644 test/units/modules/network/fortios/test_fortios_report_chart.py create mode 100644 test/units/modules/network/fortios/test_fortios_report_dataset.py diff --git a/lib/ansible/modules/network/fortios/fortios_log_memory_global_setting.py b/lib/ansible/modules/network/fortios/fortios_log_memory_global_setting.py index 325fa80d531..a1c1245e8cb 100644 --- a/lib/ansible/modules/network/fortios/fortios_log_memory_global_setting.py +++ b/lib/ansible/modules/network/fortios/fortios_log_memory_global_setting.py @@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function) # # You should have received a copy of the GNU General Public License # along with this program. If not, see . -# -# the lib use python logging can get it if the following is set in your -# Ansible config. __metaclass__ = type @@ -29,10 +26,10 @@ DOCUMENTATION = ''' module: fortios_log_memory_global_setting short_description: Global settings for memory logging in Fortinet's FortiOS and FortiGate. 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. 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" author: - Miguel Angel Munoz (@mamunozgonzalez) @@ -44,46 +41,60 @@ requirements: - fortiosapi>=0.9.8 options: host: - description: - - FortiOS or FortiGate ip address. - required: true + description: + - FortiOS or FortiGate IP address. + type: str + required: false username: description: - FortiOS or FortiGate username. - required: true + type: str + required: false password: description: - FortiOS or FortiGate password. + type: str default: "" vdom: description: - Virtual domain, among those defined previously. A vdom is a virtual instance of the FortiGate that can be configured and used as a different unit. + type: str default: root https: description: - - Indicates if the requests towards FortiGate must use HTTPS - protocol + - Indicates if the requests towards FortiGate must use HTTPS protocol. + type: bool + default: true + ssl_verify: + description: + - Ensures FortiGate certificate must be verified by a proper CA. type: bool default: true + version_added: 2.9 log_memory_global_setting: description: - Global settings for memory logging. default: null + type: dict suboptions: - full-final-warning-threshold: + full_final_warning_threshold: description: - - Log full final warning threshold as a percent (3 - 100, default = 95). - full-first-warning-threshold: + - Log full final warning threshold as a percent (3 - 100). + type: int + full_first_warning_threshold: description: - - Log full first warning threshold as a percent (1 - 98, default = 75). - full-second-warning-threshold: + - Log full first warning threshold as a percent (1 - 98). + type: int + full_second_warning_threshold: description: - - Log full second warning threshold as a percent (2 - 99, default = 90). - max-size: + - Log full second warning threshold as a percent (2 - 99). + type: int + max_size: description: - Maximum amount of memory that can be used for memory logging in bytes. + type: int ''' EXAMPLES = ''' @@ -93,6 +104,7 @@ EXAMPLES = ''' username: "admin" password: "" vdom: "root" + ssl_verify: "False" tasks: - name: Global settings for memory logging. fortios_log_memory_global_setting: @@ -102,10 +114,10 @@ EXAMPLES = ''' vdom: "{{ vdom }}" https: "False" log_memory_global_setting: - full-final-warning-threshold: "3" - full-first-warning-threshold: "4" - full-second-warning-threshold: "5" - max-size: "6" + full_final_warning_threshold: "3" + full_first_warning_threshold: "4" + full_second_warning_threshold: "5" + max_size: "6" ''' RETURN = ''' @@ -168,14 +180,16 @@ version: ''' from ansible.module_utils.basic import AnsibleModule - -fos = None +from ansible.module_utils.connection import Connection +from ansible.module_utils.network.fortios.fortios import FortiOSHandler +from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG -def login(data): +def login(data, fos): host = data['host'] username = data['username'] password = data['password'] + ssl_verify = data['ssl_verify'] fos.debug('on') if 'https' in data and not data['https']: @@ -183,12 +197,12 @@ def login(data): else: fos.https('on') - fos.login(host, username, password) + fos.login(host, username, password, verify=ssl_verify) def filter_log_memory_global_setting_data(json): - option_list = ['full-final-warning-threshold', 'full-first-warning-threshold', 'full-second-warning-threshold', - 'max-size'] + option_list = ['full_final_warning_threshold', 'full_first_warning_threshold', 'full_second_warning_threshold', + 'max_size'] dictionary = {} for attribute in option_list: @@ -198,17 +212,15 @@ def filter_log_memory_global_setting_data(json): return dictionary -def flatten_multilists_attributes(data): - multilist_attrs = [] - - for attr in multilist_attrs: - try: - path = "data['" + "']['".join(elem for elem in attr) + "']" - current_val = eval(path) - flattened_val = ' '.join(elem for elem in current_val) - exec(path + '= flattened_val') - except BaseException: - pass +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 @@ -216,38 +228,44 @@ def flatten_multilists_attributes(data): def log_memory_global_setting(data, fos): vdom = data['vdom'] log_memory_global_setting_data = data['log_memory_global_setting'] - flattened_data = flatten_multilists_attributes(log_memory_global_setting_data) - filtered_data = filter_log_memory_global_setting_data(flattened_data) + filtered_data = underscore_to_hyphen(filter_log_memory_global_setting_data(log_memory_global_setting_data)) + return fos.set('log.memory', 'global-setting', data=filtered_data, vdom=vdom) +def is_successful_status(status): + return status['status'] == "success" or \ + status['http_method'] == "DELETE" and status['http_status'] == 404 + + def fortios_log_memory(data, fos): - login(data) if data['log_memory_global_setting']: resp = log_memory_global_setting(data, fos) - fos.logout() - return not resp['status'] == "success", resp['status'] == "success", resp + return not is_successful_status(resp), \ + resp['status'] == "success", \ + resp def main(): fields = { - "host": {"required": True, "type": "str"}, - "username": {"required": True, "type": "str"}, - "password": {"required": False, "type": "str", "no_log": True}, + "host": {"required": False, "type": "str"}, + "username": {"required": False, "type": "str"}, + "password": {"required": False, "type": "str", "default": "", "no_log": True}, "vdom": {"required": False, "type": "str", "default": "root"}, "https": {"required": False, "type": "bool", "default": True}, + "ssl_verify": {"required": False, "type": "bool", "default": True}, "log_memory_global_setting": { - "required": False, "type": "dict", + "required": False, "type": "dict", "default": None, "options": { - "full-final-warning-threshold": {"required": False, "type": "int"}, - "full-first-warning-threshold": {"required": False, "type": "int"}, - "full-second-warning-threshold": {"required": False, "type": "int"}, - "max-size": {"required": False, "type": "int"} + "full_final_warning_threshold": {"required": False, "type": "int"}, + "full_first_warning_threshold": {"required": False, "type": "int"}, + "full_second_warning_threshold": {"required": False, "type": "int"}, + "max_size": {"required": False, "type": "int"} } } @@ -255,15 +273,31 @@ def main(): module = AnsibleModule(argument_spec=fields, supports_check_mode=False) - try: - from fortiosapi import FortiOSAPI - except ImportError: - module.fail_json(msg="fortiosapi module is required") - global fos - 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_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: module.exit_json(changed=has_changed, meta=result) diff --git a/lib/ansible/modules/network/fortios/fortios_log_memory_setting.py b/lib/ansible/modules/network/fortios/fortios_log_memory_setting.py index 0f5dcb6f6a3..6a634fc21bc 100644 --- a/lib/ansible/modules/network/fortios/fortios_log_memory_setting.py +++ b/lib/ansible/modules/network/fortios/fortios_log_memory_setting.py @@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function) # # You should have received a copy of the GNU General Public License # along with this program. If not, see . -# -# the lib use python logging can get it if the following is set in your -# Ansible config. __metaclass__ = type @@ -29,10 +26,10 @@ DOCUMENTATION = ''' module: fortios_log_memory_setting short_description: Settings for memory buffer in Fortinet's FortiOS and FortiGate. 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. 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" author: - Miguel Angel Munoz (@mamunozgonzalez) @@ -44,42 +41,54 @@ requirements: - fortiosapi>=0.9.8 options: host: - description: - - FortiOS or FortiGate ip address. - required: true + description: + - FortiOS or FortiGate IP address. + type: str + required: false username: description: - FortiOS or FortiGate username. - required: true + type: str + required: false password: description: - FortiOS or FortiGate password. + type: str default: "" vdom: description: - Virtual domain, among those defined previously. A vdom is a virtual instance of the FortiGate that can be configured and used as a different unit. + type: str default: root https: description: - - Indicates if the requests towards FortiGate must use HTTPS - protocol + - Indicates if the requests towards FortiGate must use HTTPS protocol. + type: bool + default: true + ssl_verify: + description: + - Ensures FortiGate certificate must be verified by a proper CA. type: bool default: true + version_added: 2.9 log_memory_setting: description: - Settings for memory buffer. default: null + type: dict suboptions: diskfull: description: - Action to take when memory is full. + type: str choices: - overwrite status: description: - Enable/disable logging to the FortiGate's memory. + type: str choices: - enable - disable @@ -92,6 +101,7 @@ EXAMPLES = ''' username: "admin" password: "" vdom: "root" + ssl_verify: "False" tasks: - name: Settings for memory buffer. fortios_log_memory_setting: @@ -165,14 +175,16 @@ version: ''' from ansible.module_utils.basic import AnsibleModule - -fos = None +from ansible.module_utils.connection import Connection +from ansible.module_utils.network.fortios.fortios import FortiOSHandler +from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG -def login(data): +def login(data, fos): host = data['host'] username = data['username'] password = data['password'] + ssl_verify = data['ssl_verify'] fos.debug('on') if 'https' in data and not data['https']: @@ -180,7 +192,7 @@ def login(data): else: fos.https('on') - fos.login(host, username, password) + fos.login(host, username, password, verify=ssl_verify) def filter_log_memory_setting_data(json): @@ -194,17 +206,15 @@ def filter_log_memory_setting_data(json): return dictionary -def flatten_multilists_attributes(data): - multilist_attrs = [] - - for attr in multilist_attrs: - try: - path = "data['" + "']['".join(elem for elem in attr) + "']" - current_val = eval(path) - flattened_val = ' '.join(elem for elem in current_val) - exec(path + '= flattened_val') - except BaseException: - pass +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 @@ -212,33 +222,39 @@ def flatten_multilists_attributes(data): def log_memory_setting(data, fos): vdom = data['vdom'] log_memory_setting_data = data['log_memory_setting'] - flattened_data = flatten_multilists_attributes(log_memory_setting_data) - filtered_data = filter_log_memory_setting_data(flattened_data) + filtered_data = underscore_to_hyphen(filter_log_memory_setting_data(log_memory_setting_data)) + return fos.set('log.memory', 'setting', data=filtered_data, vdom=vdom) +def is_successful_status(status): + return status['status'] == "success" or \ + status['http_method'] == "DELETE" and status['http_status'] == 404 + + def fortios_log_memory(data, fos): - login(data) if data['log_memory_setting']: resp = log_memory_setting(data, fos) - fos.logout() - return not resp['status'] == "success", resp['status'] == "success", resp + return not is_successful_status(resp), \ + resp['status'] == "success", \ + resp def main(): fields = { - "host": {"required": True, "type": "str"}, - "username": {"required": True, "type": "str"}, - "password": {"required": False, "type": "str", "no_log": True}, + "host": {"required": False, "type": "str"}, + "username": {"required": False, "type": "str"}, + "password": {"required": False, "type": "str", "default": "", "no_log": True}, "vdom": {"required": False, "type": "str", "default": "root"}, "https": {"required": False, "type": "bool", "default": True}, + "ssl_verify": {"required": False, "type": "bool", "default": True}, "log_memory_setting": { - "required": False, "type": "dict", + "required": False, "type": "dict", "default": None, "options": { "diskfull": {"required": False, "type": "str", "choices": ["overwrite"]}, @@ -251,15 +267,31 @@ def main(): module = AnsibleModule(argument_spec=fields, supports_check_mode=False) - try: - from fortiosapi import FortiOSAPI - except ImportError: - module.fail_json(msg="fortiosapi module is required") - global fos - 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_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: module.exit_json(changed=has_changed, meta=result) diff --git a/lib/ansible/modules/network/fortios/fortios_log_null_device_filter.py b/lib/ansible/modules/network/fortios/fortios_log_null_device_filter.py index 551df1194f6..0bf4e1a6185 100644 --- a/lib/ansible/modules/network/fortios/fortios_log_null_device_filter.py +++ b/lib/ansible/modules/network/fortios/fortios_log_null_device_filter.py @@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function) # # You should have received a copy of the GNU General Public License # along with this program. If not, see . -# -# the lib use python logging can get it if the following is set in your -# Ansible config. __metaclass__ = type @@ -29,10 +26,10 @@ DOCUMENTATION = ''' module: fortios_log_null_device_filter short_description: Filters for null device logging in Fortinet's FortiOS and FortiGate. 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. 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" author: - Miguel Angel Munoz (@mamunozgonzalez) @@ -44,88 +41,109 @@ requirements: - fortiosapi>=0.9.8 options: host: - description: - - FortiOS or FortiGate ip address. - required: true + description: + - FortiOS or FortiGate IP address. + type: str + required: false username: description: - FortiOS or FortiGate username. - required: true + type: str + required: false password: description: - FortiOS or FortiGate password. + type: str default: "" vdom: description: - Virtual domain, among those defined previously. A vdom is a virtual instance of the FortiGate that can be configured and used as a different unit. + type: str default: root https: description: - - Indicates if the requests towards FortiGate must use HTTPS - protocol + - Indicates if the requests towards FortiGate must use HTTPS protocol. + type: bool + default: true + ssl_verify: + description: + - Ensures FortiGate certificate must be verified by a proper CA. type: bool default: true + version_added: 2.9 log_null_device_filter: description: - Filters for null device logging. default: null + type: dict suboptions: anomaly: description: - Enable/disable anomaly logging. + type: str choices: - enable - disable dns: description: - Enable/disable detailed DNS event logging. + type: str choices: - enable - disable filter: description: - Null-device log filter. - filter-type: + type: str + filter_type: description: - Include/exclude logs that match the filter. + type: str choices: - include - exclude - forward-traffic: + forward_traffic: description: - Enable/disable forward traffic logging. + type: str choices: - enable - disable gtp: description: - Enable/disable GTP messages logging. + type: str choices: - enable - disable - local-traffic: + local_traffic: description: - Enable/disable local in or out traffic logging. + type: str choices: - enable - disable - multicast-traffic: + multicast_traffic: description: - Enable/disable multicast traffic logging. + type: str choices: - enable - disable - netscan-discovery: + netscan_discovery: description: - Enable/disable netscan discovery event logging. - netscan-vulnerability: + type: str + netscan_vulnerability: description: - Enable/disable netscan vulnerability event logging. + type: str severity: description: - Lowest severity level to log. + type: str choices: - emergency - alert @@ -135,21 +153,24 @@ options: - notification - information - debug - sniffer-traffic: + sniffer_traffic: description: - Enable/disable sniffer traffic logging. + type: str choices: - enable - disable ssh: description: - Enable/disable SSH logging. + type: str choices: - enable - disable voip: description: - Enable/disable VoIP logging. + type: str choices: - enable - disable @@ -162,6 +183,7 @@ EXAMPLES = ''' username: "admin" password: "" vdom: "root" + ssl_verify: "False" tasks: - name: Filters for null device logging. fortios_log_null_device_filter: @@ -174,15 +196,15 @@ EXAMPLES = ''' anomaly: "enable" dns: "enable" filter: "" - filter-type: "include" - forward-traffic: "enable" + filter_type: "include" + forward_traffic: "enable" gtp: "enable" - local-traffic: "enable" - multicast-traffic: "enable" - netscan-discovery: "" - netscan-vulnerability: "" + local_traffic: "enable" + multicast_traffic: "enable" + netscan_discovery: "" + netscan_vulnerability: "" severity: "emergency" - sniffer-traffic: "enable" + sniffer_traffic: "enable" ssh: "enable" voip: "enable" ''' @@ -247,14 +269,16 @@ version: ''' from ansible.module_utils.basic import AnsibleModule - -fos = None +from ansible.module_utils.connection import Connection +from ansible.module_utils.network.fortios.fortios import FortiOSHandler +from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG -def login(data): +def login(data, fos): host = data['host'] username = data['username'] password = data['password'] + ssl_verify = data['ssl_verify'] fos.debug('on') if 'https' in data and not data['https']: @@ -262,14 +286,14 @@ def login(data): else: fos.https('on') - fos.login(host, username, password) + fos.login(host, username, password, verify=ssl_verify) def filter_log_null_device_filter_data(json): option_list = ['anomaly', 'dns', 'filter', - 'filter-type', 'forward-traffic', 'gtp', - 'local-traffic', 'multicast-traffic', 'netscan-discovery', - 'netscan-vulnerability', 'severity', 'sniffer-traffic', + 'filter_type', 'forward_traffic', 'gtp', + 'local_traffic', 'multicast_traffic', 'netscan_discovery', + 'netscan_vulnerability', 'severity', 'sniffer_traffic', 'ssh', 'voip'] dictionary = {} @@ -280,17 +304,15 @@ def filter_log_null_device_filter_data(json): return dictionary -def flatten_multilists_attributes(data): - multilist_attrs = [] - - for attr in multilist_attrs: - try: - path = "data['" + "']['".join(elem for elem in attr) + "']" - current_val = eval(path) - flattened_val = ' '.join(elem for elem in current_val) - exec(path + '= flattened_val') - except BaseException: - pass +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 @@ -298,56 +320,62 @@ def flatten_multilists_attributes(data): def log_null_device_filter(data, fos): vdom = data['vdom'] log_null_device_filter_data = data['log_null_device_filter'] - flattened_data = flatten_multilists_attributes(log_null_device_filter_data) - filtered_data = filter_log_null_device_filter_data(flattened_data) + filtered_data = underscore_to_hyphen(filter_log_null_device_filter_data(log_null_device_filter_data)) + return fos.set('log.null-device', 'filter', data=filtered_data, vdom=vdom) +def is_successful_status(status): + return status['status'] == "success" or \ + status['http_method'] == "DELETE" and status['http_status'] == 404 + + def fortios_log_null_device(data, fos): - login(data) if data['log_null_device_filter']: resp = log_null_device_filter(data, fos) - fos.logout() - return not resp['status'] == "success", resp['status'] == "success", resp + return not is_successful_status(resp), \ + resp['status'] == "success", \ + resp def main(): fields = { - "host": {"required": True, "type": "str"}, - "username": {"required": True, "type": "str"}, - "password": {"required": False, "type": "str", "no_log": True}, + "host": {"required": False, "type": "str"}, + "username": {"required": False, "type": "str"}, + "password": {"required": False, "type": "str", "default": "", "no_log": True}, "vdom": {"required": False, "type": "str", "default": "root"}, "https": {"required": False, "type": "bool", "default": True}, + "ssl_verify": {"required": False, "type": "bool", "default": True}, "log_null_device_filter": { - "required": False, "type": "dict", + "required": False, "type": "dict", "default": None, "options": { "anomaly": {"required": False, "type": "str", "choices": ["enable", "disable"]}, "dns": {"required": False, "type": "str", "choices": ["enable", "disable"]}, "filter": {"required": False, "type": "str"}, - "filter-type": {"required": False, "type": "str", + "filter_type": {"required": False, "type": "str", "choices": ["include", "exclude"]}, - "forward-traffic": {"required": False, "type": "str", + "forward_traffic": {"required": False, "type": "str", "choices": ["enable", "disable"]}, "gtp": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "local-traffic": {"required": False, "type": "str", + "local_traffic": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "multicast-traffic": {"required": False, "type": "str", + "multicast_traffic": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "netscan-discovery": {"required": False, "type": "str"}, - "netscan-vulnerability": {"required": False, "type": "str"}, + "netscan_discovery": {"required": False, "type": "str"}, + "netscan_vulnerability": {"required": False, "type": "str"}, "severity": {"required": False, "type": "str", "choices": ["emergency", "alert", "critical", "error", "warning", "notification", "information", "debug"]}, - "sniffer-traffic": {"required": False, "type": "str", + "sniffer_traffic": {"required": False, "type": "str", "choices": ["enable", "disable"]}, "ssh": {"required": False, "type": "str", "choices": ["enable", "disable"]}, @@ -360,15 +388,31 @@ def main(): module = AnsibleModule(argument_spec=fields, supports_check_mode=False) - try: - from fortiosapi import FortiOSAPI - except ImportError: - module.fail_json(msg="fortiosapi module is required") - global fos - 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_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: module.exit_json(changed=has_changed, meta=result) diff --git a/lib/ansible/modules/network/fortios/fortios_log_null_device_setting.py b/lib/ansible/modules/network/fortios/fortios_log_null_device_setting.py index a6140d651f8..3d296a6aa5d 100644 --- a/lib/ansible/modules/network/fortios/fortios_log_null_device_setting.py +++ b/lib/ansible/modules/network/fortios/fortios_log_null_device_setting.py @@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function) # # You should have received a copy of the GNU General Public License # along with this program. If not, see . -# -# the lib use python logging can get it if the following is set in your -# Ansible config. __metaclass__ = type @@ -29,10 +26,10 @@ DOCUMENTATION = ''' module: fortios_log_null_device_setting short_description: Settings for null device logging in Fortinet's FortiOS and FortiGate. 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. 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" author: - Miguel Angel Munoz (@mamunozgonzalez) @@ -44,37 +41,48 @@ requirements: - fortiosapi>=0.9.8 options: host: - description: - - FortiOS or FortiGate ip address. - required: true + description: + - FortiOS or FortiGate IP address. + type: str + required: false username: description: - FortiOS or FortiGate username. - required: true + type: str + required: false password: description: - FortiOS or FortiGate password. + type: str default: "" vdom: description: - Virtual domain, among those defined previously. A vdom is a virtual instance of the FortiGate that can be configured and used as a different unit. + type: str default: root https: description: - - Indicates if the requests towards FortiGate must use HTTPS - protocol + - Indicates if the requests towards FortiGate must use HTTPS protocol. + type: bool + default: true + ssl_verify: + description: + - Ensures FortiGate certificate must be verified by a proper CA. type: bool default: true + version_added: 2.9 log_null_device_setting: description: - Settings for null device logging. default: null + type: dict suboptions: status: description: - Enable/disable statistics collection for when no external logging destination, such as FortiAnalyzer, is present (data is not saved). + type: str choices: - enable - disable @@ -87,6 +95,7 @@ EXAMPLES = ''' username: "admin" password: "" vdom: "root" + ssl_verify: "False" tasks: - name: Settings for null device logging. fortios_log_null_device_setting: @@ -159,14 +168,16 @@ version: ''' from ansible.module_utils.basic import AnsibleModule - -fos = None +from ansible.module_utils.connection import Connection +from ansible.module_utils.network.fortios.fortios import FortiOSHandler +from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG -def login(data): +def login(data, fos): host = data['host'] username = data['username'] password = data['password'] + ssl_verify = data['ssl_verify'] fos.debug('on') if 'https' in data and not data['https']: @@ -174,7 +185,7 @@ def login(data): else: fos.https('on') - fos.login(host, username, password) + fos.login(host, username, password, verify=ssl_verify) def filter_log_null_device_setting_data(json): @@ -188,17 +199,15 @@ def filter_log_null_device_setting_data(json): return dictionary -def flatten_multilists_attributes(data): - multilist_attrs = [] - - for attr in multilist_attrs: - try: - path = "data['" + "']['".join(elem for elem in attr) + "']" - current_val = eval(path) - flattened_val = ' '.join(elem for elem in current_val) - exec(path + '= flattened_val') - except BaseException: - pass +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 @@ -206,33 +215,39 @@ def flatten_multilists_attributes(data): def log_null_device_setting(data, fos): vdom = data['vdom'] log_null_device_setting_data = data['log_null_device_setting'] - flattened_data = flatten_multilists_attributes(log_null_device_setting_data) - filtered_data = filter_log_null_device_setting_data(flattened_data) + filtered_data = underscore_to_hyphen(filter_log_null_device_setting_data(log_null_device_setting_data)) + return fos.set('log.null-device', 'setting', data=filtered_data, vdom=vdom) +def is_successful_status(status): + return status['status'] == "success" or \ + status['http_method'] == "DELETE" and status['http_status'] == 404 + + def fortios_log_null_device(data, fos): - login(data) if data['log_null_device_setting']: resp = log_null_device_setting(data, fos) - fos.logout() - return not resp['status'] == "success", resp['status'] == "success", resp + return not is_successful_status(resp), \ + resp['status'] == "success", \ + resp def main(): fields = { - "host": {"required": True, "type": "str"}, - "username": {"required": True, "type": "str"}, - "password": {"required": False, "type": "str", "no_log": True}, + "host": {"required": False, "type": "str"}, + "username": {"required": False, "type": "str"}, + "password": {"required": False, "type": "str", "default": "", "no_log": True}, "vdom": {"required": False, "type": "str", "default": "root"}, "https": {"required": False, "type": "bool", "default": True}, + "ssl_verify": {"required": False, "type": "bool", "default": True}, "log_null_device_setting": { - "required": False, "type": "dict", + "required": False, "type": "dict", "default": None, "options": { "status": {"required": False, "type": "str", "choices": ["enable", "disable"]} @@ -243,15 +258,31 @@ def main(): module = AnsibleModule(argument_spec=fields, supports_check_mode=False) - try: - from fortiosapi import FortiOSAPI - except ImportError: - module.fail_json(msg="fortiosapi module is required") - global fos - 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_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: module.exit_json(changed=has_changed, meta=result) diff --git a/lib/ansible/modules/network/fortios/fortios_log_setting.py b/lib/ansible/modules/network/fortios/fortios_log_setting.py index de7464a28b8..6136f0427fd 100644 --- a/lib/ansible/modules/network/fortios/fortios_log_setting.py +++ b/lib/ansible/modules/network/fortios/fortios_log_setting.py @@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function) # # You should have received a copy of the GNU General Public License # along with this program. If not, see . -# -# the lib use python logging can get it if the following is set in your -# Ansible config. __metaclass__ = type @@ -29,10 +26,10 @@ DOCUMENTATION = ''' module: fortios_log_setting short_description: Configure general log settings in Fortinet's FortiOS and FortiGate. 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. 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" author: - Miguel Angel Munoz (@mamunozgonzalez) @@ -44,141 +41,169 @@ requirements: - fortiosapi>=0.9.8 options: host: - description: - - FortiOS or FortiGate ip address. - required: true + description: + - FortiOS or FortiGate IP address. + type: str + required: false username: description: - FortiOS or FortiGate username. - required: true + type: str + required: false password: description: - FortiOS or FortiGate password. + type: str default: "" vdom: description: - Virtual domain, among those defined previously. A vdom is a virtual instance of the FortiGate that can be configured and used as a different unit. + type: str default: root https: description: - - Indicates if the requests towards FortiGate must use HTTPS - protocol + - Indicates if the requests towards FortiGate must use HTTPS protocol. + type: bool + default: true + ssl_verify: + description: + - Ensures FortiGate certificate must be verified by a proper CA. type: bool default: true + version_added: 2.9 log_setting: description: - Configure general log settings. default: null + type: dict suboptions: - brief-traffic-format: + brief_traffic_format: description: - Enable/disable brief format traffic logging. + type: str choices: - enable - disable - custom-log-fields: + custom_log_fields: description: - Custom fields to append to all log messages. + type: list suboptions: - field-id: + field_id: description: - Custom log field. Source log.custom-field.id. - required: true - daemon-log: + type: str + daemon_log: description: - Enable/disable daemon logging. + type: str choices: - enable - disable - expolicy-implicit-log: + expolicy_implicit_log: description: - Enable/disable explicit proxy firewall implicit policy logging. + type: str choices: - enable - disable - fwpolicy-implicit-log: + fwpolicy_implicit_log: description: - Enable/disable implicit firewall policy logging. + type: str choices: - enable - disable - fwpolicy6-implicit-log: + fwpolicy6_implicit_log: description: - Enable/disable implicit firewall policy6 logging. + type: str choices: - enable - disable - local-in-allow: + local_in_allow: description: - Enable/disable local-in-allow logging. + type: str choices: - enable - disable - local-in-deny-broadcast: + local_in_deny_broadcast: description: - Enable/disable local-in-deny-broadcast logging. + type: str choices: - enable - disable - local-in-deny-unicast: + local_in_deny_unicast: description: - Enable/disable local-in-deny-unicast logging. + type: str choices: - enable - disable - local-out: + local_out: description: - Enable/disable local-out logging. + type: str choices: - enable - disable - log-invalid-packet: + log_invalid_packet: description: - Enable/disable invalid packet traffic logging. + type: str choices: - enable - disable - log-policy-comment: + log_policy_comment: description: - Enable/disable inserting policy comments into traffic logs. + type: str choices: - enable - disable - log-policy-name: + log_policy_name: description: - Enable/disable inserting policy name into traffic logs. + type: str choices: - enable - disable - log-user-in-upper: + log_user_in_upper: description: - Enable/disable logs with user-in-upper. + type: str choices: - enable - disable - neighbor-event: + neighbor_event: description: - Enable/disable neighbor event logging. + type: str choices: - enable - disable - resolve-ip: + resolve_ip: description: - Enable/disable adding resolved domain names to traffic logs if possible. + type: str choices: - enable - disable - resolve-port: + resolve_port: description: - Enable/disable adding resolved service names to traffic logs. + type: str choices: - enable - disable - user-anonymize: + user_anonymize: description: - Enable/disable anonymizing user names in log messages. + type: str choices: - enable - disable @@ -191,6 +216,7 @@ EXAMPLES = ''' username: "admin" password: "" vdom: "root" + ssl_verify: "False" tasks: - name: Configure general log settings. fortios_log_setting: @@ -200,26 +226,26 @@ EXAMPLES = ''' vdom: "{{ vdom }}" https: "False" log_setting: - brief-traffic-format: "enable" - custom-log-fields: + brief_traffic_format: "enable" + custom_log_fields: - - field-id: " (source log.custom-field.id)" - 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" + field_id: " (source log.custom-field.id)" + 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" ''' RETURN = ''' @@ -282,14 +308,16 @@ version: ''' from ansible.module_utils.basic import AnsibleModule - -fos = None +from ansible.module_utils.connection import Connection +from ansible.module_utils.network.fortios.fortios import FortiOSHandler +from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG -def login(data): +def login(data, fos): host = data['host'] username = data['username'] password = data['password'] + ssl_verify = data['ssl_verify'] fos.debug('on') if 'https' in data and not data['https']: @@ -297,16 +325,16 @@ def login(data): else: fos.https('on') - fos.login(host, username, password) + fos.login(host, username, password, verify=ssl_verify) def filter_log_setting_data(json): - option_list = ['brief-traffic-format', 'custom-log-fields', 'daemon-log', - 'expolicy-implicit-log', 'fwpolicy-implicit-log', 'fwpolicy6-implicit-log', - 'local-in-allow', 'local-in-deny-broadcast', 'local-in-deny-unicast', - 'local-out', 'log-invalid-packet', 'log-policy-comment', - 'log-policy-name', 'log-user-in-upper', 'neighbor-event', - 'resolve-ip', 'resolve-port', 'user-anonymize'] + option_list = ['brief_traffic_format', 'custom_log_fields', 'daemon_log', + 'expolicy_implicit_log', 'fwpolicy_implicit_log', 'fwpolicy6_implicit_log', + 'local_in_allow', 'local_in_deny_broadcast', 'local_in_deny_unicast', + 'local_out', 'log_invalid_packet', 'log_policy_comment', + 'log_policy_name', 'log_user_in_upper', 'neighbor_event', + 'resolve_ip', 'resolve_port', 'user_anonymize'] dictionary = {} for attribute in option_list: @@ -316,17 +344,15 @@ def filter_log_setting_data(json): return dictionary -def flatten_multilists_attributes(data): - multilist_attrs = [] - - for attr in multilist_attrs: - try: - path = "data['" + "']['".join(elem for elem in attr) + "']" - current_val = eval(path) - flattened_val = ' '.join(elem for elem in current_val) - exec(path + '= flattened_val') - except BaseException: - pass +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 @@ -334,71 +360,77 @@ def flatten_multilists_attributes(data): def log_setting(data, fos): vdom = data['vdom'] log_setting_data = data['log_setting'] - flattened_data = flatten_multilists_attributes(log_setting_data) - filtered_data = filter_log_setting_data(flattened_data) + filtered_data = underscore_to_hyphen(filter_log_setting_data(log_setting_data)) + return fos.set('log', 'setting', data=filtered_data, vdom=vdom) +def is_successful_status(status): + return status['status'] == "success" or \ + status['http_method'] == "DELETE" and status['http_status'] == 404 + + def fortios_log(data, fos): - login(data) if data['log_setting']: resp = log_setting(data, fos) - fos.logout() - return not resp['status'] == "success", resp['status'] == "success", resp + return not is_successful_status(resp), \ + resp['status'] == "success", \ + resp def main(): fields = { - "host": {"required": True, "type": "str"}, - "username": {"required": True, "type": "str"}, - "password": {"required": False, "type": "str", "no_log": True}, + "host": {"required": False, "type": "str"}, + "username": {"required": False, "type": "str"}, + "password": {"required": False, "type": "str", "default": "", "no_log": True}, "vdom": {"required": False, "type": "str", "default": "root"}, "https": {"required": False, "type": "bool", "default": True}, + "ssl_verify": {"required": False, "type": "bool", "default": True}, "log_setting": { - "required": False, "type": "dict", + "required": False, "type": "dict", "default": None, "options": { - "brief-traffic-format": {"required": False, "type": "str", + "brief_traffic_format": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "custom-log-fields": {"required": False, "type": "list", + "custom_log_fields": {"required": False, "type": "list", "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"]}, - "expolicy-implicit-log": {"required": False, "type": "str", + "expolicy_implicit_log": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "fwpolicy-implicit-log": {"required": False, "type": "str", + "fwpolicy_implicit_log": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "fwpolicy6-implicit-log": {"required": False, "type": "str", + "fwpolicy6_implicit_log": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "local-in-allow": {"required": False, "type": "str", + "local_in_allow": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "local-in-deny-broadcast": {"required": False, "type": "str", + "local_in_deny_broadcast": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "local-in-deny-unicast": {"required": False, "type": "str", + "local_in_deny_unicast": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "local-out": {"required": False, "type": "str", + "local_out": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "log-invalid-packet": {"required": False, "type": "str", + "log_invalid_packet": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "log-policy-comment": {"required": False, "type": "str", + "log_policy_comment": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "log-policy-name": {"required": False, "type": "str", + "log_policy_name": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "log-user-in-upper": {"required": False, "type": "str", + "log_user_in_upper": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "neighbor-event": {"required": False, "type": "str", + "neighbor_event": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "resolve-ip": {"required": False, "type": "str", + "resolve_ip": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "resolve-port": {"required": False, "type": "str", + "resolve_port": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "user-anonymize": {"required": False, "type": "str", + "user_anonymize": {"required": False, "type": "str", "choices": ["enable", "disable"]} } @@ -407,15 +439,31 @@ def main(): module = AnsibleModule(argument_spec=fields, supports_check_mode=False) - try: - from fortiosapi import FortiOSAPI - except ImportError: - module.fail_json(msg="fortiosapi module is required") - global fos - 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(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: module.exit_json(changed=has_changed, meta=result) diff --git a/lib/ansible/modules/network/fortios/fortios_log_syslogd2_filter.py b/lib/ansible/modules/network/fortios/fortios_log_syslogd2_filter.py index 9f07942da5c..a55f2b20eaf 100644 --- a/lib/ansible/modules/network/fortios/fortios_log_syslogd2_filter.py +++ b/lib/ansible/modules/network/fortios/fortios_log_syslogd2_filter.py @@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function) # # You should have received a copy of the GNU General Public License # along with this program. If not, see . -# -# the lib use python logging can get it if the following is set in your -# Ansible config. __metaclass__ = type @@ -29,10 +26,10 @@ DOCUMENTATION = ''' module: fortios_log_syslogd2_filter short_description: Filters for remote system server in Fortinet's FortiOS and FortiGate. 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. 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" author: - Miguel Angel Munoz (@mamunozgonzalez) @@ -44,88 +41,109 @@ requirements: - fortiosapi>=0.9.8 options: host: - description: - - FortiOS or FortiGate ip address. - required: true + description: + - FortiOS or FortiGate IP address. + type: str + required: false username: description: - FortiOS or FortiGate username. - required: true + type: str + required: false password: description: - FortiOS or FortiGate password. + type: str default: "" vdom: description: - Virtual domain, among those defined previously. A vdom is a virtual instance of the FortiGate that can be configured and used as a different unit. + type: str default: root https: description: - - Indicates if the requests towards FortiGate must use HTTPS - protocol + - Indicates if the requests towards FortiGate must use HTTPS protocol. + type: bool + default: true + ssl_verify: + description: + - Ensures FortiGate certificate must be verified by a proper CA. type: bool default: true + version_added: 2.9 log_syslogd2_filter: description: - Filters for remote system server. default: null + type: dict suboptions: anomaly: description: - Enable/disable anomaly logging. + type: str choices: - enable - disable dns: description: - Enable/disable detailed DNS event logging. + type: str choices: - enable - disable filter: description: - Syslog 2 filter. - filter-type: + type: str + filter_type: description: - Include/exclude logs that match the filter. + type: str choices: - include - exclude - forward-traffic: + forward_traffic: description: - Enable/disable forward traffic logging. + type: str choices: - enable - disable gtp: description: - Enable/disable GTP messages logging. + type: str choices: - enable - disable - local-traffic: + local_traffic: description: - Enable/disable local in or out traffic logging. + type: str choices: - enable - disable - multicast-traffic: + multicast_traffic: description: - Enable/disable multicast traffic logging. + type: str choices: - enable - disable - netscan-discovery: + netscan_discovery: description: - Enable/disable netscan discovery event logging. - netscan-vulnerability: + type: str + netscan_vulnerability: description: - Enable/disable netscan vulnerability event logging. + type: str severity: description: - Lowest severity level to log. + type: str choices: - emergency - alert @@ -135,21 +153,24 @@ options: - notification - information - debug - sniffer-traffic: + sniffer_traffic: description: - Enable/disable sniffer traffic logging. + type: str choices: - enable - disable ssh: description: - Enable/disable SSH logging. + type: str choices: - enable - disable voip: description: - Enable/disable VoIP logging. + type: str choices: - enable - disable @@ -162,6 +183,7 @@ EXAMPLES = ''' username: "admin" password: "" vdom: "root" + ssl_verify: "False" tasks: - name: Filters for remote system server. fortios_log_syslogd2_filter: @@ -174,15 +196,15 @@ EXAMPLES = ''' anomaly: "enable" dns: "enable" filter: "" - filter-type: "include" - forward-traffic: "enable" + filter_type: "include" + forward_traffic: "enable" gtp: "enable" - local-traffic: "enable" - multicast-traffic: "enable" - netscan-discovery: "" - netscan-vulnerability: "" + local_traffic: "enable" + multicast_traffic: "enable" + netscan_discovery: "" + netscan_vulnerability: "" severity: "emergency" - sniffer-traffic: "enable" + sniffer_traffic: "enable" ssh: "enable" voip: "enable" ''' @@ -247,14 +269,16 @@ version: ''' from ansible.module_utils.basic import AnsibleModule - -fos = None +from ansible.module_utils.connection import Connection +from ansible.module_utils.network.fortios.fortios import FortiOSHandler +from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG -def login(data): +def login(data, fos): host = data['host'] username = data['username'] password = data['password'] + ssl_verify = data['ssl_verify'] fos.debug('on') if 'https' in data and not data['https']: @@ -262,14 +286,14 @@ def login(data): else: fos.https('on') - fos.login(host, username, password) + fos.login(host, username, password, verify=ssl_verify) def filter_log_syslogd2_filter_data(json): option_list = ['anomaly', 'dns', 'filter', - 'filter-type', 'forward-traffic', 'gtp', - 'local-traffic', 'multicast-traffic', 'netscan-discovery', - 'netscan-vulnerability', 'severity', 'sniffer-traffic', + 'filter_type', 'forward_traffic', 'gtp', + 'local_traffic', 'multicast_traffic', 'netscan_discovery', + 'netscan_vulnerability', 'severity', 'sniffer_traffic', 'ssh', 'voip'] dictionary = {} @@ -280,17 +304,15 @@ def filter_log_syslogd2_filter_data(json): return dictionary -def flatten_multilists_attributes(data): - multilist_attrs = [] - - for attr in multilist_attrs: - try: - path = "data['" + "']['".join(elem for elem in attr) + "']" - current_val = eval(path) - flattened_val = ' '.join(elem for elem in current_val) - exec(path + '= flattened_val') - except BaseException: - pass +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 @@ -298,56 +320,62 @@ def flatten_multilists_attributes(data): def log_syslogd2_filter(data, fos): vdom = data['vdom'] log_syslogd2_filter_data = data['log_syslogd2_filter'] - flattened_data = flatten_multilists_attributes(log_syslogd2_filter_data) - filtered_data = filter_log_syslogd2_filter_data(flattened_data) + filtered_data = underscore_to_hyphen(filter_log_syslogd2_filter_data(log_syslogd2_filter_data)) + return fos.set('log.syslogd2', 'filter', data=filtered_data, vdom=vdom) +def is_successful_status(status): + return status['status'] == "success" or \ + status['http_method'] == "DELETE" and status['http_status'] == 404 + + def fortios_log_syslogd2(data, fos): - login(data) if data['log_syslogd2_filter']: resp = log_syslogd2_filter(data, fos) - fos.logout() - return not resp['status'] == "success", resp['status'] == "success", resp + return not is_successful_status(resp), \ + resp['status'] == "success", \ + resp def main(): fields = { - "host": {"required": True, "type": "str"}, - "username": {"required": True, "type": "str"}, - "password": {"required": False, "type": "str", "no_log": True}, + "host": {"required": False, "type": "str"}, + "username": {"required": False, "type": "str"}, + "password": {"required": False, "type": "str", "default": "", "no_log": True}, "vdom": {"required": False, "type": "str", "default": "root"}, "https": {"required": False, "type": "bool", "default": True}, + "ssl_verify": {"required": False, "type": "bool", "default": True}, "log_syslogd2_filter": { - "required": False, "type": "dict", + "required": False, "type": "dict", "default": None, "options": { "anomaly": {"required": False, "type": "str", "choices": ["enable", "disable"]}, "dns": {"required": False, "type": "str", "choices": ["enable", "disable"]}, "filter": {"required": False, "type": "str"}, - "filter-type": {"required": False, "type": "str", + "filter_type": {"required": False, "type": "str", "choices": ["include", "exclude"]}, - "forward-traffic": {"required": False, "type": "str", + "forward_traffic": {"required": False, "type": "str", "choices": ["enable", "disable"]}, "gtp": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "local-traffic": {"required": False, "type": "str", + "local_traffic": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "multicast-traffic": {"required": False, "type": "str", + "multicast_traffic": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "netscan-discovery": {"required": False, "type": "str"}, - "netscan-vulnerability": {"required": False, "type": "str"}, + "netscan_discovery": {"required": False, "type": "str"}, + "netscan_vulnerability": {"required": False, "type": "str"}, "severity": {"required": False, "type": "str", "choices": ["emergency", "alert", "critical", "error", "warning", "notification", "information", "debug"]}, - "sniffer-traffic": {"required": False, "type": "str", + "sniffer_traffic": {"required": False, "type": "str", "choices": ["enable", "disable"]}, "ssh": {"required": False, "type": "str", "choices": ["enable", "disable"]}, @@ -360,15 +388,31 @@ def main(): module = AnsibleModule(argument_spec=fields, supports_check_mode=False) - try: - from fortiosapi import FortiOSAPI - except ImportError: - module.fail_json(msg="fortiosapi module is required") - global fos - 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_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: module.exit_json(changed=has_changed, meta=result) diff --git a/lib/ansible/modules/network/fortios/fortios_log_syslogd2_setting.py b/lib/ansible/modules/network/fortios/fortios_log_syslogd2_setting.py index e3951e03c88..2e77d05767d 100644 --- a/lib/ansible/modules/network/fortios/fortios_log_syslogd2_setting.py +++ b/lib/ansible/modules/network/fortios/fortios_log_syslogd2_setting.py @@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function) # # You should have received a copy of the GNU General Public License # along with this program. If not, see . -# -# the lib use python logging can get it if the following is set in your -# Ansible config. __metaclass__ = type @@ -29,10 +26,10 @@ DOCUMENTATION = ''' module: fortios_log_syslogd2_setting short_description: Global settings for remote syslog server in Fortinet's FortiOS and FortiGate. 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. 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" author: - Miguel Angel Munoz (@mamunozgonzalez) @@ -44,54 +41,70 @@ requirements: - fortiosapi>=0.9.8 options: host: - description: - - FortiOS or FortiGate ip address. - required: true + description: + - FortiOS or FortiGate IP address. + type: str + required: false username: description: - FortiOS or FortiGate username. - required: true + type: str + required: false password: description: - FortiOS or FortiGate password. + type: str default: "" vdom: description: - Virtual domain, among those defined previously. A vdom is a virtual instance of the FortiGate that can be configured and used as a different unit. + type: str default: root https: description: - - Indicates if the requests towards FortiGate must use HTTPS - protocol + - Indicates if the requests towards FortiGate must use HTTPS protocol. + type: bool + default: true + ssl_verify: + description: + - Ensures FortiGate certificate must be verified by a proper CA. type: bool default: true + version_added: 2.9 log_syslogd2_setting: description: - Global settings for remote syslog server. default: null + type: dict suboptions: certificate: description: - Certificate used to communicate with Syslog server. Source certificate.local.name. - custom-field-name: + type: str + custom_field_name: description: - Custom field name for CEF format logging. + type: list suboptions: custom: description: - Field custom name. + type: str id: description: - Entry ID. required: true + type: int name: description: - Field name. - enc-algorithm: + type: str + enc_algorithm: description: - Enable/disable reliable syslogging with TLS encryption. + type: str choices: - high-medium - high @@ -100,6 +113,7 @@ options: facility: description: - Remote syslog facility. + type: str choices: - kernel - user @@ -128,6 +142,7 @@ options: format: description: - Log format. + type: str choices: - default - csv @@ -135,6 +150,7 @@ options: mode: description: - Remote syslog logging over UDP/Reliable TCP. + type: str choices: - udp - legacy-reliable @@ -142,15 +158,29 @@ options: port: description: - Server listen port. + type: int server: description: - Address of remote syslog server. - source-ip: + type: str + source_ip: description: - 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: description: - Enable/disable remote syslog logging. + type: str choices: - enable - disable @@ -163,6 +193,7 @@ EXAMPLES = ''' username: "admin" password: "" vdom: "root" + ssl_verify: "False" tasks: - name: Global settings for remote syslog server. fortios_log_syslogd2_setting: @@ -173,18 +204,19 @@ EXAMPLES = ''' https: "False" log_syslogd2_setting: certificate: " (source certificate.local.name)" - custom-field-name: + custom_field_name: - custom: "" id: "6" name: "default_name_7" - enc-algorithm: "high-medium" + enc_algorithm: "high-medium" facility: "kernel" format: "default" mode: "udp" port: "12" server: "192.168.100.40" - source-ip: "84.230.14.43" + source_ip: "84.230.14.43" + ssl_min_proto_version: "default" status: "enable" ''' @@ -248,14 +280,16 @@ version: ''' from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.connection import Connection +from ansible.module_utils.network.fortios.fortios import FortiOSHandler +from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG -fos = None - -def login(data): +def login(data, fos): host = data['host'] username = data['username'] password = data['password'] + ssl_verify = data['ssl_verify'] fos.debug('on') if 'https' in data and not data['https']: @@ -263,14 +297,14 @@ def login(data): else: fos.https('on') - fos.login(host, username, password) + fos.login(host, username, password, verify=ssl_verify) 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', - 'port', 'server', 'source-ip', - 'status'] + 'port', 'server', 'source_ip', + 'ssl_min_proto_version', 'status'] dictionary = {} for attribute in option_list: @@ -280,17 +314,15 @@ def filter_log_syslogd2_setting_data(json): return dictionary -def flatten_multilists_attributes(data): - multilist_attrs = [] - - for attr in multilist_attrs: - try: - path = "data['" + "']['".join(elem for elem in attr) + "']" - current_val = eval(path) - flattened_val = ' '.join(elem for elem in current_val) - exec(path + '= flattened_val') - except BaseException: - pass +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 @@ -298,42 +330,48 @@ def flatten_multilists_attributes(data): def log_syslogd2_setting(data, fos): vdom = data['vdom'] log_syslogd2_setting_data = data['log_syslogd2_setting'] - flattened_data = flatten_multilists_attributes(log_syslogd2_setting_data) - filtered_data = filter_log_syslogd2_setting_data(flattened_data) + filtered_data = underscore_to_hyphen(filter_log_syslogd2_setting_data(log_syslogd2_setting_data)) + return fos.set('log.syslogd2', 'setting', data=filtered_data, vdom=vdom) +def is_successful_status(status): + return status['status'] == "success" or \ + status['http_method'] == "DELETE" and status['http_status'] == 404 + + def fortios_log_syslogd2(data, fos): - login(data) if data['log_syslogd2_setting']: resp = log_syslogd2_setting(data, fos) - fos.logout() - return not resp['status'] == "success", resp['status'] == "success", resp + return not is_successful_status(resp), \ + resp['status'] == "success", \ + resp def main(): fields = { - "host": {"required": True, "type": "str"}, - "username": {"required": True, "type": "str"}, - "password": {"required": False, "type": "str", "no_log": True}, + "host": {"required": False, "type": "str"}, + "username": {"required": False, "type": "str"}, + "password": {"required": False, "type": "str", "default": "", "no_log": True}, "vdom": {"required": False, "type": "str", "default": "root"}, "https": {"required": False, "type": "bool", "default": True}, + "ssl_verify": {"required": False, "type": "bool", "default": True}, "log_syslogd2_setting": { - "required": False, "type": "dict", + "required": False, "type": "dict", "default": None, "options": { "certificate": {"required": False, "type": "str"}, - "custom-field-name": {"required": False, "type": "list", + "custom_field_name": {"required": False, "type": "list", "options": { "custom": {"required": False, "type": "str"}, "id": {"required": True, "type": "int"}, "name": {"required": False, "type": "str"} }}, - "enc-algorithm": {"required": False, "type": "str", + "enc_algorithm": {"required": False, "type": "str", "choices": ["high-medium", "high", "low", "disable"]}, "facility": {"required": False, "type": "str", @@ -351,7 +389,10 @@ def main(): "choices": ["udp", "legacy-reliable", "reliable"]}, "port": {"required": False, "type": "int"}, "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", "choices": ["enable", "disable"]} @@ -361,15 +402,31 @@ def main(): module = AnsibleModule(argument_spec=fields, supports_check_mode=False) - try: - from fortiosapi import FortiOSAPI - except ImportError: - module.fail_json(msg="fortiosapi module is required") - global fos - 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_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: module.exit_json(changed=has_changed, meta=result) diff --git a/lib/ansible/modules/network/fortios/fortios_log_syslogd3_filter.py b/lib/ansible/modules/network/fortios/fortios_log_syslogd3_filter.py index c7eee1c45b3..e75fbcb4ee1 100644 --- a/lib/ansible/modules/network/fortios/fortios_log_syslogd3_filter.py +++ b/lib/ansible/modules/network/fortios/fortios_log_syslogd3_filter.py @@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function) # # You should have received a copy of the GNU General Public License # along with this program. If not, see . -# -# the lib use python logging can get it if the following is set in your -# Ansible config. __metaclass__ = type @@ -29,10 +26,10 @@ DOCUMENTATION = ''' module: fortios_log_syslogd3_filter short_description: Filters for remote system server in Fortinet's FortiOS and FortiGate. 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. 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" author: - Miguel Angel Munoz (@mamunozgonzalez) @@ -44,88 +41,109 @@ requirements: - fortiosapi>=0.9.8 options: host: - description: - - FortiOS or FortiGate ip address. - required: true + description: + - FortiOS or FortiGate IP address. + type: str + required: false username: description: - FortiOS or FortiGate username. - required: true + type: str + required: false password: description: - FortiOS or FortiGate password. + type: str default: "" vdom: description: - Virtual domain, among those defined previously. A vdom is a virtual instance of the FortiGate that can be configured and used as a different unit. + type: str default: root https: description: - - Indicates if the requests towards FortiGate must use HTTPS - protocol + - Indicates if the requests towards FortiGate must use HTTPS protocol. + type: bool + default: true + ssl_verify: + description: + - Ensures FortiGate certificate must be verified by a proper CA. type: bool default: true + version_added: 2.9 log_syslogd3_filter: description: - Filters for remote system server. default: null + type: dict suboptions: anomaly: description: - Enable/disable anomaly logging. + type: str choices: - enable - disable dns: description: - Enable/disable detailed DNS event logging. + type: str choices: - enable - disable filter: description: - Syslog 3 filter. - filter-type: + type: str + filter_type: description: - Include/exclude logs that match the filter. + type: str choices: - include - exclude - forward-traffic: + forward_traffic: description: - Enable/disable forward traffic logging. + type: str choices: - enable - disable gtp: description: - Enable/disable GTP messages logging. + type: str choices: - enable - disable - local-traffic: + local_traffic: description: - Enable/disable local in or out traffic logging. + type: str choices: - enable - disable - multicast-traffic: + multicast_traffic: description: - Enable/disable multicast traffic logging. + type: str choices: - enable - disable - netscan-discovery: + netscan_discovery: description: - Enable/disable netscan discovery event logging. - netscan-vulnerability: + type: str + netscan_vulnerability: description: - Enable/disable netscan vulnerability event logging. + type: str severity: description: - Lowest severity level to log. + type: str choices: - emergency - alert @@ -135,21 +153,24 @@ options: - notification - information - debug - sniffer-traffic: + sniffer_traffic: description: - Enable/disable sniffer traffic logging. + type: str choices: - enable - disable ssh: description: - Enable/disable SSH logging. + type: str choices: - enable - disable voip: description: - Enable/disable VoIP logging. + type: str choices: - enable - disable @@ -162,6 +183,7 @@ EXAMPLES = ''' username: "admin" password: "" vdom: "root" + ssl_verify: "False" tasks: - name: Filters for remote system server. fortios_log_syslogd3_filter: @@ -174,15 +196,15 @@ EXAMPLES = ''' anomaly: "enable" dns: "enable" filter: "" - filter-type: "include" - forward-traffic: "enable" + filter_type: "include" + forward_traffic: "enable" gtp: "enable" - local-traffic: "enable" - multicast-traffic: "enable" - netscan-discovery: "" - netscan-vulnerability: "" + local_traffic: "enable" + multicast_traffic: "enable" + netscan_discovery: "" + netscan_vulnerability: "" severity: "emergency" - sniffer-traffic: "enable" + sniffer_traffic: "enable" ssh: "enable" voip: "enable" ''' @@ -247,14 +269,16 @@ version: ''' from ansible.module_utils.basic import AnsibleModule - -fos = None +from ansible.module_utils.connection import Connection +from ansible.module_utils.network.fortios.fortios import FortiOSHandler +from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG -def login(data): +def login(data, fos): host = data['host'] username = data['username'] password = data['password'] + ssl_verify = data['ssl_verify'] fos.debug('on') if 'https' in data and not data['https']: @@ -262,14 +286,14 @@ def login(data): else: fos.https('on') - fos.login(host, username, password) + fos.login(host, username, password, verify=ssl_verify) def filter_log_syslogd3_filter_data(json): option_list = ['anomaly', 'dns', 'filter', - 'filter-type', 'forward-traffic', 'gtp', - 'local-traffic', 'multicast-traffic', 'netscan-discovery', - 'netscan-vulnerability', 'severity', 'sniffer-traffic', + 'filter_type', 'forward_traffic', 'gtp', + 'local_traffic', 'multicast_traffic', 'netscan_discovery', + 'netscan_vulnerability', 'severity', 'sniffer_traffic', 'ssh', 'voip'] dictionary = {} @@ -280,17 +304,15 @@ def filter_log_syslogd3_filter_data(json): return dictionary -def flatten_multilists_attributes(data): - multilist_attrs = [] - - for attr in multilist_attrs: - try: - path = "data['" + "']['".join(elem for elem in attr) + "']" - current_val = eval(path) - flattened_val = ' '.join(elem for elem in current_val) - exec(path + '= flattened_val') - except BaseException: - pass +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 @@ -298,56 +320,62 @@ def flatten_multilists_attributes(data): def log_syslogd3_filter(data, fos): vdom = data['vdom'] log_syslogd3_filter_data = data['log_syslogd3_filter'] - flattened_data = flatten_multilists_attributes(log_syslogd3_filter_data) - filtered_data = filter_log_syslogd3_filter_data(flattened_data) + filtered_data = underscore_to_hyphen(filter_log_syslogd3_filter_data(log_syslogd3_filter_data)) + return fos.set('log.syslogd3', 'filter', data=filtered_data, vdom=vdom) +def is_successful_status(status): + return status['status'] == "success" or \ + status['http_method'] == "DELETE" and status['http_status'] == 404 + + def fortios_log_syslogd3(data, fos): - login(data) if data['log_syslogd3_filter']: resp = log_syslogd3_filter(data, fos) - fos.logout() - return not resp['status'] == "success", resp['status'] == "success", resp + return not is_successful_status(resp), \ + resp['status'] == "success", \ + resp def main(): fields = { - "host": {"required": True, "type": "str"}, - "username": {"required": True, "type": "str"}, - "password": {"required": False, "type": "str", "no_log": True}, + "host": {"required": False, "type": "str"}, + "username": {"required": False, "type": "str"}, + "password": {"required": False, "type": "str", "default": "", "no_log": True}, "vdom": {"required": False, "type": "str", "default": "root"}, "https": {"required": False, "type": "bool", "default": True}, + "ssl_verify": {"required": False, "type": "bool", "default": True}, "log_syslogd3_filter": { - "required": False, "type": "dict", + "required": False, "type": "dict", "default": None, "options": { "anomaly": {"required": False, "type": "str", "choices": ["enable", "disable"]}, "dns": {"required": False, "type": "str", "choices": ["enable", "disable"]}, "filter": {"required": False, "type": "str"}, - "filter-type": {"required": False, "type": "str", + "filter_type": {"required": False, "type": "str", "choices": ["include", "exclude"]}, - "forward-traffic": {"required": False, "type": "str", + "forward_traffic": {"required": False, "type": "str", "choices": ["enable", "disable"]}, "gtp": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "local-traffic": {"required": False, "type": "str", + "local_traffic": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "multicast-traffic": {"required": False, "type": "str", + "multicast_traffic": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "netscan-discovery": {"required": False, "type": "str"}, - "netscan-vulnerability": {"required": False, "type": "str"}, + "netscan_discovery": {"required": False, "type": "str"}, + "netscan_vulnerability": {"required": False, "type": "str"}, "severity": {"required": False, "type": "str", "choices": ["emergency", "alert", "critical", "error", "warning", "notification", "information", "debug"]}, - "sniffer-traffic": {"required": False, "type": "str", + "sniffer_traffic": {"required": False, "type": "str", "choices": ["enable", "disable"]}, "ssh": {"required": False, "type": "str", "choices": ["enable", "disable"]}, @@ -360,15 +388,31 @@ def main(): module = AnsibleModule(argument_spec=fields, supports_check_mode=False) - try: - from fortiosapi import FortiOSAPI - except ImportError: - module.fail_json(msg="fortiosapi module is required") - global fos - 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_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: module.exit_json(changed=has_changed, meta=result) diff --git a/lib/ansible/modules/network/fortios/fortios_log_syslogd3_setting.py b/lib/ansible/modules/network/fortios/fortios_log_syslogd3_setting.py index edf2341df5b..e19698e144a 100644 --- a/lib/ansible/modules/network/fortios/fortios_log_syslogd3_setting.py +++ b/lib/ansible/modules/network/fortios/fortios_log_syslogd3_setting.py @@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function) # # You should have received a copy of the GNU General Public License # along with this program. If not, see . -# -# the lib use python logging can get it if the following is set in your -# Ansible config. __metaclass__ = type @@ -29,10 +26,10 @@ DOCUMENTATION = ''' module: fortios_log_syslogd3_setting short_description: Global settings for remote syslog server in Fortinet's FortiOS and FortiGate. 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. 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" author: - Miguel Angel Munoz (@mamunozgonzalez) @@ -44,54 +41,70 @@ requirements: - fortiosapi>=0.9.8 options: host: - description: - - FortiOS or FortiGate ip address. - required: true + description: + - FortiOS or FortiGate IP address. + type: str + required: false username: description: - FortiOS or FortiGate username. - required: true + type: str + required: false password: description: - FortiOS or FortiGate password. + type: str default: "" vdom: description: - Virtual domain, among those defined previously. A vdom is a virtual instance of the FortiGate that can be configured and used as a different unit. + type: str default: root https: description: - - Indicates if the requests towards FortiGate must use HTTPS - protocol + - Indicates if the requests towards FortiGate must use HTTPS protocol. + type: bool + default: true + ssl_verify: + description: + - Ensures FortiGate certificate must be verified by a proper CA. type: bool default: true + version_added: 2.9 log_syslogd3_setting: description: - Global settings for remote syslog server. default: null + type: dict suboptions: certificate: description: - Certificate used to communicate with Syslog server. Source certificate.local.name. - custom-field-name: + type: str + custom_field_name: description: - Custom field name for CEF format logging. + type: list suboptions: custom: description: - Field custom name. + type: str id: description: - Entry ID. required: true + type: int name: description: - Field name. - enc-algorithm: + type: str + enc_algorithm: description: - Enable/disable reliable syslogging with TLS encryption. + type: str choices: - high-medium - high @@ -100,6 +113,7 @@ options: facility: description: - Remote syslog facility. + type: str choices: - kernel - user @@ -128,6 +142,7 @@ options: format: description: - Log format. + type: str choices: - default - csv @@ -135,6 +150,7 @@ options: mode: description: - Remote syslog logging over UDP/Reliable TCP. + type: str choices: - udp - legacy-reliable @@ -142,15 +158,29 @@ options: port: description: - Server listen port. + type: int server: description: - Address of remote syslog server. - source-ip: + type: str + source_ip: description: - 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: description: - Enable/disable remote syslog logging. + type: str choices: - enable - disable @@ -163,6 +193,7 @@ EXAMPLES = ''' username: "admin" password: "" vdom: "root" + ssl_verify: "False" tasks: - name: Global settings for remote syslog server. fortios_log_syslogd3_setting: @@ -173,18 +204,19 @@ EXAMPLES = ''' https: "False" log_syslogd3_setting: certificate: " (source certificate.local.name)" - custom-field-name: + custom_field_name: - custom: "" id: "6" name: "default_name_7" - enc-algorithm: "high-medium" + enc_algorithm: "high-medium" facility: "kernel" format: "default" mode: "udp" port: "12" server: "192.168.100.40" - source-ip: "84.230.14.43" + source_ip: "84.230.14.43" + ssl_min_proto_version: "default" status: "enable" ''' @@ -248,14 +280,16 @@ version: ''' from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.connection import Connection +from ansible.module_utils.network.fortios.fortios import FortiOSHandler +from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG -fos = None - -def login(data): +def login(data, fos): host = data['host'] username = data['username'] password = data['password'] + ssl_verify = data['ssl_verify'] fos.debug('on') if 'https' in data and not data['https']: @@ -263,14 +297,14 @@ def login(data): else: fos.https('on') - fos.login(host, username, password) + fos.login(host, username, password, verify=ssl_verify) 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', - 'port', 'server', 'source-ip', - 'status'] + 'port', 'server', 'source_ip', + 'ssl_min_proto_version', 'status'] dictionary = {} for attribute in option_list: @@ -280,17 +314,15 @@ def filter_log_syslogd3_setting_data(json): return dictionary -def flatten_multilists_attributes(data): - multilist_attrs = [] - - for attr in multilist_attrs: - try: - path = "data['" + "']['".join(elem for elem in attr) + "']" - current_val = eval(path) - flattened_val = ' '.join(elem for elem in current_val) - exec(path + '= flattened_val') - except BaseException: - pass +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 @@ -298,42 +330,48 @@ def flatten_multilists_attributes(data): def log_syslogd3_setting(data, fos): vdom = data['vdom'] log_syslogd3_setting_data = data['log_syslogd3_setting'] - flattened_data = flatten_multilists_attributes(log_syslogd3_setting_data) - filtered_data = filter_log_syslogd3_setting_data(flattened_data) + filtered_data = underscore_to_hyphen(filter_log_syslogd3_setting_data(log_syslogd3_setting_data)) + return fos.set('log.syslogd3', 'setting', data=filtered_data, vdom=vdom) +def is_successful_status(status): + return status['status'] == "success" or \ + status['http_method'] == "DELETE" and status['http_status'] == 404 + + def fortios_log_syslogd3(data, fos): - login(data) if data['log_syslogd3_setting']: resp = log_syslogd3_setting(data, fos) - fos.logout() - return not resp['status'] == "success", resp['status'] == "success", resp + return not is_successful_status(resp), \ + resp['status'] == "success", \ + resp def main(): fields = { - "host": {"required": True, "type": "str"}, - "username": {"required": True, "type": "str"}, - "password": {"required": False, "type": "str", "no_log": True}, + "host": {"required": False, "type": "str"}, + "username": {"required": False, "type": "str"}, + "password": {"required": False, "type": "str", "default": "", "no_log": True}, "vdom": {"required": False, "type": "str", "default": "root"}, "https": {"required": False, "type": "bool", "default": True}, + "ssl_verify": {"required": False, "type": "bool", "default": True}, "log_syslogd3_setting": { - "required": False, "type": "dict", + "required": False, "type": "dict", "default": None, "options": { "certificate": {"required": False, "type": "str"}, - "custom-field-name": {"required": False, "type": "list", + "custom_field_name": {"required": False, "type": "list", "options": { "custom": {"required": False, "type": "str"}, "id": {"required": True, "type": "int"}, "name": {"required": False, "type": "str"} }}, - "enc-algorithm": {"required": False, "type": "str", + "enc_algorithm": {"required": False, "type": "str", "choices": ["high-medium", "high", "low", "disable"]}, "facility": {"required": False, "type": "str", @@ -351,7 +389,10 @@ def main(): "choices": ["udp", "legacy-reliable", "reliable"]}, "port": {"required": False, "type": "int"}, "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", "choices": ["enable", "disable"]} @@ -361,15 +402,31 @@ def main(): module = AnsibleModule(argument_spec=fields, supports_check_mode=False) - try: - from fortiosapi import FortiOSAPI - except ImportError: - module.fail_json(msg="fortiosapi module is required") - global fos - 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_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: module.exit_json(changed=has_changed, meta=result) diff --git a/lib/ansible/modules/network/fortios/fortios_log_syslogd4_filter.py b/lib/ansible/modules/network/fortios/fortios_log_syslogd4_filter.py index f93044139f8..b7577e27687 100644 --- a/lib/ansible/modules/network/fortios/fortios_log_syslogd4_filter.py +++ b/lib/ansible/modules/network/fortios/fortios_log_syslogd4_filter.py @@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function) # # You should have received a copy of the GNU General Public License # along with this program. If not, see . -# -# the lib use python logging can get it if the following is set in your -# Ansible config. __metaclass__ = type @@ -29,10 +26,10 @@ DOCUMENTATION = ''' module: fortios_log_syslogd4_filter short_description: Filters for remote system server in Fortinet's FortiOS and FortiGate. 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. 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" author: - Miguel Angel Munoz (@mamunozgonzalez) @@ -44,88 +41,109 @@ requirements: - fortiosapi>=0.9.8 options: host: - description: - - FortiOS or FortiGate ip address. - required: true + description: + - FortiOS or FortiGate IP address. + type: str + required: false username: description: - FortiOS or FortiGate username. - required: true + type: str + required: false password: description: - FortiOS or FortiGate password. + type: str default: "" vdom: description: - Virtual domain, among those defined previously. A vdom is a virtual instance of the FortiGate that can be configured and used as a different unit. + type: str default: root https: description: - - Indicates if the requests towards FortiGate must use HTTPS - protocol + - Indicates if the requests towards FortiGate must use HTTPS protocol. + type: bool + default: true + ssl_verify: + description: + - Ensures FortiGate certificate must be verified by a proper CA. type: bool default: true + version_added: 2.9 log_syslogd4_filter: description: - Filters for remote system server. default: null + type: dict suboptions: anomaly: description: - Enable/disable anomaly logging. + type: str choices: - enable - disable dns: description: - Enable/disable detailed DNS event logging. + type: str choices: - enable - disable filter: description: - Syslog 4 filter. - filter-type: + type: str + filter_type: description: - Include/exclude logs that match the filter. + type: str choices: - include - exclude - forward-traffic: + forward_traffic: description: - Enable/disable forward traffic logging. + type: str choices: - enable - disable gtp: description: - Enable/disable GTP messages logging. + type: str choices: - enable - disable - local-traffic: + local_traffic: description: - Enable/disable local in or out traffic logging. + type: str choices: - enable - disable - multicast-traffic: + multicast_traffic: description: - Enable/disable multicast traffic logging. + type: str choices: - enable - disable - netscan-discovery: + netscan_discovery: description: - Enable/disable netscan discovery event logging. - netscan-vulnerability: + type: str + netscan_vulnerability: description: - Enable/disable netscan vulnerability event logging. + type: str severity: description: - Lowest severity level to log. + type: str choices: - emergency - alert @@ -135,21 +153,24 @@ options: - notification - information - debug - sniffer-traffic: + sniffer_traffic: description: - Enable/disable sniffer traffic logging. + type: str choices: - enable - disable ssh: description: - Enable/disable SSH logging. + type: str choices: - enable - disable voip: description: - Enable/disable VoIP logging. + type: str choices: - enable - disable @@ -162,6 +183,7 @@ EXAMPLES = ''' username: "admin" password: "" vdom: "root" + ssl_verify: "False" tasks: - name: Filters for remote system server. fortios_log_syslogd4_filter: @@ -174,15 +196,15 @@ EXAMPLES = ''' anomaly: "enable" dns: "enable" filter: "" - filter-type: "include" - forward-traffic: "enable" + filter_type: "include" + forward_traffic: "enable" gtp: "enable" - local-traffic: "enable" - multicast-traffic: "enable" - netscan-discovery: "" - netscan-vulnerability: "" + local_traffic: "enable" + multicast_traffic: "enable" + netscan_discovery: "" + netscan_vulnerability: "" severity: "emergency" - sniffer-traffic: "enable" + sniffer_traffic: "enable" ssh: "enable" voip: "enable" ''' @@ -247,14 +269,16 @@ version: ''' from ansible.module_utils.basic import AnsibleModule - -fos = None +from ansible.module_utils.connection import Connection +from ansible.module_utils.network.fortios.fortios import FortiOSHandler +from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG -def login(data): +def login(data, fos): host = data['host'] username = data['username'] password = data['password'] + ssl_verify = data['ssl_verify'] fos.debug('on') if 'https' in data and not data['https']: @@ -262,14 +286,14 @@ def login(data): else: fos.https('on') - fos.login(host, username, password) + fos.login(host, username, password, verify=ssl_verify) def filter_log_syslogd4_filter_data(json): option_list = ['anomaly', 'dns', 'filter', - 'filter-type', 'forward-traffic', 'gtp', - 'local-traffic', 'multicast-traffic', 'netscan-discovery', - 'netscan-vulnerability', 'severity', 'sniffer-traffic', + 'filter_type', 'forward_traffic', 'gtp', + 'local_traffic', 'multicast_traffic', 'netscan_discovery', + 'netscan_vulnerability', 'severity', 'sniffer_traffic', 'ssh', 'voip'] dictionary = {} @@ -280,17 +304,15 @@ def filter_log_syslogd4_filter_data(json): return dictionary -def flatten_multilists_attributes(data): - multilist_attrs = [] - - for attr in multilist_attrs: - try: - path = "data['" + "']['".join(elem for elem in attr) + "']" - current_val = eval(path) - flattened_val = ' '.join(elem for elem in current_val) - exec(path + '= flattened_val') - except BaseException: - pass +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 @@ -298,56 +320,62 @@ def flatten_multilists_attributes(data): def log_syslogd4_filter(data, fos): vdom = data['vdom'] log_syslogd4_filter_data = data['log_syslogd4_filter'] - flattened_data = flatten_multilists_attributes(log_syslogd4_filter_data) - filtered_data = filter_log_syslogd4_filter_data(flattened_data) + filtered_data = underscore_to_hyphen(filter_log_syslogd4_filter_data(log_syslogd4_filter_data)) + return fos.set('log.syslogd4', 'filter', data=filtered_data, vdom=vdom) +def is_successful_status(status): + return status['status'] == "success" or \ + status['http_method'] == "DELETE" and status['http_status'] == 404 + + def fortios_log_syslogd4(data, fos): - login(data) if data['log_syslogd4_filter']: resp = log_syslogd4_filter(data, fos) - fos.logout() - return not resp['status'] == "success", resp['status'] == "success", resp + return not is_successful_status(resp), \ + resp['status'] == "success", \ + resp def main(): fields = { - "host": {"required": True, "type": "str"}, - "username": {"required": True, "type": "str"}, - "password": {"required": False, "type": "str", "no_log": True}, + "host": {"required": False, "type": "str"}, + "username": {"required": False, "type": "str"}, + "password": {"required": False, "type": "str", "default": "", "no_log": True}, "vdom": {"required": False, "type": "str", "default": "root"}, "https": {"required": False, "type": "bool", "default": True}, + "ssl_verify": {"required": False, "type": "bool", "default": True}, "log_syslogd4_filter": { - "required": False, "type": "dict", + "required": False, "type": "dict", "default": None, "options": { "anomaly": {"required": False, "type": "str", "choices": ["enable", "disable"]}, "dns": {"required": False, "type": "str", "choices": ["enable", "disable"]}, "filter": {"required": False, "type": "str"}, - "filter-type": {"required": False, "type": "str", + "filter_type": {"required": False, "type": "str", "choices": ["include", "exclude"]}, - "forward-traffic": {"required": False, "type": "str", + "forward_traffic": {"required": False, "type": "str", "choices": ["enable", "disable"]}, "gtp": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "local-traffic": {"required": False, "type": "str", + "local_traffic": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "multicast-traffic": {"required": False, "type": "str", + "multicast_traffic": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "netscan-discovery": {"required": False, "type": "str"}, - "netscan-vulnerability": {"required": False, "type": "str"}, + "netscan_discovery": {"required": False, "type": "str"}, + "netscan_vulnerability": {"required": False, "type": "str"}, "severity": {"required": False, "type": "str", "choices": ["emergency", "alert", "critical", "error", "warning", "notification", "information", "debug"]}, - "sniffer-traffic": {"required": False, "type": "str", + "sniffer_traffic": {"required": False, "type": "str", "choices": ["enable", "disable"]}, "ssh": {"required": False, "type": "str", "choices": ["enable", "disable"]}, @@ -360,15 +388,31 @@ def main(): module = AnsibleModule(argument_spec=fields, supports_check_mode=False) - try: - from fortiosapi import FortiOSAPI - except ImportError: - module.fail_json(msg="fortiosapi module is required") - global fos - 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_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: module.exit_json(changed=has_changed, meta=result) diff --git a/lib/ansible/modules/network/fortios/fortios_log_syslogd4_setting.py b/lib/ansible/modules/network/fortios/fortios_log_syslogd4_setting.py index 96cc6bfb685..564599a50cf 100644 --- a/lib/ansible/modules/network/fortios/fortios_log_syslogd4_setting.py +++ b/lib/ansible/modules/network/fortios/fortios_log_syslogd4_setting.py @@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function) # # You should have received a copy of the GNU General Public License # along with this program. If not, see . -# -# the lib use python logging can get it if the following is set in your -# Ansible config. __metaclass__ = type @@ -29,10 +26,10 @@ DOCUMENTATION = ''' module: fortios_log_syslogd4_setting short_description: Global settings for remote syslog server in Fortinet's FortiOS and FortiGate. 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. 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" author: - Miguel Angel Munoz (@mamunozgonzalez) @@ -44,54 +41,70 @@ requirements: - fortiosapi>=0.9.8 options: host: - description: - - FortiOS or FortiGate ip address. - required: true + description: + - FortiOS or FortiGate IP address. + type: str + required: false username: description: - FortiOS or FortiGate username. - required: true + type: str + required: false password: description: - FortiOS or FortiGate password. + type: str default: "" vdom: description: - Virtual domain, among those defined previously. A vdom is a virtual instance of the FortiGate that can be configured and used as a different unit. + type: str default: root https: description: - - Indicates if the requests towards FortiGate must use HTTPS - protocol + - Indicates if the requests towards FortiGate must use HTTPS protocol. + type: bool + default: true + ssl_verify: + description: + - Ensures FortiGate certificate must be verified by a proper CA. type: bool default: true + version_added: 2.9 log_syslogd4_setting: description: - Global settings for remote syslog server. default: null + type: dict suboptions: certificate: description: - Certificate used to communicate with Syslog server. Source certificate.local.name. - custom-field-name: + type: str + custom_field_name: description: - Custom field name for CEF format logging. + type: list suboptions: custom: description: - Field custom name. + type: str id: description: - Entry ID. required: true + type: int name: description: - Field name. - enc-algorithm: + type: str + enc_algorithm: description: - Enable/disable reliable syslogging with TLS encryption. + type: str choices: - high-medium - high @@ -100,6 +113,7 @@ options: facility: description: - Remote syslog facility. + type: str choices: - kernel - user @@ -128,6 +142,7 @@ options: format: description: - Log format. + type: str choices: - default - csv @@ -135,6 +150,7 @@ options: mode: description: - Remote syslog logging over UDP/Reliable TCP. + type: str choices: - udp - legacy-reliable @@ -142,15 +158,29 @@ options: port: description: - Server listen port. + type: int server: description: - Address of remote syslog server. - source-ip: + type: str + source_ip: description: - 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: description: - Enable/disable remote syslog logging. + type: str choices: - enable - disable @@ -163,6 +193,7 @@ EXAMPLES = ''' username: "admin" password: "" vdom: "root" + ssl_verify: "False" tasks: - name: Global settings for remote syslog server. fortios_log_syslogd4_setting: @@ -173,18 +204,19 @@ EXAMPLES = ''' https: "False" log_syslogd4_setting: certificate: " (source certificate.local.name)" - custom-field-name: + custom_field_name: - custom: "" id: "6" name: "default_name_7" - enc-algorithm: "high-medium" + enc_algorithm: "high-medium" facility: "kernel" format: "default" mode: "udp" port: "12" server: "192.168.100.40" - source-ip: "84.230.14.43" + source_ip: "84.230.14.43" + ssl_min_proto_version: "default" status: "enable" ''' @@ -248,14 +280,16 @@ version: ''' from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.connection import Connection +from ansible.module_utils.network.fortios.fortios import FortiOSHandler +from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG -fos = None - -def login(data): +def login(data, fos): host = data['host'] username = data['username'] password = data['password'] + ssl_verify = data['ssl_verify'] fos.debug('on') if 'https' in data and not data['https']: @@ -263,14 +297,14 @@ def login(data): else: fos.https('on') - fos.login(host, username, password) + fos.login(host, username, password, verify=ssl_verify) 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', - 'port', 'server', 'source-ip', - 'status'] + 'port', 'server', 'source_ip', + 'ssl_min_proto_version', 'status'] dictionary = {} for attribute in option_list: @@ -280,17 +314,15 @@ def filter_log_syslogd4_setting_data(json): return dictionary -def flatten_multilists_attributes(data): - multilist_attrs = [] - - for attr in multilist_attrs: - try: - path = "data['" + "']['".join(elem for elem in attr) + "']" - current_val = eval(path) - flattened_val = ' '.join(elem for elem in current_val) - exec(path + '= flattened_val') - except BaseException: - pass +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 @@ -298,42 +330,48 @@ def flatten_multilists_attributes(data): def log_syslogd4_setting(data, fos): vdom = data['vdom'] log_syslogd4_setting_data = data['log_syslogd4_setting'] - flattened_data = flatten_multilists_attributes(log_syslogd4_setting_data) - filtered_data = filter_log_syslogd4_setting_data(flattened_data) + filtered_data = underscore_to_hyphen(filter_log_syslogd4_setting_data(log_syslogd4_setting_data)) + return fos.set('log.syslogd4', 'setting', data=filtered_data, vdom=vdom) +def is_successful_status(status): + return status['status'] == "success" or \ + status['http_method'] == "DELETE" and status['http_status'] == 404 + + def fortios_log_syslogd4(data, fos): - login(data) if data['log_syslogd4_setting']: resp = log_syslogd4_setting(data, fos) - fos.logout() - return not resp['status'] == "success", resp['status'] == "success", resp + return not is_successful_status(resp), \ + resp['status'] == "success", \ + resp def main(): fields = { - "host": {"required": True, "type": "str"}, - "username": {"required": True, "type": "str"}, - "password": {"required": False, "type": "str", "no_log": True}, + "host": {"required": False, "type": "str"}, + "username": {"required": False, "type": "str"}, + "password": {"required": False, "type": "str", "default": "", "no_log": True}, "vdom": {"required": False, "type": "str", "default": "root"}, "https": {"required": False, "type": "bool", "default": True}, + "ssl_verify": {"required": False, "type": "bool", "default": True}, "log_syslogd4_setting": { - "required": False, "type": "dict", + "required": False, "type": "dict", "default": None, "options": { "certificate": {"required": False, "type": "str"}, - "custom-field-name": {"required": False, "type": "list", + "custom_field_name": {"required": False, "type": "list", "options": { "custom": {"required": False, "type": "str"}, "id": {"required": True, "type": "int"}, "name": {"required": False, "type": "str"} }}, - "enc-algorithm": {"required": False, "type": "str", + "enc_algorithm": {"required": False, "type": "str", "choices": ["high-medium", "high", "low", "disable"]}, "facility": {"required": False, "type": "str", @@ -351,7 +389,10 @@ def main(): "choices": ["udp", "legacy-reliable", "reliable"]}, "port": {"required": False, "type": "int"}, "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", "choices": ["enable", "disable"]} @@ -361,15 +402,31 @@ def main(): module = AnsibleModule(argument_spec=fields, supports_check_mode=False) - try: - from fortiosapi import FortiOSAPI - except ImportError: - module.fail_json(msg="fortiosapi module is required") - global fos - 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_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: module.exit_json(changed=has_changed, meta=result) diff --git a/lib/ansible/modules/network/fortios/fortios_log_syslogd_filter.py b/lib/ansible/modules/network/fortios/fortios_log_syslogd_filter.py index 5f2e337df2e..5c9af71131b 100644 --- a/lib/ansible/modules/network/fortios/fortios_log_syslogd_filter.py +++ b/lib/ansible/modules/network/fortios/fortios_log_syslogd_filter.py @@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function) # # You should have received a copy of the GNU General Public License # along with this program. If not, see . -# -# the lib use python logging can get it if the following is set in your -# Ansible config. __metaclass__ = type @@ -29,10 +26,10 @@ DOCUMENTATION = ''' module: fortios_log_syslogd_filter short_description: Filters for remote system server in Fortinet's FortiOS and FortiGate. 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. 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" author: - Miguel Angel Munoz (@mamunozgonzalez) @@ -44,88 +41,109 @@ requirements: - fortiosapi>=0.9.8 options: host: - description: - - FortiOS or FortiGate ip address. - required: true + description: + - FortiOS or FortiGate IP address. + type: str + required: false username: description: - FortiOS or FortiGate username. - required: true + type: str + required: false password: description: - FortiOS or FortiGate password. + type: str default: "" vdom: description: - Virtual domain, among those defined previously. A vdom is a virtual instance of the FortiGate that can be configured and used as a different unit. + type: str default: root https: description: - - Indicates if the requests towards FortiGate must use HTTPS - protocol + - Indicates if the requests towards FortiGate must use HTTPS protocol. + type: bool + default: true + ssl_verify: + description: + - Ensures FortiGate certificate must be verified by a proper CA. type: bool default: true + version_added: 2.9 log_syslogd_filter: description: - Filters for remote system server. default: null + type: dict suboptions: anomaly: description: - Enable/disable anomaly logging. + type: str choices: - enable - disable dns: description: - Enable/disable detailed DNS event logging. + type: str choices: - enable - disable filter: description: - Syslog filter. - filter-type: + type: str + filter_type: description: - Include/exclude logs that match the filter. + type: str choices: - include - exclude - forward-traffic: + forward_traffic: description: - Enable/disable forward traffic logging. + type: str choices: - enable - disable gtp: description: - Enable/disable GTP messages logging. + type: str choices: - enable - disable - local-traffic: + local_traffic: description: - Enable/disable local in or out traffic logging. + type: str choices: - enable - disable - multicast-traffic: + multicast_traffic: description: - Enable/disable multicast traffic logging. + type: str choices: - enable - disable - netscan-discovery: + netscan_discovery: description: - Enable/disable netscan discovery event logging. - netscan-vulnerability: + type: str + netscan_vulnerability: description: - Enable/disable netscan vulnerability event logging. + type: str severity: description: - Lowest severity level to log. + type: str choices: - emergency - alert @@ -135,21 +153,24 @@ options: - notification - information - debug - sniffer-traffic: + sniffer_traffic: description: - Enable/disable sniffer traffic logging. + type: str choices: - enable - disable ssh: description: - Enable/disable SSH logging. + type: str choices: - enable - disable voip: description: - Enable/disable VoIP logging. + type: str choices: - enable - disable @@ -162,6 +183,7 @@ EXAMPLES = ''' username: "admin" password: "" vdom: "root" + ssl_verify: "False" tasks: - name: Filters for remote system server. fortios_log_syslogd_filter: @@ -174,15 +196,15 @@ EXAMPLES = ''' anomaly: "enable" dns: "enable" filter: "" - filter-type: "include" - forward-traffic: "enable" + filter_type: "include" + forward_traffic: "enable" gtp: "enable" - local-traffic: "enable" - multicast-traffic: "enable" - netscan-discovery: "" - netscan-vulnerability: "" + local_traffic: "enable" + multicast_traffic: "enable" + netscan_discovery: "" + netscan_vulnerability: "" severity: "emergency" - sniffer-traffic: "enable" + sniffer_traffic: "enable" ssh: "enable" voip: "enable" ''' @@ -247,14 +269,16 @@ version: ''' from ansible.module_utils.basic import AnsibleModule - -fos = None +from ansible.module_utils.connection import Connection +from ansible.module_utils.network.fortios.fortios import FortiOSHandler +from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG -def login(data): +def login(data, fos): host = data['host'] username = data['username'] password = data['password'] + ssl_verify = data['ssl_verify'] fos.debug('on') if 'https' in data and not data['https']: @@ -262,14 +286,14 @@ def login(data): else: fos.https('on') - fos.login(host, username, password) + fos.login(host, username, password, verify=ssl_verify) def filter_log_syslogd_filter_data(json): option_list = ['anomaly', 'dns', 'filter', - 'filter-type', 'forward-traffic', 'gtp', - 'local-traffic', 'multicast-traffic', 'netscan-discovery', - 'netscan-vulnerability', 'severity', 'sniffer-traffic', + 'filter_type', 'forward_traffic', 'gtp', + 'local_traffic', 'multicast_traffic', 'netscan_discovery', + 'netscan_vulnerability', 'severity', 'sniffer_traffic', 'ssh', 'voip'] dictionary = {} @@ -280,17 +304,15 @@ def filter_log_syslogd_filter_data(json): return dictionary -def flatten_multilists_attributes(data): - multilist_attrs = [] - - for attr in multilist_attrs: - try: - path = "data['" + "']['".join(elem for elem in attr) + "']" - current_val = eval(path) - flattened_val = ' '.join(elem for elem in current_val) - exec(path + '= flattened_val') - except BaseException: - pass +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 @@ -298,56 +320,62 @@ def flatten_multilists_attributes(data): def log_syslogd_filter(data, fos): vdom = data['vdom'] log_syslogd_filter_data = data['log_syslogd_filter'] - flattened_data = flatten_multilists_attributes(log_syslogd_filter_data) - filtered_data = filter_log_syslogd_filter_data(flattened_data) + filtered_data = underscore_to_hyphen(filter_log_syslogd_filter_data(log_syslogd_filter_data)) + return fos.set('log.syslogd', 'filter', data=filtered_data, vdom=vdom) +def is_successful_status(status): + return status['status'] == "success" or \ + status['http_method'] == "DELETE" and status['http_status'] == 404 + + def fortios_log_syslogd(data, fos): - login(data) if data['log_syslogd_filter']: resp = log_syslogd_filter(data, fos) - fos.logout() - return not resp['status'] == "success", resp['status'] == "success", resp + return not is_successful_status(resp), \ + resp['status'] == "success", \ + resp def main(): fields = { - "host": {"required": True, "type": "str"}, - "username": {"required": True, "type": "str"}, - "password": {"required": False, "type": "str", "no_log": True}, + "host": {"required": False, "type": "str"}, + "username": {"required": False, "type": "str"}, + "password": {"required": False, "type": "str", "default": "", "no_log": True}, "vdom": {"required": False, "type": "str", "default": "root"}, "https": {"required": False, "type": "bool", "default": True}, + "ssl_verify": {"required": False, "type": "bool", "default": True}, "log_syslogd_filter": { - "required": False, "type": "dict", + "required": False, "type": "dict", "default": None, "options": { "anomaly": {"required": False, "type": "str", "choices": ["enable", "disable"]}, "dns": {"required": False, "type": "str", "choices": ["enable", "disable"]}, "filter": {"required": False, "type": "str"}, - "filter-type": {"required": False, "type": "str", + "filter_type": {"required": False, "type": "str", "choices": ["include", "exclude"]}, - "forward-traffic": {"required": False, "type": "str", + "forward_traffic": {"required": False, "type": "str", "choices": ["enable", "disable"]}, "gtp": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "local-traffic": {"required": False, "type": "str", + "local_traffic": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "multicast-traffic": {"required": False, "type": "str", + "multicast_traffic": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "netscan-discovery": {"required": False, "type": "str"}, - "netscan-vulnerability": {"required": False, "type": "str"}, + "netscan_discovery": {"required": False, "type": "str"}, + "netscan_vulnerability": {"required": False, "type": "str"}, "severity": {"required": False, "type": "str", "choices": ["emergency", "alert", "critical", "error", "warning", "notification", "information", "debug"]}, - "sniffer-traffic": {"required": False, "type": "str", + "sniffer_traffic": {"required": False, "type": "str", "choices": ["enable", "disable"]}, "ssh": {"required": False, "type": "str", "choices": ["enable", "disable"]}, @@ -360,15 +388,31 @@ def main(): module = AnsibleModule(argument_spec=fields, supports_check_mode=False) - try: - from fortiosapi import FortiOSAPI - except ImportError: - module.fail_json(msg="fortiosapi module is required") - global fos - 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_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: module.exit_json(changed=has_changed, meta=result) diff --git a/lib/ansible/modules/network/fortios/fortios_log_syslogd_override_filter.py b/lib/ansible/modules/network/fortios/fortios_log_syslogd_override_filter.py index a0f5d45e871..1e2698c50d1 100644 --- a/lib/ansible/modules/network/fortios/fortios_log_syslogd_override_filter.py +++ b/lib/ansible/modules/network/fortios/fortios_log_syslogd_override_filter.py @@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function) # # You should have received a copy of the GNU General Public License # along with this program. If not, see . -# -# the lib use python logging can get it if the following is set in your -# Ansible config. __metaclass__ = type @@ -29,10 +26,10 @@ DOCUMENTATION = ''' module: fortios_log_syslogd_override_filter short_description: Override filters for remote system server in Fortinet's FortiOS and FortiGate. 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. 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" author: - Miguel Angel Munoz (@mamunozgonzalez) @@ -44,88 +41,109 @@ requirements: - fortiosapi>=0.9.8 options: host: - description: - - FortiOS or FortiGate ip address. - required: true + description: + - FortiOS or FortiGate IP address. + type: str + required: false username: description: - FortiOS or FortiGate username. - required: true + type: str + required: false password: description: - FortiOS or FortiGate password. + type: str default: "" vdom: description: - Virtual domain, among those defined previously. A vdom is a virtual instance of the FortiGate that can be configured and used as a different unit. + type: str default: root https: description: - - Indicates if the requests towards FortiGate must use HTTPS - protocol + - Indicates if the requests towards FortiGate must use HTTPS protocol. + type: bool + default: true + ssl_verify: + description: + - Ensures FortiGate certificate must be verified by a proper CA. type: bool default: true + version_added: 2.9 log_syslogd_override_filter: description: - Override filters for remote system server. default: null + type: dict suboptions: anomaly: description: - Enable/disable anomaly logging. + type: str choices: - enable - disable dns: description: - Enable/disable detailed DNS event logging. + type: str choices: - enable - disable filter: description: - Syslog filter. - filter-type: + type: str + filter_type: description: - Include/exclude logs that match the filter. + type: str choices: - include - exclude - forward-traffic: + forward_traffic: description: - Enable/disable forward traffic logging. + type: str choices: - enable - disable gtp: description: - Enable/disable GTP messages logging. + type: str choices: - enable - disable - local-traffic: + local_traffic: description: - Enable/disable local in or out traffic logging. + type: str choices: - enable - disable - multicast-traffic: + multicast_traffic: description: - Enable/disable multicast traffic logging. + type: str choices: - enable - disable - netscan-discovery: + netscan_discovery: description: - Enable/disable netscan discovery event logging. - netscan-vulnerability: + type: str + netscan_vulnerability: description: - Enable/disable netscan vulnerability event logging. + type: str severity: description: - Lowest severity level to log. + type: str choices: - emergency - alert @@ -135,21 +153,24 @@ options: - notification - information - debug - sniffer-traffic: + sniffer_traffic: description: - Enable/disable sniffer traffic logging. + type: str choices: - enable - disable ssh: description: - Enable/disable SSH logging. + type: str choices: - enable - disable voip: description: - Enable/disable VoIP logging. + type: str choices: - enable - disable @@ -162,6 +183,7 @@ EXAMPLES = ''' username: "admin" password: "" vdom: "root" + ssl_verify: "False" tasks: - name: Override filters for remote system server. fortios_log_syslogd_override_filter: @@ -174,15 +196,15 @@ EXAMPLES = ''' anomaly: "enable" dns: "enable" filter: "" - filter-type: "include" - forward-traffic: "enable" + filter_type: "include" + forward_traffic: "enable" gtp: "enable" - local-traffic: "enable" - multicast-traffic: "enable" - netscan-discovery: "" - netscan-vulnerability: "" + local_traffic: "enable" + multicast_traffic: "enable" + netscan_discovery: "" + netscan_vulnerability: "" severity: "emergency" - sniffer-traffic: "enable" + sniffer_traffic: "enable" ssh: "enable" voip: "enable" ''' @@ -247,14 +269,16 @@ version: ''' from ansible.module_utils.basic import AnsibleModule - -fos = None +from ansible.module_utils.connection import Connection +from ansible.module_utils.network.fortios.fortios import FortiOSHandler +from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG -def login(data): +def login(data, fos): host = data['host'] username = data['username'] password = data['password'] + ssl_verify = data['ssl_verify'] fos.debug('on') if 'https' in data and not data['https']: @@ -262,14 +286,14 @@ def login(data): else: fos.https('on') - fos.login(host, username, password) + fos.login(host, username, password, verify=ssl_verify) def filter_log_syslogd_override_filter_data(json): option_list = ['anomaly', 'dns', 'filter', - 'filter-type', 'forward-traffic', 'gtp', - 'local-traffic', 'multicast-traffic', 'netscan-discovery', - 'netscan-vulnerability', 'severity', 'sniffer-traffic', + 'filter_type', 'forward_traffic', 'gtp', + 'local_traffic', 'multicast_traffic', 'netscan_discovery', + 'netscan_vulnerability', 'severity', 'sniffer_traffic', 'ssh', 'voip'] dictionary = {} @@ -280,17 +304,15 @@ def filter_log_syslogd_override_filter_data(json): return dictionary -def flatten_multilists_attributes(data): - multilist_attrs = [] - - for attr in multilist_attrs: - try: - path = "data['" + "']['".join(elem for elem in attr) + "']" - current_val = eval(path) - flattened_val = ' '.join(elem for elem in current_val) - exec(path + '= flattened_val') - except BaseException: - pass +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 @@ -298,56 +320,62 @@ def flatten_multilists_attributes(data): def log_syslogd_override_filter(data, fos): vdom = data['vdom'] log_syslogd_override_filter_data = data['log_syslogd_override_filter'] - flattened_data = flatten_multilists_attributes(log_syslogd_override_filter_data) - filtered_data = filter_log_syslogd_override_filter_data(flattened_data) + filtered_data = underscore_to_hyphen(filter_log_syslogd_override_filter_data(log_syslogd_override_filter_data)) + return fos.set('log.syslogd', 'override-filter', data=filtered_data, vdom=vdom) +def is_successful_status(status): + return status['status'] == "success" or \ + status['http_method'] == "DELETE" and status['http_status'] == 404 + + def fortios_log_syslogd(data, fos): - login(data) if data['log_syslogd_override_filter']: resp = log_syslogd_override_filter(data, fos) - fos.logout() - return not resp['status'] == "success", resp['status'] == "success", resp + return not is_successful_status(resp), \ + resp['status'] == "success", \ + resp def main(): fields = { - "host": {"required": True, "type": "str"}, - "username": {"required": True, "type": "str"}, - "password": {"required": False, "type": "str", "no_log": True}, + "host": {"required": False, "type": "str"}, + "username": {"required": False, "type": "str"}, + "password": {"required": False, "type": "str", "default": "", "no_log": True}, "vdom": {"required": False, "type": "str", "default": "root"}, "https": {"required": False, "type": "bool", "default": True}, + "ssl_verify": {"required": False, "type": "bool", "default": True}, "log_syslogd_override_filter": { - "required": False, "type": "dict", + "required": False, "type": "dict", "default": None, "options": { "anomaly": {"required": False, "type": "str", "choices": ["enable", "disable"]}, "dns": {"required": False, "type": "str", "choices": ["enable", "disable"]}, "filter": {"required": False, "type": "str"}, - "filter-type": {"required": False, "type": "str", + "filter_type": {"required": False, "type": "str", "choices": ["include", "exclude"]}, - "forward-traffic": {"required": False, "type": "str", + "forward_traffic": {"required": False, "type": "str", "choices": ["enable", "disable"]}, "gtp": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "local-traffic": {"required": False, "type": "str", + "local_traffic": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "multicast-traffic": {"required": False, "type": "str", + "multicast_traffic": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "netscan-discovery": {"required": False, "type": "str"}, - "netscan-vulnerability": {"required": False, "type": "str"}, + "netscan_discovery": {"required": False, "type": "str"}, + "netscan_vulnerability": {"required": False, "type": "str"}, "severity": {"required": False, "type": "str", "choices": ["emergency", "alert", "critical", "error", "warning", "notification", "information", "debug"]}, - "sniffer-traffic": {"required": False, "type": "str", + "sniffer_traffic": {"required": False, "type": "str", "choices": ["enable", "disable"]}, "ssh": {"required": False, "type": "str", "choices": ["enable", "disable"]}, @@ -360,15 +388,31 @@ def main(): module = AnsibleModule(argument_spec=fields, supports_check_mode=False) - try: - from fortiosapi import FortiOSAPI - except ImportError: - module.fail_json(msg="fortiosapi module is required") - global fos - 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_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: module.exit_json(changed=has_changed, meta=result) diff --git a/lib/ansible/modules/network/fortios/fortios_log_syslogd_override_setting.py b/lib/ansible/modules/network/fortios/fortios_log_syslogd_override_setting.py index 6f37547c493..d95243687a1 100644 --- a/lib/ansible/modules/network/fortios/fortios_log_syslogd_override_setting.py +++ b/lib/ansible/modules/network/fortios/fortios_log_syslogd_override_setting.py @@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function) # # You should have received a copy of the GNU General Public License # along with this program. If not, see . -# -# the lib use python logging can get it if the following is set in your -# Ansible config. __metaclass__ = type @@ -29,10 +26,10 @@ DOCUMENTATION = ''' module: fortios_log_syslogd_override_setting short_description: Override settings for remote syslog server in Fortinet's FortiOS and FortiGate. 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. 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" author: - Miguel Angel Munoz (@mamunozgonzalez) @@ -44,54 +41,70 @@ requirements: - fortiosapi>=0.9.8 options: host: - description: - - FortiOS or FortiGate ip address. - required: true + description: + - FortiOS or FortiGate IP address. + type: str + required: false username: description: - FortiOS or FortiGate username. - required: true + type: str + required: false password: description: - FortiOS or FortiGate password. + type: str default: "" vdom: description: - Virtual domain, among those defined previously. A vdom is a virtual instance of the FortiGate that can be configured and used as a different unit. + type: str default: root https: description: - - Indicates if the requests towards FortiGate must use HTTPS - protocol + - Indicates if the requests towards FortiGate must use HTTPS protocol. + type: bool + default: true + ssl_verify: + description: + - Ensures FortiGate certificate must be verified by a proper CA. type: bool default: true + version_added: 2.9 log_syslogd_override_setting: description: - Override settings for remote syslog server. default: null + type: dict suboptions: certificate: description: - Certificate used to communicate with Syslog server. Source certificate.local.name. - custom-field-name: + type: str + custom_field_name: description: - Custom field name for CEF format logging. + type: list suboptions: custom: description: - Field custom name. + type: str id: description: - Entry ID. required: true + type: int name: description: - Field name. - enc-algorithm: + type: str + enc_algorithm: description: - Enable/disable reliable syslogging with TLS encryption. + type: str choices: - high-medium - high @@ -100,6 +113,7 @@ options: facility: description: - Remote syslog facility. + type: str choices: - kernel - user @@ -128,6 +142,7 @@ options: format: description: - Log format. + type: str choices: - default - csv @@ -135,6 +150,7 @@ options: mode: description: - Remote syslog logging over UDP/Reliable TCP. + type: str choices: - udp - legacy-reliable @@ -142,21 +158,36 @@ options: override: description: - Enable/disable override syslog settings. + type: str choices: - enable - disable port: description: - Server listen port. + type: int server: description: - Address of remote syslog server. - source-ip: + type: str + source_ip: description: - 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: description: - Enable/disable remote syslog logging. + type: str choices: - enable - disable @@ -169,6 +200,7 @@ EXAMPLES = ''' username: "admin" password: "" vdom: "root" + ssl_verify: "False" tasks: - name: Override settings for remote syslog server. fortios_log_syslogd_override_setting: @@ -179,19 +211,20 @@ EXAMPLES = ''' https: "False" log_syslogd_override_setting: certificate: " (source certificate.local.name)" - custom-field-name: + custom_field_name: - custom: "" id: "6" name: "default_name_7" - enc-algorithm: "high-medium" + enc_algorithm: "high-medium" facility: "kernel" format: "default" mode: "udp" override: "enable" port: "13" server: "192.168.100.40" - source-ip: "84.230.14.43" + source_ip: "84.230.14.43" + ssl_min_proto_version: "default" status: "enable" ''' @@ -255,14 +288,16 @@ version: ''' from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.connection import Connection +from ansible.module_utils.network.fortios.fortios import FortiOSHandler +from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG -fos = None - -def login(data): +def login(data, fos): host = data['host'] username = data['username'] password = data['password'] + ssl_verify = data['ssl_verify'] fos.debug('on') if 'https' in data and not data['https']: @@ -270,14 +305,14 @@ def login(data): else: fos.https('on') - fos.login(host, username, password) + fos.login(host, username, password, verify=ssl_verify) 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', 'override', 'port', 'server', - 'source-ip', 'status'] + 'source_ip', 'ssl_min_proto_version', 'status'] dictionary = {} for attribute in option_list: @@ -287,17 +322,15 @@ def filter_log_syslogd_override_setting_data(json): return dictionary -def flatten_multilists_attributes(data): - multilist_attrs = [] - - for attr in multilist_attrs: - try: - path = "data['" + "']['".join(elem for elem in attr) + "']" - current_val = eval(path) - flattened_val = ' '.join(elem for elem in current_val) - exec(path + '= flattened_val') - except BaseException: - pass +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 @@ -305,42 +338,48 @@ def flatten_multilists_attributes(data): def log_syslogd_override_setting(data, fos): vdom = data['vdom'] log_syslogd_override_setting_data = data['log_syslogd_override_setting'] - flattened_data = flatten_multilists_attributes(log_syslogd_override_setting_data) - filtered_data = filter_log_syslogd_override_setting_data(flattened_data) + filtered_data = underscore_to_hyphen(filter_log_syslogd_override_setting_data(log_syslogd_override_setting_data)) + return fos.set('log.syslogd', 'override-setting', data=filtered_data, vdom=vdom) +def is_successful_status(status): + return status['status'] == "success" or \ + status['http_method'] == "DELETE" and status['http_status'] == 404 + + def fortios_log_syslogd(data, fos): - login(data) if data['log_syslogd_override_setting']: resp = log_syslogd_override_setting(data, fos) - fos.logout() - return not resp['status'] == "success", resp['status'] == "success", resp + return not is_successful_status(resp), \ + resp['status'] == "success", \ + resp def main(): fields = { - "host": {"required": True, "type": "str"}, - "username": {"required": True, "type": "str"}, - "password": {"required": False, "type": "str", "no_log": True}, + "host": {"required": False, "type": "str"}, + "username": {"required": False, "type": "str"}, + "password": {"required": False, "type": "str", "default": "", "no_log": True}, "vdom": {"required": False, "type": "str", "default": "root"}, "https": {"required": False, "type": "bool", "default": True}, + "ssl_verify": {"required": False, "type": "bool", "default": True}, "log_syslogd_override_setting": { - "required": False, "type": "dict", + "required": False, "type": "dict", "default": None, "options": { "certificate": {"required": False, "type": "str"}, - "custom-field-name": {"required": False, "type": "list", + "custom_field_name": {"required": False, "type": "list", "options": { "custom": {"required": False, "type": "str"}, "id": {"required": True, "type": "int"}, "name": {"required": False, "type": "str"} }}, - "enc-algorithm": {"required": False, "type": "str", + "enc_algorithm": {"required": False, "type": "str", "choices": ["high-medium", "high", "low", "disable"]}, "facility": {"required": False, "type": "str", @@ -360,7 +399,10 @@ def main(): "choices": ["enable", "disable"]}, "port": {"required": False, "type": "int"}, "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", "choices": ["enable", "disable"]} @@ -370,15 +412,31 @@ def main(): module = AnsibleModule(argument_spec=fields, supports_check_mode=False) - try: - from fortiosapi import FortiOSAPI - except ImportError: - module.fail_json(msg="fortiosapi module is required") - global fos - 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_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: module.exit_json(changed=has_changed, meta=result) diff --git a/lib/ansible/modules/network/fortios/fortios_log_syslogd_setting.py b/lib/ansible/modules/network/fortios/fortios_log_syslogd_setting.py index 394d3f56b05..067e29f6467 100644 --- a/lib/ansible/modules/network/fortios/fortios_log_syslogd_setting.py +++ b/lib/ansible/modules/network/fortios/fortios_log_syslogd_setting.py @@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function) # # You should have received a copy of the GNU General Public License # along with this program. If not, see . -# -# the lib use python logging can get it if the following is set in your -# Ansible config. __metaclass__ = type @@ -29,10 +26,10 @@ DOCUMENTATION = ''' module: fortios_log_syslogd_setting short_description: Global settings for remote syslog server in Fortinet's FortiOS and FortiGate. 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. 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" author: - Miguel Angel Munoz (@mamunozgonzalez) @@ -44,54 +41,70 @@ requirements: - fortiosapi>=0.9.8 options: host: - description: - - FortiOS or FortiGate ip address. - required: true + description: + - FortiOS or FortiGate IP address. + type: str + required: false username: description: - FortiOS or FortiGate username. - required: true + type: str + required: false password: description: - FortiOS or FortiGate password. + type: str default: "" vdom: description: - Virtual domain, among those defined previously. A vdom is a virtual instance of the FortiGate that can be configured and used as a different unit. + type: str default: root https: description: - - Indicates if the requests towards FortiGate must use HTTPS - protocol + - Indicates if the requests towards FortiGate must use HTTPS protocol. + type: bool + default: true + ssl_verify: + description: + - Ensures FortiGate certificate must be verified by a proper CA. type: bool default: true + version_added: 2.9 log_syslogd_setting: description: - Global settings for remote syslog server. default: null + type: dict suboptions: certificate: description: - Certificate used to communicate with Syslog server. Source certificate.local.name. - custom-field-name: + type: str + custom_field_name: description: - Custom field name for CEF format logging. + type: list suboptions: custom: description: - Field custom name. + type: str id: description: - Entry ID. required: true + type: int name: description: - Field name. - enc-algorithm: + type: str + enc_algorithm: description: - Enable/disable reliable syslogging with TLS encryption. + type: str choices: - high-medium - high @@ -100,6 +113,7 @@ options: facility: description: - Remote syslog facility. + type: str choices: - kernel - user @@ -128,6 +142,7 @@ options: format: description: - Log format. + type: str choices: - default - csv @@ -135,6 +150,7 @@ options: mode: description: - Remote syslog logging over UDP/Reliable TCP. + type: str choices: - udp - legacy-reliable @@ -142,15 +158,29 @@ options: port: description: - Server listen port. + type: int server: description: - Address of remote syslog server. - source-ip: + type: str + source_ip: description: - 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: description: - Enable/disable remote syslog logging. + type: str choices: - enable - disable @@ -163,6 +193,7 @@ EXAMPLES = ''' username: "admin" password: "" vdom: "root" + ssl_verify: "False" tasks: - name: Global settings for remote syslog server. fortios_log_syslogd_setting: @@ -173,18 +204,19 @@ EXAMPLES = ''' https: "False" log_syslogd_setting: certificate: " (source certificate.local.name)" - custom-field-name: + custom_field_name: - custom: "" id: "6" name: "default_name_7" - enc-algorithm: "high-medium" + enc_algorithm: "high-medium" facility: "kernel" format: "default" mode: "udp" port: "12" server: "192.168.100.40" - source-ip: "84.230.14.43" + source_ip: "84.230.14.43" + ssl_min_proto_version: "default" status: "enable" ''' @@ -248,14 +280,16 @@ version: ''' from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.connection import Connection +from ansible.module_utils.network.fortios.fortios import FortiOSHandler +from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG -fos = None - -def login(data): +def login(data, fos): host = data['host'] username = data['username'] password = data['password'] + ssl_verify = data['ssl_verify'] fos.debug('on') if 'https' in data and not data['https']: @@ -263,14 +297,14 @@ def login(data): else: fos.https('on') - fos.login(host, username, password) + fos.login(host, username, password, verify=ssl_verify) 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', - 'port', 'server', 'source-ip', - 'status'] + 'port', 'server', 'source_ip', + 'ssl_min_proto_version', 'status'] dictionary = {} for attribute in option_list: @@ -280,17 +314,15 @@ def filter_log_syslogd_setting_data(json): return dictionary -def flatten_multilists_attributes(data): - multilist_attrs = [] - - for attr in multilist_attrs: - try: - path = "data['" + "']['".join(elem for elem in attr) + "']" - current_val = eval(path) - flattened_val = ' '.join(elem for elem in current_val) - exec(path + '= flattened_val') - except BaseException: - pass +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 @@ -298,42 +330,48 @@ def flatten_multilists_attributes(data): def log_syslogd_setting(data, fos): vdom = data['vdom'] log_syslogd_setting_data = data['log_syslogd_setting'] - flattened_data = flatten_multilists_attributes(log_syslogd_setting_data) - filtered_data = filter_log_syslogd_setting_data(flattened_data) + filtered_data = underscore_to_hyphen(filter_log_syslogd_setting_data(log_syslogd_setting_data)) + return fos.set('log.syslogd', 'setting', data=filtered_data, vdom=vdom) +def is_successful_status(status): + return status['status'] == "success" or \ + status['http_method'] == "DELETE" and status['http_status'] == 404 + + def fortios_log_syslogd(data, fos): - login(data) if data['log_syslogd_setting']: resp = log_syslogd_setting(data, fos) - fos.logout() - return not resp['status'] == "success", resp['status'] == "success", resp + return not is_successful_status(resp), \ + resp['status'] == "success", \ + resp def main(): fields = { - "host": {"required": True, "type": "str"}, - "username": {"required": True, "type": "str"}, - "password": {"required": False, "type": "str", "no_log": True}, + "host": {"required": False, "type": "str"}, + "username": {"required": False, "type": "str"}, + "password": {"required": False, "type": "str", "default": "", "no_log": True}, "vdom": {"required": False, "type": "str", "default": "root"}, "https": {"required": False, "type": "bool", "default": True}, + "ssl_verify": {"required": False, "type": "bool", "default": True}, "log_syslogd_setting": { - "required": False, "type": "dict", + "required": False, "type": "dict", "default": None, "options": { "certificate": {"required": False, "type": "str"}, - "custom-field-name": {"required": False, "type": "list", + "custom_field_name": {"required": False, "type": "list", "options": { "custom": {"required": False, "type": "str"}, "id": {"required": True, "type": "int"}, "name": {"required": False, "type": "str"} }}, - "enc-algorithm": {"required": False, "type": "str", + "enc_algorithm": {"required": False, "type": "str", "choices": ["high-medium", "high", "low", "disable"]}, "facility": {"required": False, "type": "str", @@ -351,7 +389,10 @@ def main(): "choices": ["udp", "legacy-reliable", "reliable"]}, "port": {"required": False, "type": "int"}, "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", "choices": ["enable", "disable"]} @@ -361,15 +402,31 @@ def main(): module = AnsibleModule(argument_spec=fields, supports_check_mode=False) - try: - from fortiosapi import FortiOSAPI - except ImportError: - module.fail_json(msg="fortiosapi module is required") - global fos - 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_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: module.exit_json(changed=has_changed, meta=result) diff --git a/lib/ansible/modules/network/fortios/fortios_log_threat_weight.py b/lib/ansible/modules/network/fortios/fortios_log_threat_weight.py index e138b17d0b7..6b2e30a593d 100644 --- a/lib/ansible/modules/network/fortios/fortios_log_threat_weight.py +++ b/lib/ansible/modules/network/fortios/fortios_log_threat_weight.py @@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function) # # You should have received a copy of the GNU General Public License # along with this program. If not, see . -# -# the lib use python logging can get it if the following is set in your -# Ansible config. __metaclass__ = type @@ -29,10 +26,10 @@ DOCUMENTATION = ''' module: fortios_log_threat_weight short_description: Configure threat weight settings in Fortinet's FortiOS and FortiGate. 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. 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" author: - Miguel Angel Munoz (@mamunozgonzalez) @@ -44,66 +41,82 @@ requirements: - fortiosapi>=0.9.8 options: host: - description: - - FortiOS or FortiGate ip address. - required: true + description: + - FortiOS or FortiGate IP address. + type: str + required: false username: description: - FortiOS or FortiGate username. - required: true + type: str + required: false password: description: - FortiOS or FortiGate password. + type: str default: "" vdom: description: - Virtual domain, among those defined previously. A vdom is a virtual instance of the FortiGate that can be configured and used as a different unit. + type: str default: root https: description: - - Indicates if the requests towards FortiGate must use HTTPS - protocol + - Indicates if the requests towards FortiGate must use HTTPS protocol. type: bool default: true + ssl_verify: + description: + - Ensures FortiGate certificate must be verified by a proper CA. + type: bool + default: true + version_added: 2.9 log_threat_weight: description: - Configure threat weight settings. default: null + type: dict suboptions: application: description: - Application-control threat weight settings. + type: list suboptions: category: description: - Application category. + type: int id: description: - Entry ID. required: true + type: int level: description: - Threat weight score for Application events. + type: str choices: - disable - low - medium - high - critical - blocked-connection: + blocked_connection: description: - Threat weight score for blocked connections. + type: str choices: - disable - low - medium - high - critical - failed-connection: + failed_connection: description: - Threat weight score for failed connections. + type: str choices: - disable - low @@ -113,17 +126,21 @@ options: geolocation: description: - Geolocation-based threat weight settings. + type: list suboptions: country: description: - Country code. + type: str id: description: - Entry ID. required: true + type: int level: description: - Threat weight score for Geolocation-based events. + type: str choices: - disable - low @@ -133,46 +150,52 @@ options: ips: description: - IPS threat weight settings. + type: dict suboptions: - critical-severity: + critical_severity: description: - Threat weight score for IPS critical severity events. + type: str choices: - disable - low - medium - high - critical - high-severity: + high_severity: description: - Threat weight score for IPS high severity events. + type: str choices: - disable - low - medium - high - critical - info-severity: + info_severity: description: - Threat weight score for IPS info severity events. + type: str choices: - disable - low - medium - high - critical - low-severity: + low_severity: description: - Threat weight score for IPS low severity events. + type: str choices: - disable - low - medium - high - critical - medium-severity: + medium_severity: description: - Threat weight score for IPS medium severity events. + type: str choices: - disable - low @@ -182,35 +205,53 @@ options: level: description: - Score mapping for threat weight levels. + type: dict suboptions: critical: description: - Critical level score value (1 - 100). + type: int high: description: - High level score value (1 - 100). + type: int low: description: - Low level score value (1 - 100). + type: int medium: description: - Medium level score value (1 - 100). + type: int malware: description: - Anti-virus malware threat weight settings. + type: dict suboptions: - botnet-connection: + botnet_connection: description: - Threat weight score for detected botnet connections. + type: str choices: - disable - low - medium - high - critical - command-blocked: + command_blocked: description: - 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: - disable - low @@ -220,6 +261,7 @@ options: mimefragmented: description: - Threat weight score for mimefragmented detected. + type: str choices: - disable - low @@ -229,60 +271,67 @@ options: oversized: description: - Threat weight score for oversized file detected. + type: str choices: - disable - low - medium - high - critical - switch-proto: + switch_proto: description: - Threat weight score for switch proto detected. + type: str choices: - disable - low - medium - high - critical - virus-blocked: + virus_blocked: description: - Threat weight score for virus (blocked) detected. + type: str choices: - disable - low - medium - high - critical - virus-file-type-executable: + virus_file_type_executable: description: - Threat weight score for virus (filetype executable) detected. + type: str choices: - disable - low - medium - high - critical - virus-infected: + virus_infected: description: - Threat weight score for virus (infected) detected. + type: str choices: - disable - low - medium - high - critical - virus-outbreak-prevention: + virus_outbreak_prevention: description: - Threat weight score for virus (outbreak prevention) event. + type: str choices: - disable - low - medium - high - critical - virus-scan-error: + virus_scan_error: description: - Threat weight score for virus (scan error) detected. + type: str choices: - disable - low @@ -292,12 +341,14 @@ options: status: description: - Enable/disable the threat weight feature. + type: str choices: - enable - disable - url-block-detected: + url_block_detected: description: - Threat weight score for URL blocking. + type: str choices: - disable - low @@ -307,17 +358,21 @@ options: web: description: - Web filtering threat weight settings. + type: list suboptions: category: description: - Threat weight score for web category filtering matches. + type: int id: description: - Entry ID. required: true + type: int level: description: - Threat weight score for web category filtering matches. + type: str choices: - disable - low @@ -333,6 +388,7 @@ EXAMPLES = ''' username: "admin" password: "" vdom: "root" + ssl_verify: "False" tasks: - name: Configure threat weight settings. fortios_log_threat_weight: @@ -347,41 +403,42 @@ EXAMPLES = ''' category: "4" id: "5" level: "disable" - blocked-connection: "disable" - failed-connection: "disable" + blocked_connection: "disable" + failed_connection: "disable" geolocation: - country: "" id: "11" level: "disable" ips: - critical-severity: "disable" - high-severity: "disable" - info-severity: "disable" - low-severity: "disable" - medium-severity: "disable" + critical_severity: "disable" + high_severity: "disable" + info_severity: "disable" + low_severity: "disable" + medium_severity: "disable" level: critical: "20" high: "21" low: "22" medium: "23" malware: - botnet-connection: "disable" - command-blocked: "disable" + botnet_connection: "disable" + command_blocked: "disable" + content_disarm: "disable" mimefragmented: "disable" oversized: "disable" - switch-proto: "disable" - virus-blocked: "disable" - virus-file-type-executable: "disable" - virus-infected: "disable" - virus-outbreak-prevention: "disable" - virus-scan-error: "disable" + switch_proto: "disable" + virus_blocked: "disable" + virus_file_type_executable: "disable" + virus_infected: "disable" + virus_outbreak_prevention: "disable" + virus_scan_error: "disable" status: "enable" - url-block-detected: "disable" + url_block_detected: "disable" web: - - category: "38" - id: "39" + category: "39" + id: "40" level: "disable" ''' @@ -445,14 +502,16 @@ version: ''' from ansible.module_utils.basic import AnsibleModule - -fos = None +from ansible.module_utils.connection import Connection +from ansible.module_utils.network.fortios.fortios import FortiOSHandler +from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG -def login(data): +def login(data, fos): host = data['host'] username = data['username'] password = data['password'] + ssl_verify = data['ssl_verify'] fos.debug('on') if 'https' in data and not data['https']: @@ -460,13 +519,13 @@ def login(data): else: fos.https('on') - fos.login(host, username, password) + fos.login(host, username, password, verify=ssl_verify) def filter_log_threat_weight_data(json): - option_list = ['application', 'blocked-connection', 'failed-connection', + option_list = ['application', 'blocked_connection', 'failed_connection', 'geolocation', 'ips', 'level', - 'malware', 'status', 'url-block-detected', + 'malware', 'status', 'url_block_detected', 'web'] dictionary = {} @@ -477,17 +536,15 @@ def filter_log_threat_weight_data(json): return dictionary -def flatten_multilists_attributes(data): - multilist_attrs = [] - - for attr in multilist_attrs: - try: - path = "data['" + "']['".join(elem for elem in attr) + "']" - current_val = eval(path) - flattened_val = ' '.join(elem for elem in current_val) - exec(path + '= flattened_val') - except BaseException: - pass +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 @@ -495,33 +552,39 @@ def flatten_multilists_attributes(data): def log_threat_weight(data, fos): vdom = data['vdom'] log_threat_weight_data = data['log_threat_weight'] - flattened_data = flatten_multilists_attributes(log_threat_weight_data) - filtered_data = filter_log_threat_weight_data(flattened_data) + filtered_data = underscore_to_hyphen(filter_log_threat_weight_data(log_threat_weight_data)) + return fos.set('log', 'threat-weight', data=filtered_data, vdom=vdom) +def is_successful_status(status): + return status['status'] == "success" or \ + status['http_method'] == "DELETE" and status['http_status'] == 404 + + def fortios_log(data, fos): - login(data) if data['log_threat_weight']: resp = log_threat_weight(data, fos) - fos.logout() - return not resp['status'] == "success", resp['status'] == "success", resp + return not is_successful_status(resp), \ + resp['status'] == "success", \ + resp def main(): fields = { - "host": {"required": True, "type": "str"}, - "username": {"required": True, "type": "str"}, - "password": {"required": False, "type": "str", "no_log": True}, + "host": {"required": False, "type": "str"}, + "username": {"required": False, "type": "str"}, + "password": {"required": False, "type": "str", "default": "", "no_log": True}, "vdom": {"required": False, "type": "str", "default": "root"}, "https": {"required": False, "type": "bool", "default": True}, + "ssl_verify": {"required": False, "type": "bool", "default": True}, "log_threat_weight": { - "required": False, "type": "dict", + "required": False, "type": "dict", "default": None, "options": { "application": {"required": False, "type": "list", "options": { @@ -531,10 +594,10 @@ def main(): "choices": ["disable", "low", "medium", "high", "critical"]} }}, - "blocked-connection": {"required": False, "type": "str", + "blocked_connection": {"required": False, "type": "str", "choices": ["disable", "low", "medium", "high", "critical"]}, - "failed-connection": {"required": False, "type": "str", + "failed_connection": {"required": False, "type": "str", "choices": ["disable", "low", "medium", "high", "critical"]}, "geolocation": {"required": False, "type": "list", @@ -547,19 +610,19 @@ def main(): }}, "ips": {"required": False, "type": "dict", "options": { - "critical-severity": {"required": False, "type": "str", + "critical_severity": {"required": False, "type": "str", "choices": ["disable", "low", "medium", "high", "critical"]}, - "high-severity": {"required": False, "type": "str", + "high_severity": {"required": False, "type": "str", "choices": ["disable", "low", "medium", "high", "critical"]}, - "info-severity": {"required": False, "type": "str", + "info_severity": {"required": False, "type": "str", "choices": ["disable", "low", "medium", "high", "critical"]}, - "low-severity": {"required": False, "type": "str", + "low_severity": {"required": False, "type": "str", "choices": ["disable", "low", "medium", "high", "critical"]}, - "medium-severity": {"required": False, "type": "str", + "medium_severity": {"required": False, "type": "str", "choices": ["disable", "low", "medium", "high", "critical"]} }}, @@ -572,40 +635,43 @@ def main(): }}, "malware": {"required": False, "type": "dict", "options": { - "botnet-connection": {"required": False, "type": "str", + "botnet_connection": {"required": False, "type": "str", "choices": ["disable", "low", "medium", "high", "critical"]}, - "command-blocked": {"required": False, "type": "str", + "command_blocked": {"required": False, "type": "str", "choices": ["disable", "low", "medium", "high", "critical"]}, + "content_disarm": {"required": False, "type": "str", + "choices": ["disable", "low", "medium", + "high", "critical"]}, "mimefragmented": {"required": False, "type": "str", "choices": ["disable", "low", "medium", "high", "critical"]}, "oversized": {"required": False, "type": "str", "choices": ["disable", "low", "medium", "high", "critical"]}, - "switch-proto": {"required": False, "type": "str", + "switch_proto": {"required": False, "type": "str", "choices": ["disable", "low", "medium", "high", "critical"]}, - "virus-blocked": {"required": False, "type": "str", + "virus_blocked": {"required": False, "type": "str", "choices": ["disable", "low", "medium", "high", "critical"]}, - "virus-file-type-executable": {"required": False, "type": "str", + "virus_file_type_executable": {"required": False, "type": "str", "choices": ["disable", "low", "medium", "high", "critical"]}, - "virus-infected": {"required": False, "type": "str", + "virus_infected": {"required": False, "type": "str", "choices": ["disable", "low", "medium", "high", "critical"]}, - "virus-outbreak-prevention": {"required": False, "type": "str", + "virus_outbreak_prevention": {"required": False, "type": "str", "choices": ["disable", "low", "medium", "high", "critical"]}, - "virus-scan-error": {"required": False, "type": "str", + "virus_scan_error": {"required": False, "type": "str", "choices": ["disable", "low", "medium", "high", "critical"]} }}, "status": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "url-block-detected": {"required": False, "type": "str", + "url_block_detected": {"required": False, "type": "str", "choices": ["disable", "low", "medium", "high", "critical"]}, "web": {"required": False, "type": "list", @@ -623,15 +689,31 @@ def main(): module = AnsibleModule(argument_spec=fields, supports_check_mode=False) - try: - from fortiosapi import FortiOSAPI - except ImportError: - module.fail_json(msg="fortiosapi module is required") - global fos - 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(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: module.exit_json(changed=has_changed, meta=result) diff --git a/lib/ansible/modules/network/fortios/fortios_log_webtrends_filter.py b/lib/ansible/modules/network/fortios/fortios_log_webtrends_filter.py index 746bb217f0b..b7a0f9d8b37 100644 --- a/lib/ansible/modules/network/fortios/fortios_log_webtrends_filter.py +++ b/lib/ansible/modules/network/fortios/fortios_log_webtrends_filter.py @@ -26,10 +26,10 @@ DOCUMENTATION = ''' module: fortios_log_webtrends_filter short_description: Filters for WebTrends in Fortinet's FortiOS and FortiGate. 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. 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" author: - Miguel Angel Munoz (@mamunozgonzalez) @@ -41,88 +41,109 @@ requirements: - fortiosapi>=0.9.8 options: host: - description: - - FortiOS or FortiGate ip address. - required: true + description: + - FortiOS or FortiGate IP address. + type: str + required: false username: description: - FortiOS or FortiGate username. - required: true + type: str + required: false password: description: - FortiOS or FortiGate password. + type: str default: "" vdom: description: - Virtual domain, among those defined previously. A vdom is a virtual instance of the FortiGate that can be configured and used as a different unit. + type: str default: root https: description: - - Indicates if the requests towards FortiGate must use HTTPS - protocol + - Indicates if the requests towards FortiGate must use HTTPS protocol. + type: bool + default: true + ssl_verify: + description: + - Ensures FortiGate certificate must be verified by a proper CA. type: bool default: true + version_added: 2.9 log_webtrends_filter: description: - Filters for WebTrends. default: null + type: dict suboptions: anomaly: description: - Enable/disable anomaly logging. + type: str choices: - enable - disable dns: description: - Enable/disable detailed DNS event logging. + type: str choices: - enable - disable filter: description: - Webtrends log filter. - filter-type: + type: str + filter_type: description: - Include/exclude logs that match the filter. + type: str choices: - include - exclude - forward-traffic: + forward_traffic: description: - Enable/disable forward traffic logging. + type: str choices: - enable - disable gtp: description: - Enable/disable GTP messages logging. + type: str choices: - enable - disable - local-traffic: + local_traffic: description: - Enable/disable local in or out traffic logging. + type: str choices: - enable - disable - multicast-traffic: + multicast_traffic: description: - Enable/disable multicast traffic logging. + type: str choices: - enable - disable - netscan-discovery: + netscan_discovery: description: - Enable/disable netscan discovery event logging. - netscan-vulnerability: + type: str + netscan_vulnerability: description: - Enable/disable netscan vulnerability event logging. + type: str severity: description: - Lowest severity level to log to WebTrends. + type: str choices: - emergency - alert @@ -132,21 +153,24 @@ options: - notification - information - debug - sniffer-traffic: + sniffer_traffic: description: - Enable/disable sniffer traffic logging. + type: str choices: - enable - disable ssh: description: - Enable/disable SSH logging. + type: str choices: - enable - disable voip: description: - Enable/disable VoIP logging. + type: str choices: - enable - disable @@ -159,6 +183,7 @@ EXAMPLES = ''' username: "admin" password: "" vdom: "root" + ssl_verify: "False" tasks: - name: Filters for WebTrends. fortios_log_webtrends_filter: @@ -171,15 +196,15 @@ EXAMPLES = ''' anomaly: "enable" dns: "enable" filter: "" - filter-type: "include" - forward-traffic: "enable" + filter_type: "include" + forward_traffic: "enable" gtp: "enable" - local-traffic: "enable" - multicast-traffic: "enable" - netscan-discovery: "" - netscan-vulnerability: "" + local_traffic: "enable" + multicast_traffic: "enable" + netscan_discovery: "" + netscan_vulnerability: "" severity: "emergency" - sniffer-traffic: "enable" + sniffer_traffic: "enable" ssh: "enable" voip: "enable" ''' @@ -244,12 +269,16 @@ version: ''' from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.connection import Connection +from ansible.module_utils.network.fortios.fortios import FortiOSHandler +from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG def login(data, fos): host = data['host'] username = data['username'] password = data['password'] + ssl_verify = data['ssl_verify'] fos.debug('on') if 'https' in data and not data['https']: @@ -257,14 +286,14 @@ def login(data, fos): else: fos.https('on') - fos.login(host, username, password) + fos.login(host, username, password, verify=ssl_verify) def filter_log_webtrends_filter_data(json): option_list = ['anomaly', 'dns', 'filter', - 'filter-type', 'forward-traffic', 'gtp', - 'local-traffic', 'multicast-traffic', 'netscan-discovery', - 'netscan-vulnerability', 'severity', 'sniffer-traffic', + 'filter_type', 'forward_traffic', 'gtp', + 'local_traffic', 'multicast_traffic', 'netscan_discovery', + 'netscan_vulnerability', 'severity', 'sniffer_traffic', 'ssh', 'voip'] dictionary = {} @@ -275,10 +304,23 @@ def filter_log_webtrends_filter_data(json): return dictionary +def underscore_to_hyphen(data): + if isinstance(data, list): + for elem in data: + elem = underscore_to_hyphen(elem) + elif isinstance(data, dict): + new_data = {} + for k, v in data.items(): + new_data[k.replace('_', '-')] = underscore_to_hyphen(v) + data = new_data + + return data + + def log_webtrends_filter(data, fos): vdom = data['vdom'] 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', 'filter', @@ -286,48 +328,54 @@ def log_webtrends_filter(data, fos): 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): - login(data, fos) if data['log_webtrends_filter']: resp = log_webtrends_filter(data, fos) - fos.logout() - return not resp['status'] == "success", resp['status'] == "success", resp + return not is_successful_status(resp), \ + resp['status'] == "success", \ + resp def main(): fields = { - "host": {"required": True, "type": "str"}, - "username": {"required": True, "type": "str"}, - "password": {"required": False, "type": "str", "no_log": True}, + "host": {"required": False, "type": "str"}, + "username": {"required": False, "type": "str"}, + "password": {"required": False, "type": "str", "default": "", "no_log": True}, "vdom": {"required": False, "type": "str", "default": "root"}, "https": {"required": False, "type": "bool", "default": True}, + "ssl_verify": {"required": False, "type": "bool", "default": True}, "log_webtrends_filter": { - "required": False, "type": "dict", + "required": False, "type": "dict", "default": None, "options": { "anomaly": {"required": False, "type": "str", "choices": ["enable", "disable"]}, "dns": {"required": False, "type": "str", "choices": ["enable", "disable"]}, "filter": {"required": False, "type": "str"}, - "filter-type": {"required": False, "type": "str", + "filter_type": {"required": False, "type": "str", "choices": ["include", "exclude"]}, - "forward-traffic": {"required": False, "type": "str", + "forward_traffic": {"required": False, "type": "str", "choices": ["enable", "disable"]}, "gtp": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "local-traffic": {"required": False, "type": "str", + "local_traffic": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "multicast-traffic": {"required": False, "type": "str", + "multicast_traffic": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "netscan-discovery": {"required": False, "type": "str"}, - "netscan-vulnerability": {"required": False, "type": "str"}, + "netscan_discovery": {"required": False, "type": "str"}, + "netscan_vulnerability": {"required": False, "type": "str"}, "severity": {"required": False, "type": "str", "choices": ["emergency", "alert", "critical", "error", "warning", "notification", "information", "debug"]}, - "sniffer-traffic": {"required": False, "type": "str", + "sniffer_traffic": {"required": False, "type": "str", "choices": ["enable", "disable"]}, "ssh": {"required": False, "type": "str", "choices": ["enable", "disable"]}, @@ -340,14 +388,31 @@ def main(): module = AnsibleModule(argument_spec=fields, 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: module.exit_json(changed=has_changed, meta=result) diff --git a/lib/ansible/modules/network/fortios/fortios_log_webtrends_setting.py b/lib/ansible/modules/network/fortios/fortios_log_webtrends_setting.py index b021d3f6872..3097d9730f5 100644 --- a/lib/ansible/modules/network/fortios/fortios_log_webtrends_setting.py +++ b/lib/ansible/modules/network/fortios/fortios_log_webtrends_setting.py @@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function) # # You should have received a copy of the GNU General Public License # along with this program. If not, see . -# -# the lib use python logging can get it if the following is set in your -# Ansible config. __metaclass__ = type @@ -29,10 +26,10 @@ DOCUMENTATION = ''' module: fortios_log_webtrends_setting short_description: Settings for WebTrends in Fortinet's FortiOS and FortiGate. 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. 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" author: - Miguel Angel Munoz (@mamunozgonzalez) @@ -44,40 +41,52 @@ requirements: - fortiosapi>=0.9.8 options: host: - description: - - FortiOS or FortiGate ip address. - required: true + description: + - FortiOS or FortiGate IP address. + type: str + required: false username: description: - FortiOS or FortiGate username. - required: true + type: str + required: false password: description: - FortiOS or FortiGate password. + type: str default: "" vdom: description: - Virtual domain, among those defined previously. A vdom is a virtual instance of the FortiGate that can be configured and used as a different unit. + type: str default: root https: description: - - Indicates if the requests towards FortiGate must use HTTPS - protocol + - Indicates if the requests towards FortiGate must use HTTPS protocol. + type: bool + default: true + ssl_verify: + description: + - Ensures FortiGate certificate must be verified by a proper CA. type: bool default: true + version_added: 2.9 log_webtrends_setting: description: - Settings for WebTrends. default: null + type: dict suboptions: server: description: - Address of the remote WebTrends server. + type: str status: description: - Enable/disable logging to WebTrends. + type: str choices: - enable - disable @@ -90,6 +99,7 @@ EXAMPLES = ''' username: "admin" password: "" vdom: "root" + ssl_verify: "False" tasks: - name: Settings for WebTrends. fortios_log_webtrends_setting: @@ -163,14 +173,16 @@ version: ''' from ansible.module_utils.basic import AnsibleModule - -fos = None +from ansible.module_utils.connection import Connection +from ansible.module_utils.network.fortios.fortios import FortiOSHandler +from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG -def login(data): +def login(data, fos): host = data['host'] username = data['username'] password = data['password'] + ssl_verify = data['ssl_verify'] fos.debug('on') if 'https' in data and not data['https']: @@ -178,7 +190,7 @@ def login(data): else: fos.https('on') - fos.login(host, username, password) + fos.login(host, username, password, verify=ssl_verify) def filter_log_webtrends_setting_data(json): @@ -192,17 +204,15 @@ def filter_log_webtrends_setting_data(json): return dictionary -def flatten_multilists_attributes(data): - multilist_attrs = [] - - for attr in multilist_attrs: - try: - path = "data['" + "']['".join(elem for elem in attr) + "']" - current_val = eval(path) - flattened_val = ' '.join(elem for elem in current_val) - exec(path + '= flattened_val') - except BaseException: - pass +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 @@ -210,33 +220,39 @@ def flatten_multilists_attributes(data): def log_webtrends_setting(data, fos): vdom = data['vdom'] log_webtrends_setting_data = data['log_webtrends_setting'] - flattened_data = flatten_multilists_attributes(log_webtrends_setting_data) - filtered_data = filter_log_webtrends_setting_data(flattened_data) + filtered_data = underscore_to_hyphen(filter_log_webtrends_setting_data(log_webtrends_setting_data)) + return fos.set('log.webtrends', 'setting', data=filtered_data, vdom=vdom) +def is_successful_status(status): + return status['status'] == "success" or \ + status['http_method'] == "DELETE" and status['http_status'] == 404 + + def fortios_log_webtrends(data, fos): - login(data) if data['log_webtrends_setting']: resp = log_webtrends_setting(data, fos) - fos.logout() - return not resp['status'] == "success", resp['status'] == "success", resp + return not is_successful_status(resp), \ + resp['status'] == "success", \ + resp def main(): fields = { - "host": {"required": True, "type": "str"}, - "username": {"required": True, "type": "str"}, - "password": {"required": False, "type": "str", "no_log": True}, + "host": {"required": False, "type": "str"}, + "username": {"required": False, "type": "str"}, + "password": {"required": False, "type": "str", "default": "", "no_log": True}, "vdom": {"required": False, "type": "str", "default": "root"}, "https": {"required": False, "type": "bool", "default": True}, + "ssl_verify": {"required": False, "type": "bool", "default": True}, "log_webtrends_setting": { - "required": False, "type": "dict", + "required": False, "type": "dict", "default": None, "options": { "server": {"required": False, "type": "str"}, "status": {"required": False, "type": "str", @@ -248,15 +264,31 @@ def main(): module = AnsibleModule(argument_spec=fields, supports_check_mode=False) - try: - from fortiosapi import FortiOSAPI - except ImportError: - module.fail_json(msg="fortiosapi module is required") - global fos - 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: module.exit_json(changed=has_changed, meta=result) diff --git a/lib/ansible/modules/network/fortios/fortios_report_chart.py b/lib/ansible/modules/network/fortios/fortios_report_chart.py index bdb4a97f963..bf88d790c5f 100644 --- a/lib/ansible/modules/network/fortios/fortios_report_chart.py +++ b/lib/ansible/modules/network/fortios/fortios_report_chart.py @@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function) # # You should have received a copy of the GNU General Public License # along with this program. If not, see . -# -# the lib use python logging can get it if the following is set in your -# Ansible config. __metaclass__ = type @@ -29,10 +26,10 @@ DOCUMENTATION = ''' module: fortios_report_chart short_description: Report chart widget configuration in Fortinet's FortiOS and FortiGate. 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. 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" author: - Miguel Angel Munoz (@mamunozgonzalez) @@ -44,46 +41,61 @@ requirements: - fortiosapi>=0.9.8 options: host: - description: - - FortiOS or FortiGate ip address. - required: true + description: + - FortiOS or FortiGate IP address. + type: str + required: false username: description: - FortiOS or FortiGate username. - required: true + type: str + required: false password: description: - FortiOS or FortiGate password. + type: str default: "" vdom: description: - Virtual domain, among those defined previously. A vdom is a virtual instance of the FortiGate that can be configured and used as a different unit. + type: str default: root https: description: - - Indicates if the requests towards FortiGate must use HTTPS - protocol + - Indicates if the requests towards FortiGate must use HTTPS protocol. + type: bool + default: true + ssl_verify: + description: + - Ensures FortiGate certificate must be verified by a proper CA. type: bool default: 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: description: - Report chart widget configuration. default: null + type: dict suboptions: - state: - description: - - Indicates whether to create or remove the object - choices: - - present - - absent background: description: - Chart background. + type: str category: description: - Category. + type: str choices: - misc - traffic @@ -95,56 +107,71 @@ options: - dlp - app-ctrl - vulnerability - category-series: + category_series: description: - Category series of pie chart. + type: dict suboptions: databind: description: - Category series value expression. - font-size: + type: str + font_size: description: - Font size of category-series title. - color-palette: + type: int + color_palette: description: - Color palette (system will pick color automatically by default). + type: str column: description: - Table column definition. + type: list suboptions: - detail-unit: + detail_unit: description: - Detail unit of column. - detail-value: + type: str + detail_value: description: - Detail value of column. - footer-unit: + type: str + footer_unit: description: - Footer unit of column. - footer-value: + type: str + footer_value: description: - Footer value of column. - header-value: + type: str + header_value: description: - Display name of table header. + type: str id: description: - ID. required: true + type: int mapping: description: - Show detail in certain display value for certain condition. + type: list suboptions: displayname: description: - Display name. + type: str id: description: - id required: true + type: int op: description: - Comparision operater. + type: str choices: - none - greater @@ -153,56 +180,68 @@ options: - less-equal - equal - between - value-type: + value_type: description: - Value type. + type: str choices: - integer - string value1: description: - Value 1. + type: str value2: description: - Value 2. + type: str comments: description: - Comment. + type: str dataset: description: - Bind dataset to chart. + type: str dimension: description: - Dimension. + type: str choices: - 2D - 3D - drill-down-charts: + drill_down_charts: description: - Drill down charts. + type: list suboptions: - chart-name: + chart_name: description: - Drill down chart name. + type: str id: description: - Drill down chart ID. required: true + type: int status: description: - Enable/disable this drill down chart. + type: str choices: - enable - disable favorite: description: - Favorite. + type: str choices: - no - yes - graph-type: + graph_type: description: - Graph type. + type: str choices: - none - bar @@ -212,88 +251,108 @@ options: legend: description: - Enable/Disable Legend area. + type: str choices: - enable - disable - legend-font-size: + legend_font_size: description: - Font size of legend area. + type: int name: description: - Chart Widget Name required: true + type: str period: description: - Time period. + type: str choices: - last24h - last7d policy: description: - Used by monitor policy. + type: int style: description: - Style. + type: str choices: - auto - manual title: description: - Chart title. - title-font-size: + type: str + title_font_size: description: - Font size of chart title. + type: int type: description: - Chart type. + type: str choices: - graph - table - value-series: + value_series: description: - Value series of pie chart. + type: dict suboptions: databind: description: - Value series value expression. - x-series: + type: str + x_series: description: - X-series of chart. + type: dict suboptions: caption: description: - X-series caption. - caption-font-size: + type: str + caption_font_size: description: - X-series caption font size. + type: int databind: description: - X-series value expression. - font-size: + type: str + font_size: description: - X-series label font size. - is-category: + type: int + is_category: description: - X-series represent category or not. + type: str choices: - yes - no - label-angle: + label_angle: description: - X-series label angle. + type: str choices: - 45-degree - vertical - horizontal - scale-direction: + scale_direction: description: - Scale increase or decrease. + type: str choices: - decrease - increase - scale-format: + scale_format: description: - Date/time format. + type: str choices: - YYYY-MM-DD-HH-MM - YYYY-MM-DD HH @@ -302,12 +361,14 @@ options: - YYYY - HH-MM - MM-DD - scale-step: + scale_step: description: - Scale step. - scale-unit: + type: int + scale_unit: description: - Scale unit. + type: str choices: - minute - hour @@ -317,40 +378,51 @@ options: unit: description: - X-series unit. - y-series: + type: str + y_series: description: - Y-series of chart. + type: dict suboptions: caption: description: - Y-series caption. - caption-font-size: + type: str + caption_font_size: description: - Y-series caption font size. + type: int databind: description: - Y-series value expression. - extra-databind: + type: str + extra_databind: description: - Extra Y-series value. - extra-y: + type: str + extra_y: description: - Allow another Y-series value + type: str choices: - enable - disable - extra-y-legend: + extra_y_legend: description: - Extra Y-series legend type/name. - font-size: + type: str + font_size: description: - Y-series label font size. + type: int group: description: - Y-series group option. - label-angle: + type: str + label_angle: description: - Y-series label angle. + type: str choices: - 45-degree - vertical @@ -358,9 +430,11 @@ options: unit: description: - Y-series unit. - y-legend: + type: str + y_legend: description: - First Y-series legend type/name. + type: str ''' EXAMPLES = ''' @@ -370,6 +444,7 @@ EXAMPLES = ''' username: "admin" password: "" vdom: "root" + ssl_verify: "False" tasks: - name: Report chart widget configuration. fortios_report_chart: @@ -378,75 +453,75 @@ EXAMPLES = ''' password: "{{ password }}" vdom: "{{ vdom }}" https: "False" + state: "present" report_chart: - state: "present" background: "" category: "misc" - category-series: + category_series: databind: "" - font-size: "7" - color-palette: "" + font_size: "7" + color_palette: "" column: - - detail-unit: "" - detail-value: "" - footer-unit: "" - footer-value: "" - header-value: "" + detail_unit: "" + detail_value: "" + footer_unit: "" + footer_value: "" + header_value: "" id: "15" mapping: - displayname: "" id: "18" op: "none" - value-type: "integer" + value_type: "integer" value1: "" value2: "" comments: "" dataset: "" dimension: "2D" - drill-down-charts: + drill_down_charts: - - chart-name: "" + chart_name: "" id: "28" status: "enable" favorite: "no" - graph-type: "none" + graph_type: "none" legend: "enable" - legend-font-size: "33" + legend_font_size: "33" name: "default_name_34" period: "last24h" policy: "36" style: "auto" title: "" - title-font-size: "39" + title_font_size: "39" type: "graph" - value-series: + value_series: databind: "" - x-series: + x_series: caption: "" - caption-font-size: "45" + caption_font_size: "45" databind: "" - font-size: "47" - is-category: "yes" - label-angle: "45-degree" - scale-direction: "decrease" - scale-format: "YYYY-MM-DD-HH-MM" - scale-step: "52" - scale-unit: "minute" + font_size: "47" + is_category: "yes" + label_angle: "45-degree" + scale_direction: "decrease" + scale_format: "YYYY-MM-DD-HH-MM" + scale_step: "52" + scale_unit: "minute" unit: "" - y-series: + y_series: caption: "" - caption-font-size: "57" + caption_font_size: "57" databind: "" - extra-databind: "" - extra-y: "enable" - extra-y-legend: "" - font-size: "62" + extra_databind: "" + extra_y: "enable" + extra_y_legend: "" + font_size: "62" group: "" - label-angle: "45-degree" + label_angle: "45-degree" unit: "" - y-legend: "" + y_legend: "" ''' RETURN = ''' @@ -509,14 +584,16 @@ version: ''' from ansible.module_utils.basic import AnsibleModule - -fos = None +from ansible.module_utils.connection import Connection +from ansible.module_utils.network.fortios.fortios import FortiOSHandler +from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG -def login(data): +def login(data, fos): host = data['host'] username = data['username'] password = data['password'] + ssl_verify = data['ssl_verify'] fos.debug('on') if 'https' in data and not data['https']: @@ -524,18 +601,18 @@ def login(data): else: fos.https('on') - fos.login(host, username, password) + fos.login(host, username, password, verify=ssl_verify) def filter_report_chart_data(json): - option_list = ['background', 'category', 'category-series', - 'color-palette', 'column', 'comments', - 'dataset', 'dimension', 'drill-down-charts', - 'favorite', 'graph-type', 'legend', - 'legend-font-size', 'name', 'period', + option_list = ['background', 'category', 'category_series', + 'color_palette', 'column', 'comments', + 'dataset', 'dimension', 'drill_down_charts', + 'favorite', 'graph_type', 'legend', + 'legend_font_size', 'name', 'period', 'policy', 'style', 'title', - 'title-font-size', 'type', 'value-series', - 'x-series', 'y-series'] + 'title_font_size', 'type', 'value_series', + 'x_series', 'y_series'] dictionary = {} for attribute in option_list: @@ -545,80 +622,85 @@ def filter_report_chart_data(json): return dictionary -def flatten_multilists_attributes(data): - multilist_attrs = [] - - for attr in multilist_attrs: - try: - path = "data['" + "']['".join(elem for elem in attr) + "']" - current_val = eval(path) - flattened_val = ' '.join(elem for elem in current_val) - exec(path + '= flattened_val') - except BaseException: - pass +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 report_chart(data, fos): vdom = data['vdom'] + state = data['state'] report_chart_data = data['report_chart'] - flattened_data = flatten_multilists_attributes(report_chart_data) - filtered_data = filter_report_chart_data(flattened_data) - if report_chart_data['state'] == "present": + filtered_data = underscore_to_hyphen(filter_report_chart_data(report_chart_data)) + + if state == "present": return fos.set('report', 'chart', data=filtered_data, vdom=vdom) - elif report_chart_data['state'] == "absent": + elif state == "absent": return fos.delete('report', 'chart', mkey=filtered_data['name'], vdom=vdom) +def is_successful_status(status): + return status['status'] == "success" or \ + status['http_method'] == "DELETE" and status['http_status'] == 404 + + def fortios_report(data, fos): - login(data) if data['report_chart']: resp = report_chart(data, fos) - fos.logout() - return not resp['status'] == "success", resp['status'] == "success", resp + return not is_successful_status(resp), \ + resp['status'] == "success", \ + resp def main(): fields = { - "host": {"required": True, "type": "str"}, - "username": {"required": True, "type": "str"}, - "password": {"required": False, "type": "str", "no_log": True}, + "host": {"required": False, "type": "str"}, + "username": {"required": False, "type": "str"}, + "password": {"required": False, "type": "str", "default": "", "no_log": True}, "vdom": {"required": False, "type": "str", "default": "root"}, "https": {"required": False, "type": "bool", "default": True}, + "ssl_verify": {"required": False, "type": "bool", "default": True}, + "state": {"required": True, "type": "str", + "choices": ["present", "absent"]}, "report_chart": { - "required": False, "type": "dict", + "required": False, "type": "dict", "default": None, "options": { - "state": {"required": True, "type": "str", - "choices": ["present", "absent"]}, "background": {"required": False, "type": "str"}, "category": {"required": False, "type": "str", "choices": ["misc", "traffic", "event", "virus", "webfilter", "attack", "spam", "dlp", "app-ctrl", "vulnerability"]}, - "category-series": {"required": False, "type": "dict", + "category_series": {"required": False, "type": "dict", "options": { "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", "options": { - "detail-unit": {"required": False, "type": "str"}, - "detail-value": {"required": False, "type": "str"}, - "footer-unit": {"required": False, "type": "str"}, - "footer-value": {"required": False, "type": "str"}, - "header-value": {"required": False, "type": "str"}, + "detail_unit": {"required": False, "type": "str"}, + "detail_value": {"required": False, "type": "str"}, + "footer_unit": {"required": False, "type": "str"}, + "footer_value": {"required": False, "type": "str"}, + "header_value": {"required": False, "type": "str"}, "id": {"required": True, "type": "int"}, "mapping": {"required": False, "type": "list", "options": { @@ -628,7 +710,7 @@ def main(): "choices": ["none", "greater", "greater-equal", "less", "less-equal", "equal", "between"]}, - "value-type": {"required": False, "type": "str", + "value_type": {"required": False, "type": "str", "choices": ["integer", "string"]}, "value1": {"required": False, "type": "str"}, "value2": {"required": False, "type": "str"} @@ -638,21 +720,21 @@ def main(): "dataset": {"required": False, "type": "str"}, "dimension": {"required": False, "type": "str", "choices": ["2D", "3D"]}, - "drill-down-charts": {"required": False, "type": "list", + "drill_down_charts": {"required": False, "type": "list", "options": { - "chart-name": {"required": False, "type": "str"}, + "chart_name": {"required": False, "type": "str"}, "id": {"required": True, "type": "int"}, "status": {"required": False, "type": "str", "choices": ["enable", "disable"]} }}, "favorite": {"required": False, "type": "str", "choices": ["no", "yes"]}, - "graph-type": {"required": False, "type": "str", + "graph_type": {"required": False, "type": "str", "choices": ["none", "bar", "pie", "line", "flow"]}, "legend": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "legend-font-size": {"required": False, "type": "int"}, + "legend_font_size": {"required": False, "type": "int"}, "name": {"required": True, "type": "str"}, "period": {"required": False, "type": "str", "choices": ["last24h", "last7d"]}, @@ -660,50 +742,50 @@ def main(): "style": {"required": False, "type": "str", "choices": ["auto", "manual"]}, "title": {"required": False, "type": "str"}, - "title-font-size": {"required": False, "type": "int"}, + "title_font_size": {"required": False, "type": "int"}, "type": {"required": False, "type": "str", "choices": ["graph", "table"]}, - "value-series": {"required": False, "type": "dict", + "value_series": {"required": False, "type": "dict", "options": { "databind": {"required": False, "type": "str"} }}, - "x-series": {"required": False, "type": "dict", + "x_series": {"required": False, "type": "dict", "options": { "caption": {"required": False, "type": "str"}, - "caption-font-size": {"required": False, "type": "int"}, + "caption_font_size": {"required": False, "type": "int"}, "databind": {"required": False, "type": "str"}, - "font-size": {"required": False, "type": "int"}, - "is-category": {"required": False, "type": "str", + "font_size": {"required": False, "type": "int"}, + "is_category": {"required": False, "type": "str", "choices": ["yes", "no"]}, - "label-angle": {"required": False, "type": "str", + "label_angle": {"required": False, "type": "str", "choices": ["45-degree", "vertical", "horizontal"]}, - "scale-direction": {"required": False, "type": "str", + "scale_direction": {"required": False, "type": "str", "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", "YYYY-MM", "YYYY", "HH-MM", "MM-DD"]}, - "scale-step": {"required": False, "type": "int"}, - "scale-unit": {"required": False, "type": "str", + "scale_step": {"required": False, "type": "int"}, + "scale_unit": {"required": False, "type": "str", "choices": ["minute", "hour", "day", "month", "year"]}, "unit": {"required": False, "type": "str"} }}, - "y-series": {"required": False, "type": "dict", + "y_series": {"required": False, "type": "dict", "options": { "caption": {"required": False, "type": "str"}, - "caption-font-size": {"required": False, "type": "int"}, + "caption_font_size": {"required": False, "type": "int"}, "databind": {"required": False, "type": "str"}, - "extra-databind": {"required": False, "type": "str"}, - "extra-y": {"required": False, "type": "str", + "extra_databind": {"required": False, "type": "str"}, + "extra_y": {"required": False, "type": "str", "choices": ["enable", "disable"]}, - "extra-y-legend": {"required": False, "type": "str"}, - "font-size": {"required": False, "type": "int"}, + "extra_y_legend": {"required": False, "type": "str"}, + "font_size": {"required": False, "type": "int"}, "group": {"required": False, "type": "str"}, - "label-angle": {"required": False, "type": "str", + "label_angle": {"required": False, "type": "str", "choices": ["45-degree", "vertical", "horizontal"]}, "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, supports_check_mode=False) - try: - from fortiosapi import FortiOSAPI - except ImportError: - module.fail_json(msg="fortiosapi module is required") - global fos - 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_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: module.exit_json(changed=has_changed, meta=result) diff --git a/lib/ansible/modules/network/fortios/fortios_report_dataset.py b/lib/ansible/modules/network/fortios/fortios_report_dataset.py index 58bc41e4d5f..36304d845f6 100644 --- a/lib/ansible/modules/network/fortios/fortios_report_dataset.py +++ b/lib/ansible/modules/network/fortios/fortios_report_dataset.py @@ -14,9 +14,6 @@ from __future__ import (absolute_import, division, print_function) # # You should have received a copy of the GNU General Public License # along with this program. If not, see . -# -# the lib use python logging can get it if the following is set in your -# Ansible config. __metaclass__ = type @@ -29,10 +26,10 @@ DOCUMENTATION = ''' module: fortios_report_dataset short_description: Report dataset configuration in Fortinet's FortiOS and FortiGate. 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. 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" author: - Miguel Angel Munoz (@mamunozgonzalez) @@ -44,57 +41,75 @@ requirements: - fortiosapi>=0.9.8 options: host: - description: - - FortiOS or FortiGate ip address. - required: true + description: + - FortiOS or FortiGate IP address. + type: str + required: false username: description: - FortiOS or FortiGate username. - required: true + type: str + required: false password: description: - FortiOS or FortiGate password. + type: str default: "" vdom: description: - Virtual domain, among those defined previously. A vdom is a virtual instance of the FortiGate that can be configured and used as a different unit. + type: str default: root https: description: - - Indicates if the requests towards FortiGate must use HTTPS - protocol + - Indicates if the requests towards FortiGate must use HTTPS protocol. + type: bool + default: true + ssl_verify: + description: + - Ensures FortiGate certificate must be verified by a proper CA. type: bool default: 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: description: - Report dataset configuration. default: null + type: dict suboptions: - state: - description: - - Indicates whether to create or remove the object - choices: - - present - - absent field: description: - Fields. + type: list suboptions: displayname: description: - Display name. + type: str id: description: - Field ID (1 to number of columns in SQL result). required: true + type: int name: description: - Name. + type: str type: description: - Field type. + type: str choices: - text - integer @@ -103,35 +118,43 @@ options: description: - Name. required: true + type: str parameters: description: - Parameters. + type: list suboptions: - data-type: + data_type: description: - Data type. + type: str choices: - text - integer - double - long-integer - date-time - display-name: + display_name: description: - Display name. + type: str field: description: - SQL field name. + type: str id: description: - Parameter ID (1 to number of columns in SQL result). required: true + type: int policy: description: - Used by monitor policy. + type: int query: description: - SQL query statement. + type: str ''' EXAMPLES = ''' @@ -141,6 +164,7 @@ EXAMPLES = ''' username: "admin" password: "" vdom: "root" + ssl_verify: "False" tasks: - name: Report dataset configuration. fortios_report_dataset: @@ -149,8 +173,8 @@ EXAMPLES = ''' password: "{{ password }}" vdom: "{{ vdom }}" https: "False" + state: "present" report_dataset: - state: "present" field: - displayname: "" @@ -160,8 +184,8 @@ EXAMPLES = ''' name: "default_name_8" parameters: - - data-type: "text" - display-name: "" + data_type: "text" + display_name: "" field: "" id: "13" policy: "14" @@ -228,14 +252,16 @@ version: ''' from ansible.module_utils.basic import AnsibleModule - -fos = None +from ansible.module_utils.connection import Connection +from ansible.module_utils.network.fortios.fortios import FortiOSHandler +from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG -def login(data): +def login(data, fos): host = data['host'] username = data['username'] password = data['password'] + ssl_verify = data['ssl_verify'] fos.debug('on') if 'https' in data and not data['https']: @@ -243,7 +269,7 @@ def login(data): else: fos.https('on') - fos.login(host, username, password) + fos.login(host, username, password, verify=ssl_verify) def filter_report_dataset_data(json): @@ -258,61 +284,66 @@ def filter_report_dataset_data(json): return dictionary -def flatten_multilists_attributes(data): - multilist_attrs = [] - - for attr in multilist_attrs: - try: - path = "data['" + "']['".join(elem for elem in attr) + "']" - current_val = eval(path) - flattened_val = ' '.join(elem for elem in current_val) - exec(path + '= flattened_val') - except BaseException: - pass +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 report_dataset(data, fos): vdom = data['vdom'] + state = data['state'] report_dataset_data = data['report_dataset'] - flattened_data = flatten_multilists_attributes(report_dataset_data) - filtered_data = filter_report_dataset_data(flattened_data) - if report_dataset_data['state'] == "present": + filtered_data = underscore_to_hyphen(filter_report_dataset_data(report_dataset_data)) + + if state == "present": return fos.set('report', 'dataset', data=filtered_data, vdom=vdom) - elif report_dataset_data['state'] == "absent": + elif state == "absent": return fos.delete('report', 'dataset', mkey=filtered_data['name'], vdom=vdom) +def is_successful_status(status): + return status['status'] == "success" or \ + status['http_method'] == "DELETE" and status['http_status'] == 404 + + def fortios_report(data, fos): - login(data) if data['report_dataset']: resp = report_dataset(data, fos) - fos.logout() - return not resp['status'] == "success", resp['status'] == "success", resp + return not is_successful_status(resp), \ + resp['status'] == "success", \ + resp def main(): fields = { - "host": {"required": True, "type": "str"}, - "username": {"required": True, "type": "str"}, - "password": {"required": False, "type": "str", "no_log": True}, + "host": {"required": False, "type": "str"}, + "username": {"required": False, "type": "str"}, + "password": {"required": False, "type": "str", "default": "", "no_log": True}, "vdom": {"required": False, "type": "str", "default": "root"}, "https": {"required": False, "type": "bool", "default": True}, + "ssl_verify": {"required": False, "type": "bool", "default": True}, + "state": {"required": True, "type": "str", + "choices": ["present", "absent"]}, "report_dataset": { - "required": False, "type": "dict", + "required": False, "type": "dict", "default": None, "options": { - "state": {"required": True, "type": "str", - "choices": ["present", "absent"]}, "field": {"required": False, "type": "list", "options": { "displayname": {"required": False, "type": "str"}, @@ -324,10 +355,10 @@ def main(): "name": {"required": True, "type": "str"}, "parameters": {"required": False, "type": "list", "options": { - "data-type": {"required": False, "type": "str", + "data_type": {"required": False, "type": "str", "choices": ["text", "integer", "double", "long-integer", "date-time"]}, - "display-name": {"required": False, "type": "str"}, + "display_name": {"required": False, "type": "str"}, "field": {"required": False, "type": "str"}, "id": {"required": True, "type": "int"} }}, @@ -340,15 +371,31 @@ def main(): module = AnsibleModule(argument_spec=fields, supports_check_mode=False) - try: - from fortiosapi import FortiOSAPI - except ImportError: - module.fail_json(msg="fortiosapi module is required") - global fos - 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_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: module.exit_json(changed=has_changed, meta=result) diff --git a/test/sanity/ignore.txt b/test/sanity/ignore.txt index 6420e415633..5084e868475 100644 --- a/test/sanity/ignore.txt +++ b/test/sanity/ignore.txt @@ -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_ipv4_policy.py validate-modules:E337 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: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:E337 lib/ansible/modules/network/fortios/fortios_report_setting.py validate-modules:E336 diff --git a/test/units/modules/network/fortios/test_fortios_log_memory_global_setting.py b/test/units/modules/network/fortios/test_fortios_log_memory_global_setting.py new file mode 100644 index 00000000000..0782f5e9a9f --- /dev/null +++ b/test/units/modules/network/fortios/test_fortios_log_memory_global_setting.py @@ -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 . + +# 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 diff --git a/test/units/modules/network/fortios/test_fortios_log_memory_setting.py b/test/units/modules/network/fortios/test_fortios_log_memory_setting.py new file mode 100644 index 00000000000..64101c7a146 --- /dev/null +++ b/test/units/modules/network/fortios/test_fortios_log_memory_setting.py @@ -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 . + +# 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 diff --git a/test/units/modules/network/fortios/test_fortios_log_null_device_filter.py b/test/units/modules/network/fortios/test_fortios_log_null_device_filter.py new file mode 100644 index 00000000000..86c2c90799c --- /dev/null +++ b/test/units/modules/network/fortios/test_fortios_log_null_device_filter.py @@ -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 . + +# 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 diff --git a/test/units/modules/network/fortios/test_fortios_log_null_device_setting.py b/test/units/modules/network/fortios/test_fortios_log_null_device_setting.py new file mode 100644 index 00000000000..bf4e63c478a --- /dev/null +++ b/test/units/modules/network/fortios/test_fortios_log_null_device_setting.py @@ -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 . + +# 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 diff --git a/test/units/modules/network/fortios/test_fortios_log_setting.py b/test/units/modules/network/fortios/test_fortios_log_setting.py new file mode 100644 index 00000000000..e3434e531ae --- /dev/null +++ b/test/units/modules/network/fortios/test_fortios_log_setting.py @@ -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 . + +# 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 diff --git a/test/units/modules/network/fortios/test_fortios_log_syslogd2_filter.py b/test/units/modules/network/fortios/test_fortios_log_syslogd2_filter.py new file mode 100644 index 00000000000..ee915494364 --- /dev/null +++ b/test/units/modules/network/fortios/test_fortios_log_syslogd2_filter.py @@ -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 . + +# 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 diff --git a/test/units/modules/network/fortios/test_fortios_log_syslogd2_setting.py b/test/units/modules/network/fortios/test_fortios_log_syslogd2_setting.py new file mode 100644 index 00000000000..ec4061bb6dd --- /dev/null +++ b/test/units/modules/network/fortios/test_fortios_log_syslogd2_setting.py @@ -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 . + +# 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 diff --git a/test/units/modules/network/fortios/test_fortios_log_syslogd3_filter.py b/test/units/modules/network/fortios/test_fortios_log_syslogd3_filter.py new file mode 100644 index 00000000000..ff3fc99c8b2 --- /dev/null +++ b/test/units/modules/network/fortios/test_fortios_log_syslogd3_filter.py @@ -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 . + +# 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 diff --git a/test/units/modules/network/fortios/test_fortios_log_syslogd3_setting.py b/test/units/modules/network/fortios/test_fortios_log_syslogd3_setting.py new file mode 100644 index 00000000000..3398f57623b --- /dev/null +++ b/test/units/modules/network/fortios/test_fortios_log_syslogd3_setting.py @@ -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 . + +# 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 diff --git a/test/units/modules/network/fortios/test_fortios_log_syslogd4_filter.py b/test/units/modules/network/fortios/test_fortios_log_syslogd4_filter.py new file mode 100644 index 00000000000..5e16cc48049 --- /dev/null +++ b/test/units/modules/network/fortios/test_fortios_log_syslogd4_filter.py @@ -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 . + +# 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 diff --git a/test/units/modules/network/fortios/test_fortios_log_syslogd4_setting.py b/test/units/modules/network/fortios/test_fortios_log_syslogd4_setting.py new file mode 100644 index 00000000000..582865fe435 --- /dev/null +++ b/test/units/modules/network/fortios/test_fortios_log_syslogd4_setting.py @@ -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 . + +# 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 diff --git a/test/units/modules/network/fortios/test_fortios_log_syslogd_filter.py b/test/units/modules/network/fortios/test_fortios_log_syslogd_filter.py new file mode 100644 index 00000000000..2ecaf064413 --- /dev/null +++ b/test/units/modules/network/fortios/test_fortios_log_syslogd_filter.py @@ -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 . + +# 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 diff --git a/test/units/modules/network/fortios/test_fortios_log_syslogd_override_filter.py b/test/units/modules/network/fortios/test_fortios_log_syslogd_override_filter.py new file mode 100644 index 00000000000..eedbcbdf320 --- /dev/null +++ b/test/units/modules/network/fortios/test_fortios_log_syslogd_override_filter.py @@ -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 . + +# 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 diff --git a/test/units/modules/network/fortios/test_fortios_log_syslogd_override_setting.py b/test/units/modules/network/fortios/test_fortios_log_syslogd_override_setting.py new file mode 100644 index 00000000000..460d03bab9d --- /dev/null +++ b/test/units/modules/network/fortios/test_fortios_log_syslogd_override_setting.py @@ -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 . + +# 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 diff --git a/test/units/modules/network/fortios/test_fortios_log_syslogd_setting.py b/test/units/modules/network/fortios/test_fortios_log_syslogd_setting.py new file mode 100644 index 00000000000..8f63cda92d2 --- /dev/null +++ b/test/units/modules/network/fortios/test_fortios_log_syslogd_setting.py @@ -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 . + +# 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 diff --git a/test/units/modules/network/fortios/test_fortios_log_threat_weight.py b/test/units/modules/network/fortios/test_fortios_log_threat_weight.py new file mode 100644 index 00000000000..991529da8cc --- /dev/null +++ b/test/units/modules/network/fortios/test_fortios_log_threat_weight.py @@ -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 . + +# 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 diff --git a/test/units/modules/network/fortios/test_fortios_log_webtrends_filter.py b/test/units/modules/network/fortios/test_fortios_log_webtrends_filter.py new file mode 100644 index 00000000000..c955da75ca3 --- /dev/null +++ b/test/units/modules/network/fortios/test_fortios_log_webtrends_filter.py @@ -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 . + +# 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 diff --git a/test/units/modules/network/fortios/test_fortios_log_webtrends_setting.py b/test/units/modules/network/fortios/test_fortios_log_webtrends_setting.py new file mode 100644 index 00000000000..0685fff5dc3 --- /dev/null +++ b/test/units/modules/network/fortios/test_fortios_log_webtrends_setting.py @@ -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 . + +# 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 diff --git a/test/units/modules/network/fortios/test_fortios_report_chart.py b/test/units/modules/network/fortios/test_fortios_report_chart.py new file mode 100644 index 00000000000..211ee299364 --- /dev/null +++ b/test/units/modules/network/fortios/test_fortios_report_chart.py @@ -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 . + +# 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 diff --git a/test/units/modules/network/fortios/test_fortios_report_dataset.py b/test/units/modules/network/fortios/test_fortios_report_dataset.py new file mode 100644 index 00000000000..6026d8e514f --- /dev/null +++ b/test/units/modules/network/fortios/test_fortios_report_dataset.py @@ -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 . + +# 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