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_action
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_action.Connection')
35    return connection_class_mock
36
37
38fos_instance = FortiOSHandler(connection_mock)
39
40
41def test_system_automation_action_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_action': {
51            'action_type': 'email',
52            'aws_api_id': 'test_value_4',
53            'aws_api_key': 'test_value_5',
54            'aws_api_path': 'test_value_6',
55            'aws_api_stage': 'test_value_7',
56            'aws_domain': 'test_value_8',
57            'aws_region': 'test_value_9',
58            'delay': '10',
59            'email_subject': 'test_value_11',
60            'http_body': 'test_value_12',
61            'method': 'post',
62            'minimum_interval': '14',
63            'name': 'default_name_15',
64            'port': '16',
65            'protocol': 'http',
66            'required': 'enable',
67            'uri': 'test_value_19'
68        },
69        'vdom': 'root'}
70
71    is_error, changed, response = fortios_system_automation_action.fortios_system(input_data, fos_instance)
72
73    expected_data = {
74        'action-type': 'email',
75        'aws-api-id': 'test_value_4',
76        'aws-api-key': 'test_value_5',
77        'aws-api-path': 'test_value_6',
78        'aws-api-stage': 'test_value_7',
79        'aws-domain': 'test_value_8',
80        'aws-region': 'test_value_9',
81        'delay': '10',
82        'email-subject': 'test_value_11',
83        'http-body': 'test_value_12',
84        'method': 'post',
85        'minimum-interval': '14',
86        'name': 'default_name_15',
87                'port': '16',
88                'protocol': 'http',
89                'required': 'enable',
90                'uri': 'test_value_19'
91    }
92
93    set_method_mock.assert_called_with('system', 'automation-action', data=expected_data, vdom='root')
94    schema_method_mock.assert_not_called()
95    assert not is_error
96    assert changed
97    assert response['status'] == 'success'
98    assert response['http_status'] == 200
99
100
101def test_system_automation_action_creation_fails(mocker):
102    schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
103
104    set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
105    set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
106
107    input_data = {
108        'username': 'admin',
109        'state': 'present',
110        'system_automation_action': {
111            'action_type': 'email',
112            'aws_api_id': 'test_value_4',
113            'aws_api_key': 'test_value_5',
114            'aws_api_path': 'test_value_6',
115            'aws_api_stage': 'test_value_7',
116            'aws_domain': 'test_value_8',
117            'aws_region': 'test_value_9',
118            'delay': '10',
119            'email_subject': 'test_value_11',
120            'http_body': 'test_value_12',
121            'method': 'post',
122            'minimum_interval': '14',
123            'name': 'default_name_15',
124            'port': '16',
125            'protocol': 'http',
126            'required': 'enable',
127            'uri': 'test_value_19'
128        },
129        'vdom': 'root'}
130
131    is_error, changed, response = fortios_system_automation_action.fortios_system(input_data, fos_instance)
132
133    expected_data = {
134        'action-type': 'email',
135        'aws-api-id': 'test_value_4',
136        'aws-api-key': 'test_value_5',
137        'aws-api-path': 'test_value_6',
138        'aws-api-stage': 'test_value_7',
139        'aws-domain': 'test_value_8',
140        'aws-region': 'test_value_9',
141        'delay': '10',
142        'email-subject': 'test_value_11',
143        'http-body': 'test_value_12',
144        'method': 'post',
145        'minimum-interval': '14',
146        'name': 'default_name_15',
147                'port': '16',
148                'protocol': 'http',
149                'required': 'enable',
150                'uri': 'test_value_19'
151    }
152
153    set_method_mock.assert_called_with('system', 'automation-action', data=expected_data, vdom='root')
154    schema_method_mock.assert_not_called()
155    assert is_error
156    assert not changed
157    assert response['status'] == 'error'
158    assert response['http_status'] == 500
159
160
161def test_system_automation_action_removal(mocker):
162    schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
163
164    delete_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
165    delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
166
167    input_data = {
168        'username': 'admin',
169        'state': 'absent',
170        'system_automation_action': {
171            'action_type': 'email',
172            'aws_api_id': 'test_value_4',
173            'aws_api_key': 'test_value_5',
174            'aws_api_path': 'test_value_6',
175            'aws_api_stage': 'test_value_7',
176            'aws_domain': 'test_value_8',
177            'aws_region': 'test_value_9',
178            'delay': '10',
179            'email_subject': 'test_value_11',
180            'http_body': 'test_value_12',
181            'method': 'post',
182            'minimum_interval': '14',
183            'name': 'default_name_15',
184            'port': '16',
185            'protocol': 'http',
186            'required': 'enable',
187            'uri': 'test_value_19'
188        },
189        'vdom': 'root'}
190
191    is_error, changed, response = fortios_system_automation_action.fortios_system(input_data, fos_instance)
192
193    delete_method_mock.assert_called_with('system', 'automation-action', mkey=ANY, vdom='root')
194    schema_method_mock.assert_not_called()
195    assert not is_error
196    assert changed
197    assert response['status'] == 'success'
198    assert response['http_status'] == 200
199
200
201def test_system_automation_action_deletion_fails(mocker):
202    schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
203
204    delete_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500}
205    delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result)
206
207    input_data = {
208        'username': 'admin',
209        'state': 'absent',
210        'system_automation_action': {
211            'action_type': 'email',
212            'aws_api_id': 'test_value_4',
213            'aws_api_key': 'test_value_5',
214            'aws_api_path': 'test_value_6',
215            'aws_api_stage': 'test_value_7',
216            'aws_domain': 'test_value_8',
217            'aws_region': 'test_value_9',
218            'delay': '10',
219            'email_subject': 'test_value_11',
220            'http_body': 'test_value_12',
221            'method': 'post',
222            'minimum_interval': '14',
223            'name': 'default_name_15',
224            'port': '16',
225            'protocol': 'http',
226            'required': 'enable',
227            'uri': 'test_value_19'
228        },
229        'vdom': 'root'}
230
231    is_error, changed, response = fortios_system_automation_action.fortios_system(input_data, fos_instance)
232
233    delete_method_mock.assert_called_with('system', 'automation-action', mkey=ANY, vdom='root')
234    schema_method_mock.assert_not_called()
235    assert is_error
236    assert not changed
237    assert response['status'] == 'error'
238    assert response['http_status'] == 500
239
240
241def test_system_automation_action_idempotent(mocker):
242    schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
243
244    set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404}
245    set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
246
247    input_data = {
248        'username': 'admin',
249        'state': 'present',
250        'system_automation_action': {
251            'action_type': 'email',
252            'aws_api_id': 'test_value_4',
253            'aws_api_key': 'test_value_5',
254            'aws_api_path': 'test_value_6',
255            'aws_api_stage': 'test_value_7',
256            'aws_domain': 'test_value_8',
257            'aws_region': 'test_value_9',
258            'delay': '10',
259            'email_subject': 'test_value_11',
260            'http_body': 'test_value_12',
261            'method': 'post',
262            'minimum_interval': '14',
263            'name': 'default_name_15',
264            'port': '16',
265            'protocol': 'http',
266            'required': 'enable',
267            'uri': 'test_value_19'
268        },
269        'vdom': 'root'}
270
271    is_error, changed, response = fortios_system_automation_action.fortios_system(input_data, fos_instance)
272
273    expected_data = {
274        'action-type': 'email',
275        'aws-api-id': 'test_value_4',
276        'aws-api-key': 'test_value_5',
277        'aws-api-path': 'test_value_6',
278        'aws-api-stage': 'test_value_7',
279        'aws-domain': 'test_value_8',
280        'aws-region': 'test_value_9',
281        'delay': '10',
282        'email-subject': 'test_value_11',
283        'http-body': 'test_value_12',
284        'method': 'post',
285        'minimum-interval': '14',
286        'name': 'default_name_15',
287                'port': '16',
288                'protocol': 'http',
289                'required': 'enable',
290                'uri': 'test_value_19'
291    }
292
293    set_method_mock.assert_called_with('system', 'automation-action', data=expected_data, vdom='root')
294    schema_method_mock.assert_not_called()
295    assert not is_error
296    assert not changed
297    assert response['status'] == 'error'
298    assert response['http_status'] == 404
299
300
301def test_system_automation_action_filter_foreign_attributes(mocker):
302    schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema')
303
304    set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200}
305    set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result)
306
307    input_data = {
308        'username': 'admin',
309        'state': 'present',
310        'system_automation_action': {
311            'random_attribute_not_valid': 'tag',
312            'action_type': 'email',
313            'aws_api_id': 'test_value_4',
314            'aws_api_key': 'test_value_5',
315            'aws_api_path': 'test_value_6',
316            'aws_api_stage': 'test_value_7',
317            'aws_domain': 'test_value_8',
318            'aws_region': 'test_value_9',
319            'delay': '10',
320            'email_subject': 'test_value_11',
321            'http_body': 'test_value_12',
322            'method': 'post',
323            'minimum_interval': '14',
324            'name': 'default_name_15',
325            'port': '16',
326            'protocol': 'http',
327            'required': 'enable',
328            'uri': 'test_value_19'
329        },
330        'vdom': 'root'}
331
332    is_error, changed, response = fortios_system_automation_action.fortios_system(input_data, fos_instance)
333
334    expected_data = {
335        'action-type': 'email',
336        'aws-api-id': 'test_value_4',
337        'aws-api-key': 'test_value_5',
338        'aws-api-path': 'test_value_6',
339        'aws-api-stage': 'test_value_7',
340        'aws-domain': 'test_value_8',
341        'aws-region': 'test_value_9',
342        'delay': '10',
343        'email-subject': 'test_value_11',
344        'http-body': 'test_value_12',
345        'method': 'post',
346        'minimum-interval': '14',
347        'name': 'default_name_15',
348                'port': '16',
349                'protocol': 'http',
350                'required': 'enable',
351                'uri': 'test_value_19'
352    }
353
354    set_method_mock.assert_called_with('system', 'automation-action', data=expected_data, vdom='root')
355    schema_method_mock.assert_not_called()
356    assert not is_error
357    assert changed
358    assert response['status'] == 'success'
359    assert response['http_status'] == 200
360