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_monitoring_npu_hpe
27short_description: Configure npu-hpe status monitoring 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 monitoring feature and npu_hpe 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    monitoring_npu_hpe:
68        description:
69            - Configure npu-hpe status monitoring.
70        default: null
71        type: dict
72        suboptions:
73            interval:
74                description:
75                    - HPE status check interval (1 - 60 seconds).
76                type: int
77            multipliers:
78                description:
79                    - HPE type interval multipliers (12 integers from <1> to <255>) number of continuous event logs.
80                type: str
81            status:
82                description:
83                    - Enable/disable HPE status monitoring.
84                type: str
85                choices:
86                    - enable
87                    - disable
88'''
89
90EXAMPLES = '''
91- hosts: fortigates
92  collections:
93    - fortinet.fortios
94  connection: httpapi
95  vars:
96   vdom: "root"
97   ansible_httpapi_use_ssl: yes
98   ansible_httpapi_validate_certs: no
99   ansible_httpapi_port: 443
100  tasks:
101  - name: Configure npu-hpe status monitoring.
102    fortios_monitoring_npu_hpe:
103      vdom:  "{{ vdom }}"
104      monitoring_npu_hpe:
105        interval: "3"
106        multipliers: "<your_own_value>"
107        status: "enable"
108
109'''
110
111RETURN = '''
112build:
113  description: Build number of the fortigate image
114  returned: always
115  type: str
116  sample: '1547'
117http_method:
118  description: Last method used to provision the content into FortiGate
119  returned: always
120  type: str
121  sample: 'PUT'
122http_status:
123  description: Last result given by FortiGate on last operation applied
124  returned: always
125  type: str
126  sample: "200"
127mkey:
128  description: Master key (id) used in the last call to FortiGate
129  returned: success
130  type: str
131  sample: "id"
132name:
133  description: Name of the table used to fulfill the request
134  returned: always
135  type: str
136  sample: "urlfilter"
137path:
138  description: Path of the table used to fulfill the request
139  returned: always
140  type: str
141  sample: "webfilter"
142revision:
143  description: Internal revision number
144  returned: always
145  type: str
146  sample: "17.0.2.10658"
147serial:
148  description: Serial number of the unit
149  returned: always
150  type: str
151  sample: "FGVMEVYYQT3AB5352"
152status:
153  description: Indication of the operation's result
154  returned: always
155  type: str
156  sample: "success"
157vdom:
158  description: Virtual domain used
159  returned: always
160  type: str
161  sample: "root"
162version:
163  description: Version of the FortiGate
164  returned: always
165  type: str
166  sample: "v5.6.3"
167
168'''
169from ansible.module_utils.basic import AnsibleModule
170from ansible.module_utils.connection import Connection
171from ansible_collections.fortinet.fortios.plugins.module_utils.fortios.fortios import FortiOSHandler
172from ansible_collections.fortinet.fortios.plugins.module_utils.fortios.fortios import check_legacy_fortiosapi
173from ansible_collections.fortinet.fortios.plugins.module_utils.fortios.fortios import schema_to_module_spec
174from ansible_collections.fortinet.fortios.plugins.module_utils.fortios.fortios import check_schema_versioning
175from ansible_collections.fortinet.fortios.plugins.module_utils.fortimanager.common import FAIL_SOCKET_MSG
176from ansible_collections.fortinet.fortios.plugins.module_utils.fortios.comparison import is_same_comparison
177from ansible_collections.fortinet.fortios.plugins.module_utils.fortios.comparison import serialize
178
179
180def filter_monitoring_npu_hpe_data(json):
181    option_list = ['interval', 'multipliers', 'status']
182    dictionary = {}
183
184    for attribute in option_list:
185        if attribute in json and json[attribute] is not None:
186            dictionary[attribute] = json[attribute]
187
188    return dictionary
189
190
191def underscore_to_hyphen(data):
192    if isinstance(data, list):
193        for i, elem in enumerate(data):
194            data[i] = underscore_to_hyphen(elem)
195    elif isinstance(data, dict):
196        new_data = {}
197        for k, v in data.items():
198            new_data[k.replace('_', '-')] = underscore_to_hyphen(v)
199        data = new_data
200
201    return data
202
203
204def monitoring_npu_hpe(data, fos):
205    vdom = data['vdom']
206    monitoring_npu_hpe_data = data['monitoring_npu_hpe']
207    filtered_data = underscore_to_hyphen(filter_monitoring_npu_hpe_data(monitoring_npu_hpe_data))
208
209    return fos.set('monitoring',
210                   'npu-hpe',
211                   data=filtered_data,
212                   vdom=vdom)
213
214
215def is_successful_status(status):
216    return status['status'] == "success" or \
217        status['http_method'] == "DELETE" and status['http_status'] == 404
218
219
220def fortios_monitoring(data, fos):
221
222    if data['monitoring_npu_hpe']:
223        resp = monitoring_npu_hpe(data, fos)
224    else:
225        fos._module.fail_json(msg='missing task body: %s' % ('monitoring_npu_hpe'))
226
227    return not is_successful_status(resp), \
228        resp['status'] == "success" and \
229        (resp['revision_changed'] if 'revision_changed' in resp else True), \
230        resp
231
232
233versioned_schema = {
234    "type": "dict",
235    "children": {
236        "status": {
237            "type": "string",
238            "options": [
239                {
240                    "value": "enable",
241                    "revisions": {
242                        "v7.0.0": True
243                    }
244                },
245                {
246                    "value": "disable",
247                    "revisions": {
248                        "v7.0.0": True
249                    }
250                }
251            ],
252            "revisions": {
253                "v7.0.0": True
254            }
255        },
256        "interval": {
257            "type": "integer",
258            "revisions": {
259                "v7.0.0": True
260            }
261        },
262        "multipliers": {
263            "type": "string",
264            "revisions": {
265                "v7.0.0": True
266            }
267        }
268    },
269    "revisions": {
270        "v7.0.0": True
271    }
272}
273
274
275def main():
276    module_spec = schema_to_module_spec(versioned_schema)
277    mkeyname = None
278    fields = {
279        "access_token": {"required": False, "type": "str", "no_log": True},
280        "enable_log": {"required": False, "type": bool},
281        "vdom": {"required": False, "type": "str", "default": "root"},
282        "monitoring_npu_hpe": {
283            "required": False, "type": "dict", "default": None,
284            "options": {
285            }
286        }
287    }
288    for attribute_name in module_spec['options']:
289        fields["monitoring_npu_hpe"]['options'][attribute_name] = module_spec['options'][attribute_name]
290        if mkeyname and mkeyname == attribute_name:
291            fields["monitoring_npu_hpe"]['options'][attribute_name]['required'] = True
292
293    check_legacy_fortiosapi()
294    module = AnsibleModule(argument_spec=fields,
295                           supports_check_mode=False)
296
297    versions_check_result = None
298    if module._socket_path:
299        connection = Connection(module._socket_path)
300        if 'access_token' in module.params:
301            connection.set_option('access_token', module.params['access_token'])
302
303        if 'enable_log' in module.params:
304            connection.set_option('enable_log', module.params['enable_log'])
305        else:
306            connection.set_option('enable_log', False)
307        fos = FortiOSHandler(connection, module, mkeyname)
308        versions_check_result = check_schema_versioning(fos, versioned_schema, "monitoring_npu_hpe")
309
310        is_error, has_changed, result = fortios_monitoring(module.params, fos)
311
312    else:
313        module.fail_json(**FAIL_SOCKET_MSG)
314
315    if versions_check_result and versions_check_result['matched'] is False:
316        module.warn("Ansible has detected version mismatch between FortOS system and your playbook, see more details by specifying option -vvv")
317
318    if not is_error:
319        if versions_check_result and versions_check_result['matched'] is False:
320            module.exit_json(changed=has_changed, version_check_warning=versions_check_result, meta=result)
321        else:
322            module.exit_json(changed=has_changed, meta=result)
323    else:
324        if versions_check_result and versions_check_result['matched'] is False:
325            module.fail_json(msg="Error in repo", version_check_warning=versions_check_result, meta=result)
326        else:
327            module.fail_json(msg="Error in repo", meta=result)
328
329
330if __name__ == '__main__':
331    main()
332