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_offload 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        )
77
78        p = ModuleParameters(params=args)
79        assert p.name == 'foo'
80        assert p.config_set_name == 'foo'
81        assert p.sub_path == 'foo'
82        assert p.http_profile == 'profile_http'
83        assert p.service_environment == 'bar'
84        assert len(p.servers) == 2
85        assert 'address' in p.servers[0]
86        assert 'port' in p.servers[0]
87        assert 'address' in p.servers[1]
88        assert 'port' in p.servers[1]
89        assert p.servers[0]['address'] == '1.2.3.4'
90        assert p.servers[0]['port'] == 8080
91        assert p.servers[1]['address'] == '5.6.7.8'
92        assert p.servers[1]['port'] == 8000
93        assert 'address' in p.inbound_virtual
94        assert 'netmask' in p.inbound_virtual
95        assert 'port' in p.inbound_virtual
96        assert p.inbound_virtual['address'] == '2.2.2.2'
97        assert p.inbound_virtual['netmask'] == '255.255.255.255'
98        assert p.inbound_virtual['port'] == 80
99        assert 'address' in p.redirect_virtual
100        assert 'netmask' in p.redirect_virtual
101        assert 'port' in p.redirect_virtual
102        assert p.redirect_virtual['address'] == '3.3.3.3'
103        assert p.redirect_virtual['netmask'] == '255.255.255.255'
104        assert p.redirect_virtual['port'] == 80
105
106
107class TestManager(unittest.TestCase):
108    def setUp(self):
109        self.spec = ArgumentSpec()
110        self.patcher1 = patch('time.sleep')
111        self.patcher1.start()
112
113        self.p1 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigiq_application_https_offload.bigiq_version')
114        self.p2 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigiq_application_https_offload.ModuleParameters.template_reference')
115        self.p3 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigiq_application_https_offload.ModuleParameters.ssg_reference')
116        self.p4 = patch(
117            'ansible_collections.f5networks.f5_modules.plugins.modules.bigiq_application_https_offload.ModuleParameters.default_device_reference'
118        )
119
120        self.m1 = self.p1.start()
121        self.m2 = self.p2.start()
122        self.m3 = self.p3.start()
123        self.m4 = self.p4.start()
124
125        self.m1.return_value = '6.1.0'
126        self.m2.return_value = Mock(return_value='https://localhost/mgmt/foobar1')
127        self.m3.return_value = Mock(return_value='https://localhost/mgmt/foobar2')
128        self.m4.return_value = Mock(return_value='https://localhost/mgmt/foobar3')
129
130        self.p5 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigiq_application_https_offload.send_teem')
131        self.m5 = self.p5.start()
132        self.m5.return_value = True
133
134    def tearDown(self):
135        self.patcher1.stop()
136        self.p1.stop()
137        self.p2.stop()
138        self.p3.stop()
139        self.p4.stop()
140        self.p5.stop()
141
142    def test_create(self, *args):
143        set_module_args(dict(
144            name='foo',
145            description='my description',
146            service_environment='bar',
147            servers=[
148                dict(
149                    address='1.2.3.4',
150                    port=8080
151                ),
152                dict(
153                    address='5.6.7.8',
154                    port=8000
155                )
156            ],
157            inbound_virtual=dict(
158                address='2.2.2.2',
159                netmask='255.255.255.255',
160                port=80
161            ),
162            redirect_virtual=dict(
163                address='3.3.3.3',
164                netmask='255.255.255.255',
165                port=80
166            ),
167            provider=dict(
168                server='localhost',
169                password='password',
170                user='admin'
171            )
172        ))
173
174        module = AnsibleModule(
175            argument_spec=self.spec.argument_spec,
176            supports_check_mode=self.spec.supports_check_mode,
177        )
178
179        # Override methods to force specific logic in the module to happen
180        mm = ModuleManager(module=module)
181        mm.check_bigiq_version = Mock(return_value=True)
182        mm.has_no_service_environment = Mock(return_value=False)
183        mm.wait_for_apply_template_task = Mock(return_value=True)
184
185        mm.create_on_device = Mock(return_value=True)
186        mm.exists = Mock(side_effect=[False, True])
187
188        results = mm.exec_module()
189
190        assert results['changed'] is True
191        assert results['description'] == 'my description'
192
193    def test_bigiq_version_raises(self):
194        set_module_args(dict(
195            name='foo',
196            description='my description',
197            service_environment='bar',
198            servers=[
199                dict(
200                    address='1.2.3.4',
201                    port=8080
202                ),
203                dict(
204                    address='5.6.7.8',
205                    port=8000
206                )
207            ],
208            inbound_virtual=dict(
209                address='2.2.2.2',
210                netmask='255.255.255.255',
211                port=80
212            ),
213            provider=dict(
214                server='localhost',
215                password='password',
216                user='admin'
217            )
218        ))
219
220        module = AnsibleModule(
221            argument_spec=self.spec.argument_spec,
222            supports_check_mode=self.spec.supports_check_mode,
223        )
224
225        msg = 'Module supports only BIGIQ version 6.0.x or lower.'
226        # Override methods to force specific logic in the module to happen
227        mm = ModuleManager(module=module)
228
229        with pytest.raises(F5ModuleError) as err:
230            mm.exec_module()
231        assert str(err.value) == msg
232