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