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.bigip_ucs import (
20    ModuleParameters, ModuleManager, ArgumentSpec, V1Manager, V2Manager
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            ucs="/root/bigip.localhost.localdomain.ucs",
54            force=True,
55            include_chassis_level_config=True,
56            no_license=True,
57            no_platform_check=True,
58            passphrase="foobar",
59            reset_trust=True,
60            state='installed'
61        )
62
63        p = ModuleParameters(params=args)
64        assert p.ucs == '/root/bigip.localhost.localdomain.ucs'
65        assert p.force is True
66        assert p.include_chassis_level_config is True
67        assert p.no_license is True
68        assert p.no_platform_check is True
69        assert p.passphrase == "foobar"
70        assert p.reset_trust is True
71        assert p.install_command == \
72            "tmsh load sys ucs /var/local/ucs/bigip.localhost.localdomain.ucs " \
73            "include-chassis-level-config no-license no-platform-check " \
74            "passphrase foobar reset-trust"
75
76    def test_module_parameters_false_ucs_booleans(self):
77        args = dict(
78            ucs="/root/bigip.localhost.localdomain.ucs",
79            include_chassis_level_config=False,
80            no_license=False,
81            no_platform_check=False,
82            reset_trust=False
83        )
84
85        p = ModuleParameters(params=args)
86        assert p.ucs == '/root/bigip.localhost.localdomain.ucs'
87        assert p.include_chassis_level_config is False
88        assert p.no_license is False
89        assert p.no_platform_check is False
90        assert p.reset_trust is False
91        assert p.install_command == "tmsh load sys ucs /var/local/ucs/bigip.localhost.localdomain.ucs"
92
93
94class TestV1Manager(unittest.TestCase):
95    def setUp(self):
96        self.spec = ArgumentSpec()
97        self.patcher1 = patch('time.sleep')
98        self.patcher1.start()
99        self.p2 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigip_ucs.tmos_version')
100        self.p3 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigip_ucs.send_teem')
101        self.m2 = self.p2.start()
102        self.m2.return_value = '12.1.0'
103        self.m3 = self.p3.start()
104        self.m3.return_value = True
105
106    def tearDown(self):
107        self.p2.stop()
108        self.p3.stop()
109        self.patcher1.stop()
110
111    def test_ucs_default_present(self, *args):
112        set_module_args(dict(
113            ucs="/root/bigip.localhost.localdomain.ucs",
114            provider=dict(
115                server='localhost',
116                password='password',
117                user='admin'
118            )
119        ))
120
121        module = AnsibleModule(
122            argument_spec=self.spec.argument_spec,
123            supports_check_mode=self.spec.supports_check_mode
124        )
125
126        # Override methods to force specific logic in the module to happen
127        mm = ModuleManager(module=module)
128        mm.is_version_v1 = Mock(return_value=True)
129
130        vm = V1Manager(module=module)
131        vm.create_on_device = Mock(return_value=True)
132        vm.exists = Mock(side_effect=[False, True])
133
134        results = vm.exec_module()
135
136        assert results['changed'] is True
137
138    def test_ucs_explicit_present(self, *args):
139        set_module_args(dict(
140            ucs="/root/bigip.localhost.localdomain.ucs",
141            state='present',
142            provider=dict(
143                server='localhost',
144                password='password',
145                user='admin'
146            )
147        ))
148
149        module = AnsibleModule(
150            argument_spec=self.spec.argument_spec,
151            supports_check_mode=self.spec.supports_check_mode
152        )
153
154        # Override methods to force specific logic in the module to happen
155        mm = ModuleManager(module=module)
156        mm.is_version_v1 = Mock(return_value=True)
157
158        vm = V1Manager(module=module)
159        vm.create_on_device = Mock(return_value=True)
160        vm.exists = Mock(side_effect=[False, True])
161
162        results = vm.exec_module()
163
164        assert results['changed'] is True
165
166    def test_ucs_installed(self, *args):
167        set_module_args(dict(
168            ucs="/root/bigip.localhost.localdomain.ucs",
169            state='installed',
170            provider=dict(
171                server='localhost',
172                password='password',
173                user='admin'
174            )
175        ))
176
177        module = AnsibleModule(
178            argument_spec=self.spec.argument_spec,
179            supports_check_mode=self.spec.supports_check_mode
180        )
181
182        # Override methods to force specific logic in the module to happen
183        mm = ModuleManager(module=module)
184        mm.is_version_v1 = Mock(return_value=True)
185
186        vm = V1Manager(module=module)
187        vm.create_on_device = Mock(return_value=True)
188        vm.exists = Mock(return_value=True)
189        vm.install_on_device = Mock(return_value=True)
190
191        results = vm.exec_module()
192
193        assert results['changed'] is True
194
195    def test_ucs_absent_exists(self, *args):
196        set_module_args(dict(
197            ucs="/root/bigip.localhost.localdomain.ucs",
198            state='absent',
199            provider=dict(
200                server='localhost',
201                password='password',
202                user='admin'
203            )
204        ))
205
206        module = AnsibleModule(
207            argument_spec=self.spec.argument_spec,
208            supports_check_mode=self.spec.supports_check_mode
209        )
210
211        # Override methods to force specific logic in the module to happen
212        mm = ModuleManager(module=module)
213        mm.is_version_v1 = Mock(return_value=True)
214
215        vm = V1Manager(module=module)
216        vm.remove_from_device = Mock(return_value=True)
217        vm.exists = Mock(side_effect=[True, False])
218
219        results = vm.exec_module()
220
221        assert results['changed'] is True
222
223    def test_ucs_absent_fails(self, *args):
224        set_module_args(dict(
225            ucs="/root/bigip.localhost.localdomain.ucs",
226            state='absent',
227            provider=dict(
228                server='localhost',
229                password='password',
230                user='admin'
231            )
232        ))
233
234        module = AnsibleModule(
235            argument_spec=self.spec.argument_spec,
236            supports_check_mode=self.spec.supports_check_mode
237        )
238
239        # Override methods to force specific logic in the module to happen
240        mm = ModuleManager(module=module)
241        mm.is_version_v1 = Mock(return_value=True)
242
243        vm = V1Manager(module=module)
244        vm.remove_from_device = Mock(return_value=True)
245        vm.exists = Mock(side_effect=[True, True])
246
247        with pytest.raises(F5ModuleError) as ex:
248            vm.exec_module()
249        assert 'Failed to delete' in str(ex.value)
250
251
252class TestV2Manager(unittest.TestCase):
253    def setUp(self):
254        self.spec = ArgumentSpec()
255        self.patcher1 = patch('time.sleep')
256        self.patcher1.start()
257        self.p2 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigip_ucs.tmos_version')
258        self.p3 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigip_ucs.send_teem')
259        self.m2 = self.p2.start()
260        self.m2.return_value = '14.1.0'
261        self.m3 = self.p3.start()
262        self.m3.return_value = True
263
264    def tearDown(self):
265        self.p2.stop()
266        self.p3.stop()
267        self.patcher1.stop()
268
269    def test_ucs_default_present(self, *args):
270        set_module_args(dict(
271            ucs="/root/bigip.localhost.localdomain.ucs",
272            provider=dict(
273                server='localhost',
274                password='password',
275                user='admin'
276            )
277        ))
278
279        module = AnsibleModule(
280            argument_spec=self.spec.argument_spec,
281            supports_check_mode=self.spec.supports_check_mode
282        )
283
284        # Override methods to force specific logic in the module to happen
285        mm = ModuleManager(module=module)
286        mm.is_version_v1 = Mock(return_value=False)
287
288        vm = V2Manager(module=module)
289        vm.create_on_device = Mock(return_value=True)
290        vm.exists = Mock(side_effect=[False, True])
291
292        results = vm.exec_module()
293
294        assert results['changed'] is True
295
296    def test_ucs_explicit_present(self, *args):
297        set_module_args(dict(
298            ucs="/root/bigip.localhost.localdomain.ucs",
299            state='present',
300            provider=dict(
301                server='localhost',
302                password='password',
303                user='admin'
304            )
305        ))
306
307        module = AnsibleModule(
308            argument_spec=self.spec.argument_spec,
309            supports_check_mode=self.spec.supports_check_mode
310        )
311
312        # Override methods to force specific logic in the module to happen
313        mm = ModuleManager(module=module)
314        mm.is_version_v1 = Mock(return_value=False)
315
316        vm = V2Manager(module=module)
317        vm.create_on_device = Mock(return_value=True)
318        vm.exists = Mock(side_effect=[False, True])
319
320        results = vm.exec_module()
321
322        assert results['changed'] is True
323
324    def test_ucs_installed(self, *args):
325        set_module_args(dict(
326            ucs="/root/bigip.localhost.localdomain.ucs",
327            state='installed',
328            provider=dict(
329                server='localhost',
330                password='password',
331                user='admin'
332            )
333        ))
334
335        module = AnsibleModule(
336            argument_spec=self.spec.argument_spec,
337            supports_check_mode=self.spec.supports_check_mode
338        )
339
340        # Override methods to force specific logic in the module to happen
341        mm = ModuleManager(module=module)
342        mm.is_version_v1 = Mock(return_value=False)
343
344        vm = V2Manager(module=module)
345        vm.create_on_device = Mock(return_value=True)
346        vm.exists = Mock(return_value=True)
347        vm.install_on_device = Mock(return_value=True)
348
349        results = vm.exec_module()
350
351        assert results['changed'] is True
352
353    def test_ucs_absent_exists(self, *args):
354        set_module_args(dict(
355            ucs="/root/bigip.localhost.localdomain.ucs",
356            state='absent',
357            provider=dict(
358                server='localhost',
359                password='password',
360                user='admin'
361            )
362        ))
363
364        module = AnsibleModule(
365            argument_spec=self.spec.argument_spec,
366            supports_check_mode=self.spec.supports_check_mode
367        )
368
369        # Override methods to force specific logic in the module to happen
370        mm = ModuleManager(module=module)
371        mm.is_version_v1 = Mock(return_value=False)
372
373        vm = V1Manager(module=module)
374        vm.remove_from_device = Mock(return_value=True)
375        vm.exists = Mock(side_effect=[True, False])
376
377        results = vm.exec_module()
378
379        assert results['changed'] is True
380
381    def test_ucs_absent_fails(self, *args):
382        set_module_args(dict(
383            ucs="/root/bigip.localhost.localdomain.ucs",
384            state='absent',
385            provider=dict(
386                server='localhost',
387                password='password',
388                user='admin'
389            )
390        ))
391
392        module = AnsibleModule(
393            argument_spec=self.spec.argument_spec,
394            supports_check_mode=self.spec.supports_check_mode
395        )
396
397        # Override methods to force specific logic in the module to happen
398        mm = ModuleManager(module=module)
399        mm.is_version_v1 = Mock(return_value=False)
400
401        vm = V1Manager(module=module)
402        vm.remove_from_device = Mock(return_value=True)
403        vm.exists = Mock(side_effect=[True, True])
404
405        with pytest.raises(F5ModuleError) as ex:
406            vm.exec_module()
407        assert 'Failed to delete' in str(ex.value)
408