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_firewall_vip46 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_firewall_vip46.Connection') 35 return connection_class_mock 36 37 38fos_instance = FortiOSHandler(connection_mock) 39 40 41def test_firewall_vip46_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 'firewall_vip46': { 51 'arp_reply': 'disable', 52 'color': '4', 53 'comment': 'Comment.', 54 'extip': 'test_value_6', 55 'extport': 'test_value_7', 56 'id': '8', 57 'ldb_method': 'static', 58 'mappedip': 'test_value_10', 59 'mappedport': 'test_value_11', 60 'name': 'default_name_12', 61 'portforward': 'disable', 62 'protocol': 'tcp', 63 'server_type': 'http', 64 'type': 'static-nat', 65 'uuid': 'test_value_17' 66 }, 67 'vdom': 'root'} 68 69 is_error, changed, response = fortios_firewall_vip46.fortios_firewall(input_data, fos_instance) 70 71 expected_data = { 72 'arp-reply': 'disable', 73 'color': '4', 74 'comment': 'Comment.', 75 'extip': 'test_value_6', 76 'extport': 'test_value_7', 77 'id': '8', 78 'ldb-method': 'static', 79 'mappedip': 'test_value_10', 80 'mappedport': 'test_value_11', 81 'name': 'default_name_12', 82 'portforward': 'disable', 83 'protocol': 'tcp', 84 'server-type': 'http', 85 'type': 'static-nat', 86 'uuid': 'test_value_17' 87 } 88 89 set_method_mock.assert_called_with('firewall', 'vip46', data=expected_data, vdom='root') 90 schema_method_mock.assert_not_called() 91 assert not is_error 92 assert changed 93 assert response['status'] == 'success' 94 assert response['http_status'] == 200 95 96 97def test_firewall_vip46_creation_fails(mocker): 98 schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema') 99 100 set_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500} 101 set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result) 102 103 input_data = { 104 'username': 'admin', 105 'state': 'present', 106 'firewall_vip46': { 107 'arp_reply': 'disable', 108 'color': '4', 109 'comment': 'Comment.', 110 'extip': 'test_value_6', 111 'extport': 'test_value_7', 112 'id': '8', 113 'ldb_method': 'static', 114 'mappedip': 'test_value_10', 115 'mappedport': 'test_value_11', 116 'name': 'default_name_12', 117 'portforward': 'disable', 118 'protocol': 'tcp', 119 'server_type': 'http', 120 'type': 'static-nat', 121 'uuid': 'test_value_17' 122 }, 123 'vdom': 'root'} 124 125 is_error, changed, response = fortios_firewall_vip46.fortios_firewall(input_data, fos_instance) 126 127 expected_data = { 128 'arp-reply': 'disable', 129 'color': '4', 130 'comment': 'Comment.', 131 'extip': 'test_value_6', 132 'extport': 'test_value_7', 133 'id': '8', 134 'ldb-method': 'static', 135 'mappedip': 'test_value_10', 136 'mappedport': 'test_value_11', 137 'name': 'default_name_12', 138 'portforward': 'disable', 139 'protocol': 'tcp', 140 'server-type': 'http', 141 'type': 'static-nat', 142 'uuid': 'test_value_17' 143 } 144 145 set_method_mock.assert_called_with('firewall', 'vip46', data=expected_data, vdom='root') 146 schema_method_mock.assert_not_called() 147 assert is_error 148 assert not changed 149 assert response['status'] == 'error' 150 assert response['http_status'] == 500 151 152 153def test_firewall_vip46_removal(mocker): 154 schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema') 155 156 delete_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200} 157 delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result) 158 159 input_data = { 160 'username': 'admin', 161 'state': 'absent', 162 'firewall_vip46': { 163 'arp_reply': 'disable', 164 'color': '4', 165 'comment': 'Comment.', 166 'extip': 'test_value_6', 167 'extport': 'test_value_7', 168 'id': '8', 169 'ldb_method': 'static', 170 'mappedip': 'test_value_10', 171 'mappedport': 'test_value_11', 172 'name': 'default_name_12', 173 'portforward': 'disable', 174 'protocol': 'tcp', 175 'server_type': 'http', 176 'type': 'static-nat', 177 'uuid': 'test_value_17' 178 }, 179 'vdom': 'root'} 180 181 is_error, changed, response = fortios_firewall_vip46.fortios_firewall(input_data, fos_instance) 182 183 delete_method_mock.assert_called_with('firewall', 'vip46', mkey=ANY, vdom='root') 184 schema_method_mock.assert_not_called() 185 assert not is_error 186 assert changed 187 assert response['status'] == 'success' 188 assert response['http_status'] == 200 189 190 191def test_firewall_vip46_deletion_fails(mocker): 192 schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema') 193 194 delete_method_result = {'status': 'error', 'http_method': 'POST', 'http_status': 500} 195 delete_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.delete', return_value=delete_method_result) 196 197 input_data = { 198 'username': 'admin', 199 'state': 'absent', 200 'firewall_vip46': { 201 'arp_reply': 'disable', 202 'color': '4', 203 'comment': 'Comment.', 204 'extip': 'test_value_6', 205 'extport': 'test_value_7', 206 'id': '8', 207 'ldb_method': 'static', 208 'mappedip': 'test_value_10', 209 'mappedport': 'test_value_11', 210 'name': 'default_name_12', 211 'portforward': 'disable', 212 'protocol': 'tcp', 213 'server_type': 'http', 214 'type': 'static-nat', 215 'uuid': 'test_value_17' 216 }, 217 'vdom': 'root'} 218 219 is_error, changed, response = fortios_firewall_vip46.fortios_firewall(input_data, fos_instance) 220 221 delete_method_mock.assert_called_with('firewall', 'vip46', mkey=ANY, vdom='root') 222 schema_method_mock.assert_not_called() 223 assert is_error 224 assert not changed 225 assert response['status'] == 'error' 226 assert response['http_status'] == 500 227 228 229def test_firewall_vip46_idempotent(mocker): 230 schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema') 231 232 set_method_result = {'status': 'error', 'http_method': 'DELETE', 'http_status': 404} 233 set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result) 234 235 input_data = { 236 'username': 'admin', 237 'state': 'present', 238 'firewall_vip46': { 239 'arp_reply': 'disable', 240 'color': '4', 241 'comment': 'Comment.', 242 'extip': 'test_value_6', 243 'extport': 'test_value_7', 244 'id': '8', 245 'ldb_method': 'static', 246 'mappedip': 'test_value_10', 247 'mappedport': 'test_value_11', 248 'name': 'default_name_12', 249 'portforward': 'disable', 250 'protocol': 'tcp', 251 'server_type': 'http', 252 'type': 'static-nat', 253 'uuid': 'test_value_17' 254 }, 255 'vdom': 'root'} 256 257 is_error, changed, response = fortios_firewall_vip46.fortios_firewall(input_data, fos_instance) 258 259 expected_data = { 260 'arp-reply': 'disable', 261 'color': '4', 262 'comment': 'Comment.', 263 'extip': 'test_value_6', 264 'extport': 'test_value_7', 265 'id': '8', 266 'ldb-method': 'static', 267 'mappedip': 'test_value_10', 268 'mappedport': 'test_value_11', 269 'name': 'default_name_12', 270 'portforward': 'disable', 271 'protocol': 'tcp', 272 'server-type': 'http', 273 'type': 'static-nat', 274 'uuid': 'test_value_17' 275 } 276 277 set_method_mock.assert_called_with('firewall', 'vip46', data=expected_data, vdom='root') 278 schema_method_mock.assert_not_called() 279 assert not is_error 280 assert not changed 281 assert response['status'] == 'error' 282 assert response['http_status'] == 404 283 284 285def test_firewall_vip46_filter_foreign_attributes(mocker): 286 schema_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.schema') 287 288 set_method_result = {'status': 'success', 'http_method': 'POST', 'http_status': 200} 289 set_method_mock = mocker.patch('ansible.module_utils.network.fortios.fortios.FortiOSHandler.set', return_value=set_method_result) 290 291 input_data = { 292 'username': 'admin', 293 'state': 'present', 294 'firewall_vip46': { 295 'random_attribute_not_valid': 'tag', 296 'arp_reply': 'disable', 297 'color': '4', 298 'comment': 'Comment.', 299 'extip': 'test_value_6', 300 'extport': 'test_value_7', 301 'id': '8', 302 'ldb_method': 'static', 303 'mappedip': 'test_value_10', 304 'mappedport': 'test_value_11', 305 'name': 'default_name_12', 306 'portforward': 'disable', 307 'protocol': 'tcp', 308 'server_type': 'http', 309 'type': 'static-nat', 310 'uuid': 'test_value_17' 311 }, 312 'vdom': 'root'} 313 314 is_error, changed, response = fortios_firewall_vip46.fortios_firewall(input_data, fos_instance) 315 316 expected_data = { 317 'arp-reply': 'disable', 318 'color': '4', 319 'comment': 'Comment.', 320 'extip': 'test_value_6', 321 'extport': 'test_value_7', 322 'id': '8', 323 'ldb-method': 'static', 324 'mappedip': 'test_value_10', 325 'mappedport': 'test_value_11', 326 'name': 'default_name_12', 327 'portforward': 'disable', 328 'protocol': 'tcp', 329 'server-type': 'http', 330 'type': 'static-nat', 331 'uuid': 'test_value_17' 332 } 333 334 set_method_mock.assert_called_with('firewall', 'vip46', data=expected_data, vdom='root') 335 schema_method_mock.assert_not_called() 336 assert not is_error 337 assert changed 338 assert response['status'] == 'success' 339 assert response['http_status'] == 200 340