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_gtm_server import (
20    ApiParameters, ModuleParameters, ModuleManager, V1Manager, V2Manager, ArgumentSpec
21)
22from ansible_collections.f5networks.f5_modules.tests.unit.compat import unittest
23from ansible_collections.f5networks.f5_modules.tests.unit.compat.mock import Mock, patch
24from ansible_collections.f5networks.f5_modules.tests.unit.modules.utils import set_module_args
25
26
27fixture_path = os.path.join(os.path.dirname(__file__), 'fixtures')
28fixture_data = {}
29
30
31def load_fixture(name):
32    path = os.path.join(fixture_path, name)
33
34    if path in fixture_data:
35        return fixture_data[path]
36
37    with open(path) as f:
38        data = f.read()
39
40    try:
41        data = json.loads(data)
42    except Exception:
43        pass
44
45    fixture_data[path] = data
46    return data
47
48
49class TestParameters(unittest.TestCase):
50    def test_module_parameters(self):
51        args = dict(
52            name='GTM_Server',
53            datacenter='New York',
54            partition='Common',
55            server_type='bigip',
56            link_discovery='disabled',
57            virtual_server_discovery='disabled',
58            devices=[
59                dict(
60                    name='server_1',
61                    address='1.1.1.1'
62                ),
63                dict(
64                    name='server_2',
65                    address='2.2.2.1',
66                    translation='192.168.2.1'
67                ),
68                dict(
69                    name='server_2',
70                    address='2.2.2.2'
71                ),
72                dict(
73                    name='server_3',
74                    addresses=[
75                        dict(
76                            address='3.3.3.1'
77                        ),
78                        dict(
79                            address='3.3.3.2'
80                        )
81                    ]
82                ),
83                dict(
84                    name='server_4',
85                    addresses=[
86                        dict(
87                            address='4.4.4.1',
88                            translation='192.168.14.1'
89                        ),
90                        dict(
91                            address='4.4.4.2'
92                        )
93                    ]
94                )
95            ]
96        )
97
98        p = ModuleParameters(params=args)
99        assert p.name == 'GTM_Server'
100        assert p.datacenter == '/Common/New York'
101        assert p.server_type == 'bigip'
102        assert p.link_discovery == 'disabled'
103        assert p.virtual_server_discovery == 'disabled'
104
105    def test_api_parameters(self):
106        args = load_fixture('load_gtm_server_1.json')
107
108        p = ApiParameters(params=args)
109        assert p.name == 'baz'
110        assert p.datacenter == '/Common/foo'
111        assert p.server_type == 'bigip'
112        assert p.link_discovery == 'disabled'
113        assert p.virtual_server_discovery == 'disabled'
114
115
116class TestV1Manager(unittest.TestCase):
117
118    def setUp(self):
119        self.spec = ArgumentSpec()
120        self.p1 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigip_gtm_server.module_provisioned')
121        self.m1 = self.p1.start()
122        self.m1.return_value = True
123        self.p2 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigip_gtm_server.tmos_version')
124        self.m2 = self.p2.start()
125        self.m2.return_value = '13.0.0'
126        self.p3 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigip_gtm_server.send_teem')
127        self.m3 = self.p3.start()
128        self.m3.return_value = True
129
130    def tearDown(self):
131        self.p1.stop()
132        self.p2.stop()
133        self.p3.stop()
134
135    def test_create(self, *args):
136        set_module_args(dict(
137            name='GTM_Server',
138            datacenter='/Common/New York',
139            server_type='bigip',
140            link_discovery='disabled',
141            virtual_server_discovery='disabled',
142            devices=[
143                dict(
144                    name='server_1',
145                    address='1.1.1.1'
146                ),
147                dict(
148                    name='server_2',
149                    address='2.2.2.1',
150                    translation='192.168.2.1'
151                ),
152                dict(
153                    name='server_2',
154                    address='2.2.2.2'
155                ),
156                dict(
157                    name='server_3',
158                    addresses=[
159                        dict(
160                            address='3.3.3.1'
161                        ),
162                        dict(
163                            address='3.3.3.2'
164                        )
165                    ]
166                ),
167                dict(
168                    name='server_4',
169                    addresses=[
170                        dict(
171                            address='4.4.4.1',
172                            translation='192.168.14.1'
173                        ),
174                        dict(
175                            address='4.4.4.2'
176                        )
177                    ]
178                )
179            ],
180            provider=dict(
181                server='localhost',
182                password='password',
183                user='admin'
184            )
185        ))
186
187        module = AnsibleModule(
188            argument_spec=self.spec.argument_spec,
189            supports_check_mode=self.spec.supports_check_mode
190        )
191
192        m1 = V1Manager(module=module, params=module.params)
193        m1.exists = Mock(side_effect=[False, True])
194        m1.create_on_device = Mock(return_value=True)
195        m1.client = Mock()
196        m1.client.api.tmos_version = '12.0.0'
197
198        # Override methods in the specific type of manager
199        mm = ModuleManager(module=module)
200        mm.get_manager = Mock(return_value=m1)
201        mm.version_is_less_than = Mock(return_value=True)
202        mm.gtm_provisioned = Mock(return_value=True)
203        mm.module_provisioned = Mock(return_value=True)
204
205        results = mm.exec_module()
206
207        assert results['changed'] is True
208        assert results['server_type'] == 'bigip'
209
210
211class TestV2Manager(unittest.TestCase):
212
213    def setUp(self):
214        self.spec = ArgumentSpec()
215        self.p1 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigip_gtm_server.module_provisioned')
216        self.m1 = self.p1.start()
217        self.m1.return_value = True
218        self.p2 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigip_gtm_server.tmos_version')
219        self.m2 = self.p2.start()
220        self.m2.return_value = '13.0.0'
221        self.p3 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigip_gtm_server.send_teem')
222        self.m3 = self.p3.start()
223        self.m3.return_value = True
224
225    def tearDown(self):
226        self.p1.stop()
227        self.p2.stop()
228        self.p3.stop()
229
230    def test_create(self, *args):
231        set_module_args(dict(
232            name='GTM_Server',
233            datacenter='/Common/New York',
234            server_type='bigip',
235            link_discovery='disabled',
236            virtual_server_discovery='disabled',
237            devices=[
238                dict(
239                    name='server_1',
240                    address='1.1.1.1'
241                ),
242                dict(
243                    name='server_2',
244                    address='2.2.2.1',
245                    translation='192.168.2.1'
246                ),
247                dict(
248                    name='server_2',
249                    address='2.2.2.2'
250                ),
251                dict(
252                    name='server_3',
253                    addresses=[
254                        dict(
255                            address='3.3.3.1'
256                        ),
257                        dict(
258                            address='3.3.3.2'
259                        )
260                    ]
261                ),
262                dict(
263                    name='server_4',
264                    addresses=[
265                        dict(
266                            address='4.4.4.1',
267                            translation='192.168.14.1'
268                        ),
269                        dict(
270                            address='4.4.4.2'
271                        )
272                    ]
273                )
274            ],
275            provider=dict(
276                server='localhost',
277                password='password',
278                user='admin'
279            )
280        ))
281
282        module = AnsibleModule(
283            argument_spec=self.spec.argument_spec,
284            supports_check_mode=self.spec.supports_check_mode
285        )
286
287        m1 = V2Manager(module=module)
288        m1.exists = Mock(side_effect=[False, True])
289        m1.create_on_device = Mock(return_value=True)
290        m1.client = Mock()
291        m1.client.api.tmos_version = '13.1.0'
292
293        # Override methods in the specific type of manager
294        mm = ModuleManager(module=module)
295        mm.get_manager = Mock(return_value=m1)
296        mm.version_is_less_than = Mock(return_value=False)
297        mm.gtm_provisioned = Mock(return_value=True)
298        mm.module_provisioned = Mock(return_value=True)
299
300        results = mm.exec_module()
301
302        assert results['changed'] is True
303        assert results['server_type'] == 'bigip'
304