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_fortianalyzer2_filter 27short_description: Filters for FortiAnalyzer 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_fortianalyzer2 feature and filter 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_fortianalyzer2_filter: 77 description: 78 - Filters for FortiAnalyzer. 79 default: null 80 type: dict 81 suboptions: 82 anomaly: 83 description: 84 - Enable/disable anomaly logging. 85 type: str 86 choices: 87 - enable 88 - disable 89 dlp_archive: 90 description: 91 - Enable/disable DLP archive logging. 92 type: str 93 choices: 94 - enable 95 - disable 96 dns: 97 description: 98 - Enable/disable detailed DNS event logging. 99 type: str 100 choices: 101 - enable 102 - disable 103 filter: 104 description: 105 - FortiAnalyzer 2 log filter. 106 type: str 107 filter_type: 108 description: 109 - Include/exclude logs that match the filter. 110 type: str 111 choices: 112 - include 113 - exclude 114 forward_traffic: 115 description: 116 - Enable/disable forward traffic logging. 117 type: str 118 choices: 119 - enable 120 - disable 121 gtp: 122 description: 123 - Enable/disable GTP messages logging. 124 type: str 125 choices: 126 - enable 127 - disable 128 local_traffic: 129 description: 130 - Enable/disable local in or out traffic logging. 131 type: str 132 choices: 133 - enable 134 - disable 135 multicast_traffic: 136 description: 137 - Enable/disable multicast traffic logging. 138 type: str 139 choices: 140 - enable 141 - disable 142 netscan_discovery: 143 description: 144 - Enable/disable netscan discovery event logging. 145 type: str 146 netscan_vulnerability: 147 description: 148 - Enable/disable netscan vulnerability event logging. 149 type: str 150 severity: 151 description: 152 - Log every message above and including this severity level. 153 type: str 154 choices: 155 - emergency 156 - alert 157 - critical 158 - error 159 - warning 160 - notification 161 - information 162 - debug 163 sniffer_traffic: 164 description: 165 - Enable/disable sniffer traffic logging. 166 type: str 167 choices: 168 - enable 169 - disable 170 ssh: 171 description: 172 - Enable/disable SSH logging. 173 type: str 174 choices: 175 - enable 176 - disable 177 voip: 178 description: 179 - Enable/disable VoIP logging. 180 type: str 181 choices: 182 - enable 183 - disable 184''' 185 186EXAMPLES = ''' 187- hosts: localhost 188 vars: 189 host: "192.168.122.40" 190 username: "admin" 191 password: "" 192 vdom: "root" 193 ssl_verify: "False" 194 tasks: 195 - name: Filters for FortiAnalyzer. 196 fortios_log_fortianalyzer2_filter: 197 host: "{{ host }}" 198 username: "{{ username }}" 199 password: "{{ password }}" 200 vdom: "{{ vdom }}" 201 https: "False" 202 log_fortianalyzer2_filter: 203 anomaly: "enable" 204 dlp_archive: "enable" 205 dns: "enable" 206 filter: "<your_own_value>" 207 filter_type: "include" 208 forward_traffic: "enable" 209 gtp: "enable" 210 local_traffic: "enable" 211 multicast_traffic: "enable" 212 netscan_discovery: "<your_own_value>" 213 netscan_vulnerability: "<your_own_value>" 214 severity: "emergency" 215 sniffer_traffic: "enable" 216 ssh: "enable" 217 voip: "enable" 218''' 219 220RETURN = ''' 221build: 222 description: Build number of the fortigate image 223 returned: always 224 type: str 225 sample: '1547' 226http_method: 227 description: Last method used to provision the content into FortiGate 228 returned: always 229 type: str 230 sample: 'PUT' 231http_status: 232 description: Last result given by FortiGate on last operation applied 233 returned: always 234 type: str 235 sample: "200" 236mkey: 237 description: Master key (id) used in the last call to FortiGate 238 returned: success 239 type: str 240 sample: "id" 241name: 242 description: Name of the table used to fulfill the request 243 returned: always 244 type: str 245 sample: "urlfilter" 246path: 247 description: Path of the table used to fulfill the request 248 returned: always 249 type: str 250 sample: "webfilter" 251revision: 252 description: Internal revision number 253 returned: always 254 type: str 255 sample: "17.0.2.10658" 256serial: 257 description: Serial number of the unit 258 returned: always 259 type: str 260 sample: "FGVMEVYYQT3AB5352" 261status: 262 description: Indication of the operation's result 263 returned: always 264 type: str 265 sample: "success" 266vdom: 267 description: Virtual domain used 268 returned: always 269 type: str 270 sample: "root" 271version: 272 description: Version of the FortiGate 273 returned: always 274 type: str 275 sample: "v5.6.3" 276 277''' 278 279from ansible.module_utils.basic import AnsibleModule 280from ansible.module_utils.connection import Connection 281from ansible.module_utils.network.fortios.fortios import FortiOSHandler 282from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG 283 284 285def login(data, fos): 286 host = data['host'] 287 username = data['username'] 288 password = data['password'] 289 ssl_verify = data['ssl_verify'] 290 291 fos.debug('on') 292 if 'https' in data and not data['https']: 293 fos.https('off') 294 else: 295 fos.https('on') 296 297 fos.login(host, username, password, verify=ssl_verify) 298 299 300def filter_log_fortianalyzer2_filter_data(json): 301 option_list = ['anomaly', 'dlp_archive', 'dns', 302 'filter', 'filter_type', 'forward_traffic', 303 'gtp', 'local_traffic', 'multicast_traffic', 304 'netscan_discovery', 'netscan_vulnerability', 'severity', 305 'sniffer_traffic', 'ssh', 'voip'] 306 dictionary = {} 307 308 for attribute in option_list: 309 if attribute in json and json[attribute] is not None: 310 dictionary[attribute] = json[attribute] 311 312 return dictionary 313 314 315def underscore_to_hyphen(data): 316 if isinstance(data, list): 317 for elem in data: 318 elem = underscore_to_hyphen(elem) 319 elif isinstance(data, dict): 320 new_data = {} 321 for k, v in data.items(): 322 new_data[k.replace('_', '-')] = underscore_to_hyphen(v) 323 data = new_data 324 325 return data 326 327 328def log_fortianalyzer2_filter(data, fos): 329 vdom = data['vdom'] 330 log_fortianalyzer2_filter_data = data['log_fortianalyzer2_filter'] 331 filtered_data = underscore_to_hyphen(filter_log_fortianalyzer2_filter_data(log_fortianalyzer2_filter_data)) 332 333 return fos.set('log.fortianalyzer2', 334 'filter', 335 data=filtered_data, 336 vdom=vdom) 337 338 339def is_successful_status(status): 340 return status['status'] == "success" or \ 341 status['http_method'] == "DELETE" and status['http_status'] == 404 342 343 344def fortios_log_fortianalyzer2(data, fos): 345 346 if data['log_fortianalyzer2_filter']: 347 resp = log_fortianalyzer2_filter(data, fos) 348 349 return not is_successful_status(resp), \ 350 resp['status'] == "success", \ 351 resp 352 353 354def main(): 355 fields = { 356 "host": {"required": False, "type": "str"}, 357 "username": {"required": False, "type": "str"}, 358 "password": {"required": False, "type": "str", "default": "", "no_log": True}, 359 "vdom": {"required": False, "type": "str", "default": "root"}, 360 "https": {"required": False, "type": "bool", "default": True}, 361 "ssl_verify": {"required": False, "type": "bool", "default": True}, 362 "log_fortianalyzer2_filter": { 363 "required": False, "type": "dict", "default": None, 364 "options": { 365 "anomaly": {"required": False, "type": "str", 366 "choices": ["enable", "disable"]}, 367 "dlp_archive": {"required": False, "type": "str", 368 "choices": ["enable", "disable"]}, 369 "dns": {"required": False, "type": "str", 370 "choices": ["enable", "disable"]}, 371 "filter": {"required": False, "type": "str"}, 372 "filter_type": {"required": False, "type": "str", 373 "choices": ["include", "exclude"]}, 374 "forward_traffic": {"required": False, "type": "str", 375 "choices": ["enable", "disable"]}, 376 "gtp": {"required": False, "type": "str", 377 "choices": ["enable", "disable"]}, 378 "local_traffic": {"required": False, "type": "str", 379 "choices": ["enable", "disable"]}, 380 "multicast_traffic": {"required": False, "type": "str", 381 "choices": ["enable", "disable"]}, 382 "netscan_discovery": {"required": False, "type": "str"}, 383 "netscan_vulnerability": {"required": False, "type": "str"}, 384 "severity": {"required": False, "type": "str", 385 "choices": ["emergency", "alert", "critical", 386 "error", "warning", "notification", 387 "information", "debug"]}, 388 "sniffer_traffic": {"required": False, "type": "str", 389 "choices": ["enable", "disable"]}, 390 "ssh": {"required": False, "type": "str", 391 "choices": ["enable", "disable"]}, 392 "voip": {"required": False, "type": "str", 393 "choices": ["enable", "disable"]} 394 395 } 396 } 397 } 398 399 module = AnsibleModule(argument_spec=fields, 400 supports_check_mode=False) 401 402 # legacy_mode refers to using fortiosapi instead of HTTPAPI 403 legacy_mode = 'host' in module.params and module.params['host'] is not None and \ 404 'username' in module.params and module.params['username'] is not None and \ 405 'password' in module.params and module.params['password'] is not None 406 407 if not legacy_mode: 408 if module._socket_path: 409 connection = Connection(module._socket_path) 410 fos = FortiOSHandler(connection) 411 412 is_error, has_changed, result = fortios_log_fortianalyzer2(module.params, fos) 413 else: 414 module.fail_json(**FAIL_SOCKET_MSG) 415 else: 416 try: 417 from fortiosapi import FortiOSAPI 418 except ImportError: 419 module.fail_json(msg="fortiosapi module is required") 420 421 fos = FortiOSAPI() 422 423 login(module.params, fos) 424 is_error, has_changed, result = fortios_log_fortianalyzer2(module.params, fos) 425 fos.logout() 426 427 if not is_error: 428 module.exit_json(changed=has_changed, meta=result) 429 else: 430 module.fail_json(msg="Error in repo", meta=result) 431 432 433if __name__ == '__main__': 434 main() 435