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_wireless_controller_hotspot20_h2qp_osu_provider
27short_description: Configure online sign up (OSU) provider list 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 wireless_controller_hotspot20 feature and h2qp_osu_provider 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    wireless_controller_hotspot20_h2qp_osu_provider:
84        description:
85            - Configure online sign up (OSU) provider list.
86        default: null
87        type: dict
88        suboptions:
89            friendly_name:
90                description:
91                    - OSU provider friendly name.
92                type: list
93                suboptions:
94                    friendly_name:
95                        description:
96                            - OSU provider friendly name.
97                        type: str
98                    index:
99                        description:
100                            - OSU provider friendly name index.
101                        required: true
102                        type: int
103                    lang:
104                        description:
105                            - Language code.
106                        type: str
107            icon:
108                description:
109                    - OSU provider icon. Source wireless-controller.hotspot20.icon.name.
110                type: str
111            name:
112                description:
113                    - OSU provider ID.
114                required: true
115                type: str
116            osu_method:
117                description:
118                    - OSU method list.
119                type: str
120                choices:
121                    - oma-dm
122                    - soap-xml-spp
123                    - reserved
124            osu_nai:
125                description:
126                    - OSU NAI.
127                type: str
128            server_uri:
129                description:
130                    - Server URI.
131                type: str
132            service_description:
133                description:
134                    - OSU service name.
135                type: list
136                suboptions:
137                    lang:
138                        description:
139                            - Language code.
140                        type: str
141                    service_description:
142                        description:
143                            - Service description.
144                        type: str
145                    service_id:
146                        description:
147                            - OSU service ID.
148                        type: int
149'''
150
151EXAMPLES = '''
152- hosts: localhost
153  vars:
154   host: "192.168.122.40"
155   username: "admin"
156   password: ""
157   vdom: "root"
158   ssl_verify: "False"
159  tasks:
160  - name: Configure online sign up (OSU) provider list.
161    fortios_wireless_controller_hotspot20_h2qp_osu_provider:
162      host:  "{{ host }}"
163      username: "{{ username }}"
164      password: "{{ password }}"
165      vdom:  "{{ vdom }}"
166      https: "False"
167      state: "present"
168      wireless_controller_hotspot20_h2qp_osu_provider:
169        friendly_name:
170         -
171            friendly_name: "<your_own_value>"
172            index: "5"
173            lang: "<your_own_value>"
174        icon: "<your_own_value> (source wireless-controller.hotspot20.icon.name)"
175        name: "default_name_8"
176        osu_method: "oma-dm"
177        osu_nai: "<your_own_value>"
178        server_uri: "<your_own_value>"
179        service_description:
180         -
181            lang: "<your_own_value>"
182            service_description: "<your_own_value>"
183            service_id: "15"
184'''
185
186RETURN = '''
187build:
188  description: Build number of the fortigate image
189  returned: always
190  type: str
191  sample: '1547'
192http_method:
193  description: Last method used to provision the content into FortiGate
194  returned: always
195  type: str
196  sample: 'PUT'
197http_status:
198  description: Last result given by FortiGate on last operation applied
199  returned: always
200  type: str
201  sample: "200"
202mkey:
203  description: Master key (id) used in the last call to FortiGate
204  returned: success
205  type: str
206  sample: "id"
207name:
208  description: Name of the table used to fulfill the request
209  returned: always
210  type: str
211  sample: "urlfilter"
212path:
213  description: Path of the table used to fulfill the request
214  returned: always
215  type: str
216  sample: "webfilter"
217revision:
218  description: Internal revision number
219  returned: always
220  type: str
221  sample: "17.0.2.10658"
222serial:
223  description: Serial number of the unit
224  returned: always
225  type: str
226  sample: "FGVMEVYYQT3AB5352"
227status:
228  description: Indication of the operation's result
229  returned: always
230  type: str
231  sample: "success"
232vdom:
233  description: Virtual domain used
234  returned: always
235  type: str
236  sample: "root"
237version:
238  description: Version of the FortiGate
239  returned: always
240  type: str
241  sample: "v5.6.3"
242
243'''
244
245from ansible.module_utils.basic import AnsibleModule
246from ansible.module_utils.connection import Connection
247from ansible.module_utils.network.fortios.fortios import FortiOSHandler
248from ansible.module_utils.network.fortimanager.common import FAIL_SOCKET_MSG
249
250
251def login(data, fos):
252    host = data['host']
253    username = data['username']
254    password = data['password']
255    ssl_verify = data['ssl_verify']
256
257    fos.debug('on')
258    if 'https' in data and not data['https']:
259        fos.https('off')
260    else:
261        fos.https('on')
262
263    fos.login(host, username, password, verify=ssl_verify)
264
265
266def filter_wireless_controller_hotspot20_h2qp_osu_provider_data(json):
267    option_list = ['friendly_name', 'icon', 'name',
268                   'osu_method', 'osu_nai', 'server_uri',
269                   'service_description']
270    dictionary = {}
271
272    for attribute in option_list:
273        if attribute in json and json[attribute] is not None:
274            dictionary[attribute] = json[attribute]
275
276    return dictionary
277
278
279def underscore_to_hyphen(data):
280    if isinstance(data, list):
281        for elem in data:
282            elem = underscore_to_hyphen(elem)
283    elif isinstance(data, dict):
284        new_data = {}
285        for k, v in data.items():
286            new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
287        data = new_data
288
289    return data
290
291
292def wireless_controller_hotspot20_h2qp_osu_provider(data, fos):
293    vdom = data['vdom']
294    state = data['state']
295    wireless_controller_hotspot20_h2qp_osu_provider_data = data['wireless_controller_hotspot20_h2qp_osu_provider']
296    filtered_data = underscore_to_hyphen(filter_wireless_controller_hotspot20_h2qp_osu_provider_data(wireless_controller_hotspot20_h2qp_osu_provider_data))
297
298    if state == "present":
299        return fos.set('wireless-controller.hotspot20',
300                       'h2qp-osu-provider',
301                       data=filtered_data,
302                       vdom=vdom)
303
304    elif state == "absent":
305        return fos.delete('wireless-controller.hotspot20',
306                          'h2qp-osu-provider',
307                          mkey=filtered_data['name'],
308                          vdom=vdom)
309
310
311def is_successful_status(status):
312    return status['status'] == "success" or \
313        status['http_method'] == "DELETE" and status['http_status'] == 404
314
315
316def fortios_wireless_controller_hotspot20(data, fos):
317
318    if data['wireless_controller_hotspot20_h2qp_osu_provider']:
319        resp = wireless_controller_hotspot20_h2qp_osu_provider(data, fos)
320
321    return not is_successful_status(resp), \
322        resp['status'] == "success", \
323        resp
324
325
326def main():
327    fields = {
328        "host": {"required": False, "type": "str"},
329        "username": {"required": False, "type": "str"},
330        "password": {"required": False, "type": "str", "default": "", "no_log": True},
331        "vdom": {"required": False, "type": "str", "default": "root"},
332        "https": {"required": False, "type": "bool", "default": True},
333        "ssl_verify": {"required": False, "type": "bool", "default": True},
334        "state": {"required": True, "type": "str",
335                  "choices": ["present", "absent"]},
336        "wireless_controller_hotspot20_h2qp_osu_provider": {
337            "required": False, "type": "dict", "default": None,
338            "options": {
339                "friendly_name": {"required": False, "type": "list",
340                                  "options": {
341                                      "friendly_name": {"required": False, "type": "str"},
342                                      "index": {"required": True, "type": "int"},
343                                      "lang": {"required": False, "type": "str"}
344                                  }},
345                "icon": {"required": False, "type": "str"},
346                "name": {"required": True, "type": "str"},
347                "osu_method": {"required": False, "type": "str",
348                               "choices": ["oma-dm", "soap-xml-spp", "reserved"]},
349                "osu_nai": {"required": False, "type": "str"},
350                "server_uri": {"required": False, "type": "str"},
351                "service_description": {"required": False, "type": "list",
352                                        "options": {
353                                            "lang": {"required": False, "type": "str"},
354                                            "service_description": {"required": False, "type": "str"},
355                                            "service_id": {"required": False, "type": "int"}
356                                        }}
357
358            }
359        }
360    }
361
362    module = AnsibleModule(argument_spec=fields,
363                           supports_check_mode=False)
364
365    # legacy_mode refers to using fortiosapi instead of HTTPAPI
366    legacy_mode = 'host' in module.params and module.params['host'] is not None and \
367                  'username' in module.params and module.params['username'] is not None and \
368                  'password' in module.params and module.params['password'] is not None
369
370    if not legacy_mode:
371        if module._socket_path:
372            connection = Connection(module._socket_path)
373            fos = FortiOSHandler(connection)
374
375            is_error, has_changed, result = fortios_wireless_controller_hotspot20(module.params, fos)
376        else:
377            module.fail_json(**FAIL_SOCKET_MSG)
378    else:
379        try:
380            from fortiosapi import FortiOSAPI
381        except ImportError:
382            module.fail_json(msg="fortiosapi module is required")
383
384        fos = FortiOSAPI()
385
386        login(module.params, fos)
387        is_error, has_changed, result = fortios_wireless_controller_hotspot20(module.params, fos)
388        fos.logout()
389
390    if not is_error:
391        module.exit_json(changed=has_changed, meta=result)
392    else:
393        module.fail_json(msg="Error in repo", meta=result)
394
395
396if __name__ == '__main__':
397    main()
398