1# Copyright 2019 Fortinet, Inc.
2#
3# This program is free software: you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation, either version 3 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with Ansible.  If not, see <https://www.gnu.org/licenses/>.
15
16# Make coding more python3-ish
17from __future__ import (absolute_import, division, print_function)
18__metaclass__ = type
19
20import os
21import json
22import pytest
23from mock import ANY
24from ansible.module_utils.network.fortios.fortios import FortiOSHandler
25
26try:
27    from ansible.modules.network.fortios import fortios_system_automation_trigger
28except ImportError:
29    pytest.skip("Could not load required modules for testing", allow_module_level=True)
30
31
32@pytest.fixture(autouse=True)
33def connection_mock(mocker):
34    connection_class_mock = mocker.patch('ansible.modules.network.fortios.fortios_system_automation_trigger.Connection')
35    return connection_class_mock
36
37
38fos_instance = FortiOSHandler(connection_mock)
39
40
41def test_system_automation_trigger_creation(mocker):
42    schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
43
44    set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
45    set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
46
47    input_data = {
48        'username': 'admin',
49        'state': 'present',
50        'system_automation_trigger': {
51            'event_type': 'ioc',
52            'ioc_level': 'medium',
53            'license_type': 'forticare-support',
54            'logid': '6',
55            'name': 'default_name_7',
56            'trigger_day': '8',
57            'trigger_frequency': 'hourly',
58            'trigger_hour': '10',
59            'trigger_minute': '11',
60            'trigger_type': 'event-based',
61            'trigger_weekday': 'sunday'
62        },
63        'vdom': 'root'}
64
65    is_error, changed, response = fortios_system_automation_trigger.fortios_system(input_data, fos_instance)
66
67    expected_data = {
68        'event-type': 'ioc',
69        'ioc-level': 'medium',
70        'license-type': 'forticare-support',
71        'logid': '6',
72        'name': 'default_name_7',
73                'trigger-day': '8',
74                'trigger-frequency': 'hourly',
75                'trigger-hour': '10',
76                'trigger-minute': '11',
77                'trigger-type': 'event-based',
78                'trigger-weekday': 'sunday'
79    }
80
81    set_method_mock.assert_called_with('system', 'automation-trigger', data=expected_data, vdom='root')
82    schema_method_mock.assert_not_called()
83    assert not is_error
84    assert changed
85    assert response['status'] == 'success'
86    assert response['http_status'] == 200
87
88
89def test_system_automation_trigger_creation_fails(mocker):
90    schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
91
92    set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
93    set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
94
95    input_data = {
96        'username': 'admin',
97        'state': 'present',
98        'system_automation_trigger': {
99            'event_type': 'ioc',
100            'ioc_level': 'medium',
101            'license_type': 'forticare-support',
102            'logid': '6',
103            'name': 'default_name_7',
104            'trigger_day': '8',
105            'trigger_frequency': 'hourly',
106            'trigger_hour': '10',
107            'trigger_minute': '11',
108            'trigger_type': 'event-based',
109            'trigger_weekday': 'sunday'
110        },
111        'vdom': 'root'}
112
113    is_error, changed, response = fortios_system_automation_trigger.fortios_system(input_data, fos_instance)
114
115    expected_data = {
116        'event-type': 'ioc',
117        'ioc-level': 'medium',
118        'license-type': 'forticare-support',
119        'logid': '6',
120        'name': 'default_name_7',
121                'trigger-day': '8',
122                'trigger-frequency': 'hourly',
123                'trigger-hour': '10',
124                'trigger-minute': '11',
125                'trigger-type': 'event-based',
126                'trigger-weekday': 'sunday'
127    }
128
129    set_method_mock.assert_called_with('system', 'automation-trigger', data=expected_data, vdom='root')
130    schema_method_mock.assert_not_called()
131    assert is_error
132    assert not changed
133    assert response['status'] == 'error'
134    assert response['http_status'] == 500
135
136
137def test_system_automation_trigger_removal(mocker):
138    schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
139
140    delete_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
141    delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
142
143    input_data = {
144        'username': 'admin',
145        'state': 'absent',
146        'system_automation_trigger': {
147            'event_type': 'ioc',
148            'ioc_level': 'medium',
149            'license_type': 'forticare-support',
150            'logid': '6',
151            'name': 'default_name_7',
152            'trigger_day': '8',
153            'trigger_frequency': 'hourly',
154            'trigger_hour': '10',
155            'trigger_minute': '11',
156            'trigger_type': 'event-based',
157            'trigger_weekday': 'sunday'
158        },
159        'vdom': 'root'}
160
161    is_error, changed, response = fortios_system_automation_trigger.fortios_system(input_data, fos_instance)
162
163    delete_method_mock.assert_called_with('system', 'automation-trigger', mkey=ANY, vdom='root')
164    schema_method_mock.assert_not_called()
165    assert not is_error
166    assert changed
167    assert response['status'] == 'success'
168    assert response['http_status'] == 200
169
170
171def test_system_automation_trigger_deletion_fails(mocker):
172    schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
173
174    delete_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
175    delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
176
177    input_data = {
178        'username': 'admin',
179        'state': 'absent',
180        'system_automation_trigger': {
181            'event_type': 'ioc',
182            'ioc_level': 'medium',
183            'license_type': 'forticare-support',
184            'logid': '6',
185            'name': 'default_name_7',
186            'trigger_day': '8',
187            'trigger_frequency': 'hourly',
188            'trigger_hour': '10',
189            'trigger_minute': '11',
190            'trigger_type': 'event-based',
191            'trigger_weekday': 'sunday'
192        },
193        'vdom': 'root'}
194
195    is_error, changed, response = fortios_system_automation_trigger.fortios_system(input_data, fos_instance)
196
197    delete_method_mock.assert_called_with('system', 'automation-trigger', mkey=ANY, vdom='root')
198    schema_method_mock.assert_not_called()
199    assert is_error
200    assert not changed
201    assert response['status'] == 'error'
202    assert response['http_status'] == 500
203
204
205def test_system_automation_trigger_idempotent(mocker):
206    schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
207
208    set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
209    set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
210
211    input_data = {
212        'username': 'admin',
213        'state': 'present',
214        'system_automation_trigger': {
215            'event_type': 'ioc',
216            'ioc_level': 'medium',
217            'license_type': 'forticare-support',
218            'logid': '6',
219            'name': 'default_name_7',
220            'trigger_day': '8',
221            'trigger_frequency': 'hourly',
222            'trigger_hour': '10',
223            'trigger_minute': '11',
224            'trigger_type': 'event-based',
225            'trigger_weekday': 'sunday'
226        },
227        'vdom': 'root'}
228
229    is_error, changed, response = fortios_system_automation_trigger.fortios_system(input_data, fos_instance)
230
231    expected_data = {
232        'event-type': 'ioc',
233        'ioc-level': 'medium',
234        'license-type': 'forticare-support',
235        'logid': '6',
236        'name': 'default_name_7',
237                'trigger-day': '8',
238                'trigger-frequency': 'hourly',
239                'trigger-hour': '10',
240                'trigger-minute': '11',
241                'trigger-type': 'event-based',
242                'trigger-weekday': 'sunday'
243    }
244
245    set_method_mock.assert_called_with('system', 'automation-trigger', data=expected_data, vdom='root')
246    schema_method_mock.assert_not_called()
247    assert not is_error
248    assert not changed
249    assert response['status'] == 'error'
250    assert response['http_status'] == 404
251
252
253def test_system_automation_trigger_filter_foreign_attributes(mocker):
254    schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
255
256    set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
257    set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
258
259    input_data = {
260        'username': 'admin',
261        'state': 'present',
262        'system_automation_trigger': {
263            'random_attribute_not_valid': 'tag',
264            'event_type': 'ioc',
265            'ioc_level': 'medium',
266            'license_type': 'forticare-support',
267            'logid': '6',
268            'name': 'default_name_7',
269            'trigger_day': '8',
270            'trigger_frequency': 'hourly',
271            'trigger_hour': '10',
272            'trigger_minute': '11',
273            'trigger_type': 'event-based',
274            'trigger_weekday': 'sunday'
275        },
276        'vdom': 'root'}
277
278    is_error, changed, response = fortios_system_automation_trigger.fortios_system(input_data, fos_instance)
279
280    expected_data = {
281        'event-type': 'ioc',
282        'ioc-level': 'medium',
283        'license-type': 'forticare-support',
284        'logid': '6',
285        'name': 'default_name_7',
286                'trigger-day': '8',
287                'trigger-frequency': 'hourly',
288                'trigger-hour': '10',
289                'trigger-minute': '11',
290                'trigger-type': 'event-based',
291                'trigger-weekday': 'sunday'
292    }
293
294    set_method_mock.assert_called_with('system', 'automation-trigger', data=expected_data, vdom='root')
295    schema_method_mock.assert_not_called()
296    assert not is_error
297    assert changed
298    assert response['status'] == 'success'
299    assert response['http_status'] == 200
300