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_system_dedicated_mgmt 27short_description: Configure dedicated management 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 system feature and dedicated_mgmt 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.9" 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 system_dedicated_mgmt: 76 description: 77 - Configure dedicated management. 78 default: null 79 type: dict 80 suboptions: 81 default_gateway: 82 description: 83 - Default gateway for dedicated management interface. 84 type: str 85 dhcp_end_ip: 86 description: 87 - DHCP end IP for dedicated management. 88 type: str 89 dhcp_netmask: 90 description: 91 - DHCP netmask. 92 type: str 93 dhcp_server: 94 description: 95 - Enable/disable DHCP server on management interface. 96 type: str 97 choices: 98 - enable 99 - disable 100 dhcp_start_ip: 101 description: 102 - DHCP start IP for dedicated management. 103 type: str 104 interface: 105 description: 106 - Dedicated management interface. Source system.interface.name. 107 type: str 108 status: 109 description: 110 - Enable/disable dedicated management. 111 type: str 112 choices: 113 - enable 114 - disable 115''' 116 117EXAMPLES = ''' 118- hosts: localhost 119 vars: 120 host: "192.168.122.40" 121 username: "admin" 122 password: "" 123 vdom: "root" 124 ssl_verify: "False" 125 tasks: 126 - name: Configure dedicated management. 127 fortios_system_dedicated_mgmt: 128 host: "{{ host }}" 129 username: "{{ username }}" 130 password: "{{ password }}" 131 vdom: "{{ vdom }}" 132 https: "False" 133 system_dedicated_mgmt: 134 default_gateway: "<your_own_value>" 135 dhcp_end_ip: "<your_own_value>" 136 dhcp_netmask: "<your_own_value>" 137 dhcp_server: "enable" 138 dhcp_start_ip: "<your_own_value>" 139 interface: "<your_own_value> (source system.interface.name)" 140 status: "enable" 141''' 142 143RETURN = ''' 144build: 145 description: Build number of the fortigate image 146 returned: always 147 type: str 148 sample: '1547' 149http_method: 150 description: Last method used to provision the content into FortiGate 151 returned: always 152 type: str 153 sample: 'PUT' 154http_status: 155 description: Last result given by FortiGate on last operation applied 156 returned: always 157 type: str 158 sample: "200" 159mkey: 160 description: Master key (id) used in the last call to FortiGate 161 returned: success 162 type: str 163 sample: "id" 164name: 165 description: Name of the table used to fulfill the request 166 returned: always 167 type: str 168 sample: "urlfilter" 169path: 170 description: Path of the table used to fulfill the request 171 returned: always 172 type: str 173 sample: "webfilter" 174revision: 175 description: Internal revision number 176 returned: always 177 type: str 178 sample: "17.0.2.10658" 179serial: 180 description: Serial number of the unit 181 returned: always 182 type: str 183 sample: "FGVMEVYYQT3AB5352" 184status: 185 description: Indication of the operation's result 186 returned: always 187 type: str 188 sample: "success" 189vdom: 190 description: Virtual domain used 191 returned: always 192 type: str 193 sample: "root" 194version: 195 description: Version of the FortiGate 196 returned: always 197 type: str 198 sample: "v5.6.3" 199 200''' 201 202from ansible.module_utils.basic import AnsibleModule 203from ansible.module_utils.connection import Connection 204from ansible.module_utils.network.fortios.fortios import FortiOSHandler 205from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG 206 207 208def login(data, fos): 209 host = data['host'] 210 username = data['username'] 211 password = data['password'] 212 ssl_verify = data['ssl_verify'] 213 214 fos.debug('on') 215 if 'https' in data and not data['https']: 216 fos.https('off') 217 else: 218 fos.https('on') 219 220 fos.login(host, username, password, verify=ssl_verify) 221 222 223def filter_system_dedicated_mgmt_data(json): 224 option_list = ['default_gateway', 'dhcp_end_ip', 'dhcp_netmask', 225 'dhcp_server', 'dhcp_start_ip', 'interface', 226 'status'] 227 dictionary = {} 228 229 for attribute in option_list: 230 if attribute in json and json[attribute] is not None: 231 dictionary[attribute] = json[attribute] 232 233 return dictionary 234 235 236def underscore_to_hyphen(data): 237 if isinstance(data, list): 238 for elem in data: 239 elem = underscore_to_hyphen(elem) 240 elif isinstance(data, dict): 241 new_data = {} 242 for k, v in data.items(): 243 new_data[k.replace('_', '-')] = underscore_to_hyphen(v) 244 data = new_data 245 246 return data 247 248 249def system_dedicated_mgmt(data, fos): 250 vdom = data['vdom'] 251 system_dedicated_mgmt_data = data['system_dedicated_mgmt'] 252 filtered_data = underscore_to_hyphen(filter_system_dedicated_mgmt_data(system_dedicated_mgmt_data)) 253 254 return fos.set('system', 255 'dedicated-mgmt', 256 data=filtered_data, 257 vdom=vdom) 258 259 260def is_successful_status(status): 261 return status['status'] == "success" or \ 262 status['http_method'] == "DELETE" and status['http_status'] == 404 263 264 265def fortios_system(data, fos): 266 267 if data['system_dedicated_mgmt']: 268 resp = system_dedicated_mgmt(data, fos) 269 270 return not is_successful_status(resp), \ 271 resp['status'] == "success", \ 272 resp 273 274 275def main(): 276 fields = { 277 "host": {"required": False, "type": "str"}, 278 "username": {"required": False, "type": "str"}, 279 "password": {"required": False, "type": "str", "default": "", "no_log": True}, 280 "vdom": {"required": False, "type": "str", "default": "root"}, 281 "https": {"required": False, "type": "bool", "default": True}, 282 "ssl_verify": {"required": False, "type": "bool", "default": True}, 283 "system_dedicated_mgmt": { 284 "required": False, "type": "dict", "default": None, 285 "options": { 286 "default_gateway": {"required": False, "type": "str"}, 287 "dhcp_end_ip": {"required": False, "type": "str"}, 288 "dhcp_netmask": {"required": False, "type": "str"}, 289 "dhcp_server": {"required": False, "type": "str", 290 "choices": ["enable", "disable"]}, 291 "dhcp_start_ip": {"required": False, "type": "str"}, 292 "interface": {"required": False, "type": "str"}, 293 "status": {"required": False, "type": "str", 294 "choices": ["enable", "disable"]} 295 296 } 297 } 298 } 299 300 module = AnsibleModule(argument_spec=fields, 301 supports_check_mode=False) 302 303 # legacy_mode refers to using fortiosapi instead of HTTPAPI 304 legacy_mode = 'host' in module.params and module.params['host'] is not None and \ 305 'username' in module.params and module.params['username'] is not None and \ 306 'password' in module.params and module.params['password'] is not None 307 308 if not legacy_mode: 309 if module._socket_path: 310 connection = Connection(module._socket_path) 311 fos = FortiOSHandler(connection) 312 313 is_error, has_changed, result = fortios_system(module.params, fos) 314 else: 315 module.fail_json(**FAIL_SOCKET_MSG) 316 else: 317 try: 318 from fortiosapi import FortiOSAPI 319 except ImportError: 320 module.fail_json(msg="fortiosapi module is required") 321 322 fos = FortiOSAPI() 323 324 login(module.params, fos) 325 is_error, has_changed, result = fortios_system(module.params, fos) 326 fos.logout() 327 328 if not is_error: 329 module.exit_json(changed=has_changed, meta=result) 330 else: 331 module.fail_json(msg="Error in repo", meta=result) 332 333 334if __name__ == '__main__': 335 main() 336