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_vlan import (
20    ApiParameters, ModuleParameters, ModuleManager, 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
26fixture_path = os.path.join(os.path.dirname(__file__), 'fixtures')
27fixture_data = {}
28
29
30def load_fixture(name):
31    path = os.path.join(fixture_path, name)
32
33    if path in fixture_data:
34        return fixture_data[path]
35
36    with open(path) as f:
37        data = f.read()
38
39    try:
40        data = json.loads(data)
41    except Exception:
42        pass
43
44    fixture_data[path] = data
45    return data
46
47
48class BigIpObj(object):
49    def __init__(self, **kwargs):
50        self.__dict__.update(kwargs)
51
52
53class TestParameters(unittest.TestCase):
54    def test_module_parameters(self):
55        args = dict(
56            name='somevlan',
57            tag=213,
58            description='fakevlan',
59            untagged_interfaces=['1.1'],
60            hw_syn_cookie=True,
61        )
62        p = ModuleParameters(params=args)
63
64        assert p.name == 'somevlan'
65        assert p.tag == 213
66        assert p.description == 'fakevlan'
67        assert p.untagged_interfaces == ['1.1']
68        assert p.hw_syn_cookie == 'enabled'
69
70    def test_api_parameters(self):
71        args = dict(
72            name='somevlan',
73            description='fakevlan',
74            tag=213
75        )
76
77        p = ApiParameters(params=args)
78
79        assert p.name == 'somevlan'
80        assert p.tag == 213
81        assert p.description == 'fakevlan'
82
83
84class TestManager(unittest.TestCase):
85    def setUp(self):
86        self.spec = ArgumentSpec()
87        self.p2 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigip_vlan.tmos_version')
88        self.p3 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigip_vlan.send_teem')
89        self.m2 = self.p2.start()
90        self.m2.return_value = '14.1.0'
91        self.m3 = self.p3.start()
92        self.m3.return_value = True
93
94    def tearDown(self):
95        self.p2.stop()
96        self.p3.stop()
97
98    def test_create_vlan(self, *args):
99        set_module_args(dict(
100            name='somevlan',
101            description='fakevlan',
102            partition='Common',
103            provider=dict(
104                server='localhost',
105                password='password',
106                user='admin'
107            )
108        ))
109
110        module = AnsibleModule(
111            argument_spec=self.spec.argument_spec,
112            supports_check_mode=self.spec.supports_check_mode,
113            mutually_exclusive=self.spec.mutually_exclusive
114        )
115
116        # Override methods to force specific logic in the module to happen
117        mm = ModuleManager(module=module)
118        mm.create_on_device = Mock(return_value=True)
119        mm.exists = Mock(return_value=False)
120
121        results = mm.exec_module()
122
123        assert results['changed'] is True
124        assert results['description'] == 'fakevlan'
125
126    def test_create_vlan_tagged_interface(self, *args):
127        set_module_args(dict(
128            name='somevlan',
129            tagged_interface=['2.1'],
130            tag=213,
131            partition='Common',
132            provider=dict(
133                server='localhost',
134                password='password',
135                user='admin'
136            )
137        ))
138
139        module = AnsibleModule(
140            argument_spec=self.spec.argument_spec,
141            supports_check_mode=self.spec.supports_check_mode,
142            mutually_exclusive=self.spec.mutually_exclusive
143        )
144
145        # Override methods to force specific logic in the module to happen
146        mm = ModuleManager(module=module)
147        mm.create_on_device = Mock(return_value=True)
148        mm.exists = Mock(return_value=False)
149
150        results = mm.exec_module()
151
152        assert results['changed'] is True
153        assert results['tagged_interfaces'] == ['2.1']
154        assert results['tag'] == 213
155
156    def test_create_vlan_untagged_interface(self, *args):
157        set_module_args(dict(
158            name='somevlan',
159            untagged_interface=['2.1'],
160            partition='Common',
161            provider=dict(
162                server='localhost',
163                password='password',
164                user='admin'
165            )
166        ))
167
168        module = AnsibleModule(
169            argument_spec=self.spec.argument_spec,
170            supports_check_mode=self.spec.supports_check_mode,
171            mutually_exclusive=self.spec.mutually_exclusive
172        )
173
174        # Override methods to force specific logic in the module to happen
175        mm = ModuleManager(module=module)
176        mm.create_on_device = Mock(return_value=True)
177        mm.exists = Mock(return_value=False)
178
179        results = mm.exec_module()
180
181        assert results['changed'] is True
182        assert results['untagged_interfaces'] == ['2.1']
183
184    def test_create_vlan_tagged_interfaces(self, *args):
185        set_module_args(dict(
186            name='somevlan',
187            tagged_interface=['2.1', '1.1'],
188            tag=213,
189            partition='Common',
190            provider=dict(
191                server='localhost',
192                password='password',
193                user='admin'
194            )
195        ))
196
197        module = AnsibleModule(
198            argument_spec=self.spec.argument_spec,
199            supports_check_mode=self.spec.supports_check_mode,
200            mutually_exclusive=self.spec.mutually_exclusive
201        )
202
203        # Override methods to force specific logic in the module to happen
204        mm = ModuleManager(module=module)
205        mm.create_on_device = Mock(return_value=True)
206        mm.exists = Mock(return_value=False)
207
208        results = mm.exec_module()
209
210        assert results['changed'] is True
211        assert results['tagged_interfaces'] == ['1.1', '2.1']
212        assert results['tag'] == 213
213
214    def test_create_vlan_untagged_interfaces(self, *args):
215        set_module_args(dict(
216            name='somevlan',
217            untagged_interface=['2.1', '1.1'],
218            partition='Common',
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            mutually_exclusive=self.spec.mutually_exclusive
230        )
231
232        # Override methods to force specific logic in the module to happen
233        mm = ModuleManager(module=module)
234        mm.create_on_device = Mock(return_value=True)
235        mm.exists = Mock(return_value=False)
236
237        results = mm.exec_module()
238
239        assert results['changed'] is True
240        assert results['untagged_interfaces'] == ['1.1', '2.1']
241
242    def test_update_vlan_untag_interface(self, *args):
243        set_module_args(dict(
244            name='somevlan',
245            untagged_interface=['2.1'],
246            partition='Common',
247            provider=dict(
248                server='localhost',
249                password='password',
250                user='admin'
251            )
252        ))
253
254        module = AnsibleModule(
255            argument_spec=self.spec.argument_spec,
256            supports_check_mode=self.spec.supports_check_mode,
257            mutually_exclusive=self.spec.mutually_exclusive
258        )
259
260        # Override methods to force specific logic in the module to happen
261        mm = ModuleManager(module=module)
262
263        current = ApiParameters(params=load_fixture('load_vlan.json'))
264        interfaces = load_fixture('load_vlan_interfaces.json')
265        current.update({'interfaces': interfaces})
266
267        mm.update_on_device = Mock(return_value=True)
268        mm.exists = Mock(return_value=True)
269        mm.read_current_from_device = Mock(return_value=current)
270
271        results = mm.exec_module()
272
273        assert results['changed'] is True
274        assert results['untagged_interfaces'] == ['2.1']
275
276    def test_update_vlan_tag_interface(self, *args):
277        set_module_args(dict(
278            name='somevlan',
279            tagged_interface=['2.1'],
280            partition='Common',
281            provider=dict(
282                server='localhost',
283                password='password',
284                user='admin'
285            )
286        ))
287
288        module = AnsibleModule(
289            argument_spec=self.spec.argument_spec,
290            supports_check_mode=self.spec.supports_check_mode,
291            mutually_exclusive=self.spec.mutually_exclusive
292        )
293
294        # Override methods to force specific logic in the module to happen
295        mm = ModuleManager(module=module)
296
297        current = ApiParameters(params=load_fixture('load_vlan.json'))
298
299        mm.update_on_device = Mock(return_value=True)
300        mm.exists = Mock(return_value=True)
301        mm.read_current_from_device = Mock(return_value=current)
302
303        results = mm.exec_module()
304
305        assert results['changed'] is True
306        assert results['tagged_interfaces'] == ['2.1']
307
308    def test_update_vlan_description(self, *args):
309        set_module_args(dict(
310            name='somevlan',
311            description='changed_that',
312            partition='Common',
313            provider=dict(
314                server='localhost',
315                password='password',
316                user='admin'
317            )
318        ))
319
320        module = AnsibleModule(
321            argument_spec=self.spec.argument_spec,
322            supports_check_mode=self.spec.supports_check_mode,
323            mutually_exclusive=self.spec.mutually_exclusive
324        )
325
326        # Override methods to force specific logic in the module to happen
327        mm = ModuleManager(module=module)
328
329        current = ApiParameters(params=load_fixture('update_vlan_description.json'))
330
331        mm.update_on_device = Mock(return_value=True)
332        mm.exists = Mock(return_value=True)
333        mm.read_current_from_device = Mock(return_value=current)
334
335        results = mm.exec_module()
336
337        assert results['changed'] is True
338        assert results['description'] == 'changed_that'
339