1#!/usr/bin/python 2from __future__ import (absolute_import, division, print_function) 3# Copyright 2019 Fortinet, Inc. 4# 5# This program is free software: you can redistribute it and/or modify 6# it under the terms of the GNU General Public License as published by 7# the Free Software Foundation, either version 3 of the License, or 8# (at your option) any later version. 9# 10# This program is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13# GNU General Public License for more details. 14# 15# You should have received a copy of the GNU General Public License 16# along with this program. If not, see <https://www.gnu.org/licenses/>. 17 18__metaclass__ = type 19 20ANSIBLE_METADATA = {'status': ['preview'], 21 'supported_by': 'community', 22 'metadata_version': '1.1'} 23 24DOCUMENTATION = ''' 25--- 26module: fortios_log_fortiguard_setting 27short_description: Configure logging to FortiCloud in Fortinet's FortiOS and FortiGate. 28description: 29 - This module is able to configure a FortiGate or FortiOS (FOS) device by allowing the 30 user to set and modify log_fortiguard feature and setting category. 31 Examples include all parameters and values need to be adjusted to datasources before usage. 32 Tested with FOS v6.0.5 33version_added: "2.8" 34author: 35 - Miguel Angel Munoz (@mamunozgonzalez) 36 - Nicolas Thomas (@thomnico) 37notes: 38 - Requires fortiosapi library developed by Fortinet 39 - Run as a local_action in your playbook 40requirements: 41 - fortiosapi>=0.9.8 42options: 43 host: 44 description: 45 - FortiOS or FortiGate IP address. 46 type: str 47 required: false 48 username: 49 description: 50 - FortiOS or FortiGate username. 51 type: str 52 required: false 53 password: 54 description: 55 - FortiOS or FortiGate password. 56 type: str 57 default: "" 58 vdom: 59 description: 60 - Virtual domain, among those defined previously. A vdom is a 61 virtual instance of the FortiGate that can be configured and 62 used as a different unit. 63 type: str 64 default: root 65 https: 66 description: 67 - Indicates if the requests towards FortiGate must use HTTPS protocol. 68 type: bool 69 default: true 70 ssl_verify: 71 description: 72 - Ensures FortiGate certificate must be verified by a proper CA. 73 type: bool 74 default: true 75 version_added: 2.9 76 log_fortiguard_setting: 77 description: 78 - Configure logging to FortiCloud. 79 default: null 80 type: dict 81 suboptions: 82 enc_algorithm: 83 description: 84 - Enable and set the SSL security level for for sending encrypted logs to FortiCloud. 85 type: str 86 choices: 87 - high-medium 88 - high 89 - low 90 source_ip: 91 description: 92 - Source IP address used to connect FortiCloud. 93 type: str 94 ssl_min_proto_version: 95 description: 96 - Minimum supported protocol version for SSL/TLS connections . 97 type: str 98 choices: 99 - default 100 - SSLv3 101 - TLSv1 102 - TLSv1-1 103 - TLSv1-2 104 status: 105 description: 106 - Enable/disable logging to FortiCloud. 107 type: str 108 choices: 109 - enable 110 - disable 111 upload_day: 112 description: 113 - Day of week to roll logs. 114 type: str 115 upload_interval: 116 description: 117 - Frequency of uploading log files to FortiCloud. 118 type: str 119 choices: 120 - daily 121 - weekly 122 - monthly 123 upload_option: 124 description: 125 - Configure how log messages are sent to FortiCloud. 126 type: str 127 choices: 128 - store-and-upload 129 - realtime 130 - 1-minute 131 - 5-minute 132 upload_time: 133 description: 134 - "Time of day to roll logs (hh:mm)." 135 type: str 136''' 137 138EXAMPLES = ''' 139- hosts: localhost 140 vars: 141 host: "192.168.122.40" 142 username: "admin" 143 password: "" 144 vdom: "root" 145 ssl_verify: "False" 146 tasks: 147 - name: Configure logging to FortiCloud. 148 fortios_log_fortiguard_setting: 149 host: "{{ host }}" 150 username: "{{ username }}" 151 password: "{{ password }}" 152 vdom: "{{ vdom }}" 153 https: "False" 154 log_fortiguard_setting: 155 enc_algorithm: "high-medium" 156 source_ip: "84.230.14.43" 157 ssl_min_proto_version: "default" 158 status: "enable" 159 upload_day: "<your_own_value>" 160 upload_interval: "daily" 161 upload_option: "store-and-upload" 162 upload_time: "<your_own_value>" 163''' 164 165RETURN = ''' 166build: 167 description: Build number of the fortigate image 168 returned: always 169 type: str 170 sample: '1547' 171http_method: 172 description: Last method used to provision the content into FortiGate 173 returned: always 174 type: str 175 sample: 'PUT' 176http_status: 177 description: Last result given by FortiGate on last operation applied 178 returned: always 179 type: str 180 sample: "200" 181mkey: 182 description: Master key (id) used in the last call to FortiGate 183 returned: success 184 type: str 185 sample: "id" 186name: 187 description: Name of the table used to fulfill the request 188 returned: always 189 type: str 190 sample: "urlfilter" 191path: 192 description: Path of the table used to fulfill the request 193 returned: always 194 type: str 195 sample: "webfilter" 196revision: 197 description: Internal revision number 198 returned: always 199 type: str 200 sample: "17.0.2.10658" 201serial: 202 description: Serial number of the unit 203 returned: always 204 type: str 205 sample: "FGVMEVYYQT3AB5352" 206status: 207 description: Indication of the operation's result 208 returned: always 209 type: str 210 sample: "success" 211vdom: 212 description: Virtual domain used 213 returned: always 214 type: str 215 sample: "root" 216version: 217 description: Version of the FortiGate 218 returned: always 219 type: str 220 sample: "v5.6.3" 221 222''' 223 224from ansible.module_utils.basic import AnsibleModule 225from ansible.module_utils.connection import Connection 226from ansible.module_utils.network.fortios.fortios import FortiOSHandler 227from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG 228 229 230def login(data, fos): 231 host = data['host'] 232 username = data['username'] 233 password = data['password'] 234 ssl_verify = data['ssl_verify'] 235 236 fos.debug('on') 237 if 'https' in data and not data['https']: 238 fos.https('off') 239 else: 240 fos.https('on') 241 242 fos.login(host, username, password, verify=ssl_verify) 243 244 245def filter_log_fortiguard_setting_data(json): 246 option_list = ['enc_algorithm', 'source_ip', 'ssl_min_proto_version', 247 'status', 'upload_day', 'upload_interval', 248 'upload_option', 'upload_time'] 249 dictionary = {} 250 251 for attribute in option_list: 252 if attribute in json and json[attribute] is not None: 253 dictionary[attribute] = json[attribute] 254 255 return dictionary 256 257 258def underscore_to_hyphen(data): 259 if isinstance(data, list): 260 for elem in data: 261 elem = underscore_to_hyphen(elem) 262 elif isinstance(data, dict): 263 new_data = {} 264 for k, v in data.items(): 265 new_data[k.replace('_', '-')] = underscore_to_hyphen(v) 266 data = new_data 267 268 return data 269 270 271def log_fortiguard_setting(data, fos): 272 vdom = data['vdom'] 273 log_fortiguard_setting_data = data['log_fortiguard_setting'] 274 filtered_data = underscore_to_hyphen(filter_log_fortiguard_setting_data(log_fortiguard_setting_data)) 275 276 return fos.set('log.fortiguard', 277 'setting', 278 data=filtered_data, 279 vdom=vdom) 280 281 282def is_successful_status(status): 283 return status['status'] == "success" or \ 284 status['http_method'] == "DELETE" and status['http_status'] == 404 285 286 287def fortios_log_fortiguard(data, fos): 288 289 if data['log_fortiguard_setting']: 290 resp = log_fortiguard_setting(data, fos) 291 292 return not is_successful_status(resp), \ 293 resp['status'] == "success", \ 294 resp 295 296 297def main(): 298 fields = { 299 "host": {"required": False, "type": "str"}, 300 "username": {"required": False, "type": "str"}, 301 "password": {"required": False, "type": "str", "default": "", "no_log": True}, 302 "vdom": {"required": False, "type": "str", "default": "root"}, 303 "https": {"required": False, "type": "bool", "default": True}, 304 "ssl_verify": {"required": False, "type": "bool", "default": True}, 305 "log_fortiguard_setting": { 306 "required": False, "type": "dict", "default": None, 307 "options": { 308 "enc_algorithm": {"required": False, "type": "str", 309 "choices": ["high-medium", "high", "low"]}, 310 "source_ip": {"required": False, "type": "str"}, 311 "ssl_min_proto_version": {"required": False, "type": "str", 312 "choices": ["default", "SSLv3", "TLSv1", 313 "TLSv1-1", "TLSv1-2"]}, 314 "status": {"required": False, "type": "str", 315 "choices": ["enable", "disable"]}, 316 "upload_day": {"required": False, "type": "str"}, 317 "upload_interval": {"required": False, "type": "str", 318 "choices": ["daily", "weekly", "monthly"]}, 319 "upload_option": {"required": False, "type": "str", 320 "choices": ["store-and-upload", "realtime", "1-minute", 321 "5-minute"]}, 322 "upload_time": {"required": False, "type": "str"} 323 324 } 325 } 326 } 327 328 module = AnsibleModule(argument_spec=fields, 329 supports_check_mode=False) 330 331 # legacy_mode refers to using fortiosapi instead of HTTPAPI 332 legacy_mode = 'host' in module.params and module.params['host'] is not None and \ 333 'username' in module.params and module.params['username'] is not None and \ 334 'password' in module.params and module.params['password'] is not None 335 336 if not legacy_mode: 337 if module._socket_path: 338 connection = Connection(module._socket_path) 339 fos = FortiOSHandler(connection) 340 341 is_error, has_changed, result = fortios_log_fortiguard(module.params, fos) 342 else: 343 module.fail_json(**FAIL_SOCKET_MSG) 344 else: 345 try: 346 from fortiosapi import FortiOSAPI 347 except ImportError: 348 module.fail_json(msg="fortiosapi module is required") 349 350 fos = FortiOSAPI() 351 352 login(module.params, fos) 353 is_error, has_changed, result = fortios_log_fortiguard(module.params, fos) 354 fos.logout() 355 356 if not is_error: 357 module.exit_json(changed=has_changed, meta=result) 358 else: 359 module.fail_json(msg="Error in repo", meta=result) 360 361 362if __name__ == '__main__': 363 main() 364