1# -*- coding: utf-8 -*-
2#
3# Copyright: (c) 2017, F5 Networks Inc.
4# GNU General Public License v3.0 (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
5
6from __future__ import (absolute_import, division, print_function)
7__metaclass__ = type
8
9import os
10import json
11import pytest
12import sys
13
14if sys.version_info < (2, 7):
15    pytestmark = pytest.mark.skip("F5 Ansible modules require Python >= 2.7")
16
17from ansible.module_utils.basic import AnsibleModule
18
19from ansible_collections.f5networks.f5_modules.plugins.modules.bigiq_application_https_waf import (
20    ModuleParameters, ModuleManager, ArgumentSpec
21)
22from ansible_collections.f5networks.f5_modules.plugins.module_utils.common import F5ModuleError
23from ansible_collections.f5networks.f5_modules.tests.unit.compat import unittest
24from ansible_collections.f5networks.f5_modules.tests.unit.compat.mock import Mock, patch
25from ansible_collections.f5networks.f5_modules.tests.unit.modules.utils import set_module_args
26
27
28fixture_path = os.path.join(os.path.dirname(__file__), 'fixtures')
29fixture_data = {}
30
31
32def load_fixture(name):
33    path = os.path.join(fixture_path, name)
34
35    if path in fixture_data:
36        return fixture_data[path]
37
38    with open(path) as f:
39        data = f.read()
40
41    try:
42        data = json.loads(data)
43    except Exception:
44        pass
45
46    fixture_data[path] = data
47    return data
48
49
50class TestParameters(unittest.TestCase):
51    def test_module_parameters(self):
52        args = dict(
53            name='foo',
54            description='my description',
55            service_environment='bar',
56            servers=[
57                dict(
58                    address='1.2.3.4',
59                    port=8080
60                ),
61                dict(
62                    address='5.6.7.8',
63                    port=8000
64                )
65            ],
66            inbound_virtual=dict(
67                address='2.2.2.2',
68                netmask='255.255.255.255',
69                port=80
70            ),
71            redirect_virtual=dict(
72                address='3.3.3.3',
73                netmask='255.255.255.255',
74                port=80
75            ),
76            domain_names=[
77                'foo.baz.com',
78                'bar.baz.com'
79            ]
80        )
81
82        p = ModuleParameters(params=args)
83        assert p.name == 'foo'
84        assert p.config_set_name == 'foo'
85        assert p.sub_path == 'foo'
86        assert p.http_profile == 'profile_http'
87        assert p.service_environment == 'bar'
88        assert len(p.servers) == 2
89        assert 'address' in p.servers[0]
90        assert 'port' in p.servers[0]
91        assert 'address' in p.servers[1]
92        assert 'port' in p.servers[1]
93        assert p.servers[0]['address'] == '1.2.3.4'
94        assert p.servers[0]['port'] == 8080
95        assert p.servers[1]['address'] == '5.6.7.8'
96        assert p.servers[1]['port'] == 8000
97        assert 'address' in p.inbound_virtual
98        assert 'netmask' in p.inbound_virtual
99        assert 'port' in p.inbound_virtual
100        assert p.inbound_virtual['address'] == '2.2.2.2'
101        assert p.inbound_virtual['netmask'] == '255.255.255.255'
102        assert p.inbound_virtual['port'] == 80
103        assert 'address' in p.redirect_virtual
104        assert 'netmask' in p.redirect_virtual
105        assert 'port' in p.redirect_virtual
106        assert p.redirect_virtual['address'] == '3.3.3.3'
107        assert p.redirect_virtual['netmask'] == '255.255.255.255'
108        assert p.redirect_virtual['port'] == 80
109
110
111class TestManager(unittest.TestCase):
112    def setUp(self):
113        self.spec = ArgumentSpec()
114        self.patcher1 = patch('time.sleep')
115        self.patcher1.start()
116
117        self.p1 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigiq_application_https_waf.bigiq_version')
118        self.p2 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigiq_application_https_waf.ModuleParameters.template_reference')
119        self.p3 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigiq_application_https_waf.ModuleParameters.ssg_reference')
120        self.p4 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigiq_application_https_waf.ModuleParameters.default_device_reference')
121
122        self.m1 = self.p1.start()
123        self.m2 = self.p2.start()
124        self.m3 = self.p3.start()
125        self.m4 = self.p4.start()
126
127        self.m1.return_value = '6.1.0'
128        self.m2.return_value = Mock(return_value='https://localhost/mgmt/foobar1')
129        self.m3.return_value = Mock(return_value='https://localhost/mgmt/foobar2')
130        self.m4.return_value = Mock(return_value='https://localhost/mgmt/foobar3')
131
132        self.p5 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigiq_application_https_waf.send_teem')
133        self.m5 = self.p5.start()
134        self.m5.return_value = True
135
136    def tearDown(self):
137        self.patcher1.stop()
138        self.p1.stop()
139        self.p2.stop()
140        self.p3.stop()
141        self.p4.stop()
142        self.p5.stop()
143
144    def test_create(self, *args):
145        set_module_args(dict(
146            name='foo',
147            description='my description',
148            service_environment='bar',
149            servers=[
150                dict(
151                    address='1.2.3.4',
152                    port=8080
153                ),
154                dict(
155                    address='5.6.7.8',
156                    port=8000
157                )
158            ],
159            inbound_virtual=dict(
160                address='2.2.2.2',
161                netmask='255.255.255.255',
162                port=80
163            ),
164            redirect_virtual=dict(
165                address='3.3.3.3',
166                netmask='255.255.255.255',
167                port=80
168            ),
169            domain_names=[
170                'foo.baz.com',
171                'bar.baz.com'
172            ],
173            provider=dict(
174                server='localhost',
175                password='password',
176                user='admin'
177            )
178        ))
179
180        module = AnsibleModule(
181            argument_spec=self.spec.argument_spec,
182            supports_check_mode=self.spec.supports_check_mode,
183        )
184
185        # Override methods to force specific logic in the module to happen
186        mm = ModuleManager(module=module)
187        mm.check_bigiq_version = Mock(return_value=True)
188        mm.has_no_service_environment = Mock(return_value=False)
189        mm.wait_for_apply_template_task = Mock(return_value=True)
190
191        mm.create_on_device = Mock(return_value=True)
192        mm.exists = Mock(side_effect=[False, True])
193
194        results = mm.exec_module()
195
196        assert results['changed'] is True
197        assert results['description'] == 'my description'
198
199    def test_bigiq_version_raises(self):
200        set_module_args(dict(
201            name='foo',
202            description='my description',
203            service_environment='bar',
204            servers=[
205                dict(
206                    address='1.2.3.4',
207                    port=8080
208                ),
209                dict(
210                    address='5.6.7.8',
211                    port=8000
212                )
213            ],
214            inbound_virtual=dict(
215                address='2.2.2.2',
216                netmask='255.255.255.255',
217                port=80
218            ),
219            provider=dict(
220                server='localhost',
221                password='password',
222                user='admin'
223            )
224        ))
225
226        module = AnsibleModule(
227            argument_spec=self.spec.argument_spec,
228            supports_check_mode=self.spec.supports_check_mode,
229        )
230
231        msg = 'Module supports only BIGIQ version 6.0.x or lower.'
232        # Override methods to force specific logic in the module to happen
233        mm = ModuleManager(module=module)
234
235        with pytest.raises(F5ModuleError) as err:
236            mm.exec_module()
237        assert str(err.value) == msg
238