1#!/usr/local/bin/python3.8 2from __future__ import (absolute_import, division, print_function) 3# Copyright 2019-2020 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_webfilter_status 27short_description: Display rating info 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 webfilter feature and status category. 31 Examples include all parameters and values need to be adjusted to datasources before usage. 32 Tested with FOS v6.0.0 33version_added: "2.10" 34author: 35 - Link Zheng (@chillancezen) 36 - Jie Xue (@JieX19) 37 - Hongbin Lu (@fgtdev-hblu) 38 - Frank Shen (@frankshen01) 39 - Miguel Angel Munoz (@mamunozgonzalez) 40 - Nicolas Thomas (@thomnico) 41notes: 42 - Legacy fortiosapi has been deprecated, httpapi is the preferred way to run playbooks 43 44requirements: 45 - ansible>=2.9.0 46options: 47 access_token: 48 description: 49 - Token-based authentication. 50 Generated from GUI of Fortigate. 51 type: str 52 required: false 53 enable_log: 54 description: 55 - Enable/Disable logging for task. 56 type: bool 57 required: false 58 default: false 59 vdom: 60 description: 61 - Virtual domain, among those defined previously. A vdom is a 62 virtual instance of the FortiGate that can be configured and 63 used as a different unit. 64 type: str 65 default: root 66 67 webfilter_status: 68 description: 69 - Display rating info. 70 default: null 71 type: dict 72 suboptions: 73 <refresh_rate>: 74 description: 75 - Frequency to refresh the server list (sec). 76 type: str 77''' 78 79EXAMPLES = ''' 80- hosts: fortigates 81 collections: 82 - fortinet.fortios 83 connection: httpapi 84 vars: 85 vdom: "root" 86 ansible_httpapi_use_ssl: yes 87 ansible_httpapi_validate_certs: no 88 ansible_httpapi_port: 443 89 tasks: 90 - name: Display rating info. 91 fortios_webfilter_status: 92 vdom: "{{ vdom }}" 93 webfilter_status: 94 <refresh_rate>: "<your_own_value>" 95 96''' 97 98RETURN = ''' 99build: 100 description: Build number of the fortigate image 101 returned: always 102 type: str 103 sample: '1547' 104http_method: 105 description: Last method used to provision the content into FortiGate 106 returned: always 107 type: str 108 sample: 'PUT' 109http_status: 110 description: Last result given by FortiGate on last operation applied 111 returned: always 112 type: str 113 sample: "200" 114mkey: 115 description: Master key (id) used in the last call to FortiGate 116 returned: success 117 type: str 118 sample: "id" 119name: 120 description: Name of the table used to fulfill the request 121 returned: always 122 type: str 123 sample: "urlfilter" 124path: 125 description: Path of the table used to fulfill the request 126 returned: always 127 type: str 128 sample: "webfilter" 129revision: 130 description: Internal revision number 131 returned: always 132 type: str 133 sample: "17.0.2.10658" 134serial: 135 description: Serial number of the unit 136 returned: always 137 type: str 138 sample: "FGVMEVYYQT3AB5352" 139status: 140 description: Indication of the operation's result 141 returned: always 142 type: str 143 sample: "success" 144vdom: 145 description: Virtual domain used 146 returned: always 147 type: str 148 sample: "root" 149version: 150 description: Version of the FortiGate 151 returned: always 152 type: str 153 sample: "v5.6.3" 154 155''' 156from ansible.module_utils.basic import AnsibleModule 157from ansible.module_utils.connection import Connection 158from ansible_collections.fortinet.fortios.plugins.module_utils.fortios.fortios import FortiOSHandler 159from ansible_collections.fortinet.fortios.plugins.module_utils.fortios.fortios import check_legacy_fortiosapi 160from ansible_collections.fortinet.fortios.plugins.module_utils.fortios.fortios import schema_to_module_spec 161from ansible_collections.fortinet.fortios.plugins.module_utils.fortios.fortios import check_schema_versioning 162from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FAIL_SOCKET_MSG 163from ansible_collections.fortinet.fortios.plugins.module_utils.fortios.comparison import is_same_comparison 164from ansible_collections.fortinet.fortios.plugins.module_utils.fortios.comparison import serialize 165 166 167def filter_webfilter_status_data(json): 168 option_list = ['<refresh_rate>'] 169 dictionary = {} 170 171 for attribute in option_list: 172 if attribute in json and json[attribute] is not None: 173 dictionary[attribute] = json[attribute] 174 175 return dictionary 176 177 178def underscore_to_hyphen(data): 179 if isinstance(data, list): 180 for i, elem in enumerate(data): 181 data[i] = underscore_to_hyphen(elem) 182 elif isinstance(data, dict): 183 new_data = {} 184 for k, v in data.items(): 185 new_data[k.replace('_', '-')] = underscore_to_hyphen(v) 186 data = new_data 187 188 return data 189 190 191def webfilter_status(data, fos): 192 vdom = data['vdom'] 193 webfilter_status_data = data['webfilter_status'] 194 filtered_data = underscore_to_hyphen(filter_webfilter_status_data(webfilter_status_data)) 195 196 return fos.set('webfilter', 197 'status', 198 data=filtered_data, 199 vdom=vdom) 200 201 202def is_successful_status(status): 203 return status['status'] == "success" or \ 204 status['http_method'] == "DELETE" and status['http_status'] == 404 205 206 207def fortios_webfilter(data, fos): 208 209 if data['webfilter_status']: 210 resp = webfilter_status(data, fos) 211 else: 212 fos._module.fail_json(msg='missing task body: %s' % ('webfilter_status')) 213 214 return not is_successful_status(resp), \ 215 resp['status'] == "success" and \ 216 (resp['revision_changed'] if 'revision_changed' in resp else True), \ 217 resp 218 219 220versioned_schema = { 221 "type": "dict", 222 "children": { 223 "<refresh_rate>": { 224 "type": "string", 225 "revisions": { 226 "v7.0.0": True, 227 "v6.4.4": True, 228 "v6.4.0": True, 229 "v6.4.1": True, 230 "v6.2.0": True, 231 "v6.2.5": True, 232 "v6.2.7": True 233 } 234 } 235 }, 236 "revisions": { 237 "v7.0.0": True, 238 "v6.4.4": True, 239 "v6.4.0": True, 240 "v6.4.1": True, 241 "v6.2.0": True, 242 "v6.2.5": True, 243 "v6.2.7": True 244 } 245} 246 247 248def main(): 249 module_spec = schema_to_module_spec(versioned_schema) 250 mkeyname = None 251 fields = { 252 "access_token": {"required": False, "type": "str", "no_log": True}, 253 "enable_log": {"required": False, "type": bool}, 254 "vdom": {"required": False, "type": "str", "default": "root"}, 255 "webfilter_status": { 256 "required": False, "type": "dict", "default": None, 257 "options": { 258 } 259 } 260 } 261 for attribute_name in module_spec['options']: 262 fields["webfilter_status"]['options'][attribute_name] = module_spec['options'][attribute_name] 263 if mkeyname and mkeyname == attribute_name: 264 fields["webfilter_status"]['options'][attribute_name]['required'] = True 265 266 check_legacy_fortiosapi() 267 module = AnsibleModule(argument_spec=fields, 268 supports_check_mode=False) 269 270 versions_check_result = None 271 if module._socket_path: 272 connection = Connection(module._socket_path) 273 if 'access_token' in module.params: 274 connection.set_option('access_token', module.params['access_token']) 275 276 if 'enable_log' in module.params: 277 connection.set_option('enable_log', module.params['enable_log']) 278 else: 279 connection.set_option('enable_log', False) 280 fos = FortiOSHandler(connection, module, mkeyname) 281 versions_check_result = check_schema_versioning(fos, versioned_schema, "webfilter_status") 282 283 is_error, has_changed, result = fortios_webfilter(module.params, fos) 284 285 else: 286 module.fail_json(**FAIL_SOCKET_MSG) 287 288 if versions_check_result and versions_check_result['matched'] is False: 289 module.warn("Ansible has detected version mismatch between FortOS system and your playbook, see more details by specifying option -vvv") 290 291 if not is_error: 292 if versions_check_result and versions_check_result['matched'] is False: 293 module.exit_json(changed=has_changed, version_check_warning=versions_check_result, meta=result) 294 else: 295 module.exit_json(changed=has_changed, meta=result) 296 else: 297 if versions_check_result and versions_check_result['matched'] is False: 298 module.fail_json(msg="Error in repo", version_check_warning=versions_check_result, meta=result) 299 else: 300 module.fail_json(msg="Error in repo", meta=result) 301 302 303if __name__ == '__main__': 304 main() 305