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
19try:
20    from library.modules.bigip_remote_syslog import ModuleParameters
21    from library.modules.bigip_remote_syslog import ModuleManager
22    from library.modules.bigip_remote_syslog import ArgumentSpec
23
24    from library.module_utils.network.f5.common import F5ModuleError
25
26    # In Ansible 2.8, Ansible changed import paths.
27    from test.units.compat import unittest
28    from test.units.compat.mock import Mock
29
30    from test.units.modules.utils import set_module_args
31except ImportError:
32    from ansible.modules.network.f5.bigip_remote_syslog import ModuleParameters
33    from ansible.modules.network.f5.bigip_remote_syslog import ModuleManager
34    from ansible.modules.network.f5.bigip_remote_syslog import ArgumentSpec
35
36    from ansible.module_utils.network.f5.common import F5ModuleError
37
38    # Ansible 2.8 imports
39    from units.compat import unittest
40    from units.compat.mock import Mock
41
42    from units.modules.utils import set_module_args
43
44
45fixture_path = os.path.join(os.path.dirname(__file__), 'fixtures')
46fixture_data = {}
47
48
49def load_fixture(name):
50    path = os.path.join(fixture_path, name)
51
52    if path in fixture_data:
53        return fixture_data[path]
54
55    with open(path) as f:
56        data = f.read()
57
58    try:
59        data = json.loads(data)
60    except Exception:
61        pass
62
63    fixture_data[path] = data
64    return data
65
66
67class TestParameters(unittest.TestCase):
68    def test_module_parameters(self):
69        args = dict(
70            remote_host='10.10.10.10',
71            remote_port=514,
72            local_ip='1.1.1.1'
73        )
74
75        p = ModuleParameters(params=args)
76        assert p.remote_host == '10.10.10.10'
77        assert p.remote_port == 514
78        assert p.local_ip == '1.1.1.1'
79
80
81class TestManager(unittest.TestCase):
82
83    def setUp(self):
84        self.spec = ArgumentSpec()
85
86    def test_create_remote_syslog(self, *args):
87        set_module_args(dict(
88            remote_host='1.1.1.1',
89            provider=dict(
90                server='localhost',
91                password='password',
92                user='admin'
93            )
94        ))
95
96        fixture = load_fixture('load_tm_sys_syslog_1.json')
97        current = fixture['remoteServers']
98
99        module = AnsibleModule(
100            argument_spec=self.spec.argument_spec,
101            supports_check_mode=self.spec.supports_check_mode
102        )
103
104        # Override methods in the specific type of manager
105        mm = ModuleManager(module=module)
106        mm.exists = Mock(side_effect=[False, True])
107        mm.update_on_device = Mock(return_value=True)
108        mm.read_current_from_device = Mock(return_value=current)
109
110        results = mm.exec_module()
111
112        assert results['changed'] is True
113
114    def test_create_remote_syslog_idempotent(self, *args):
115        set_module_args(dict(
116            name='remotesyslog1',
117            remote_host='10.10.10.10',
118            provider=dict(
119                server='localhost',
120                password='password',
121                user='admin'
122            )
123        ))
124
125        fixture = load_fixture('load_tm_sys_syslog_1.json')
126        current = fixture['remoteServers']
127
128        module = AnsibleModule(
129            argument_spec=self.spec.argument_spec,
130            supports_check_mode=self.spec.supports_check_mode
131        )
132
133        # Override methods in the specific type of manager
134        mm = ModuleManager(module=module)
135        mm.exists = Mock(return_value=True)
136        mm.read_current_from_device = Mock(return_value=current)
137
138        results = mm.exec_module()
139
140        assert results['changed'] is False
141
142    def test_update_remote_port(self, *args):
143        set_module_args(dict(
144            remote_host='10.10.10.10',
145            remote_port=800,
146            provider=dict(
147                server='localhost',
148                password='password',
149                user='admin'
150            )
151        ))
152
153        fixture = load_fixture('load_tm_sys_syslog_1.json')
154        current = fixture['remoteServers']
155
156        module = AnsibleModule(
157            argument_spec=self.spec.argument_spec,
158            supports_check_mode=self.spec.supports_check_mode
159        )
160
161        # Override methods in the specific type of manager
162        mm = ModuleManager(module=module)
163        mm.exists = Mock(return_value=True)
164        mm.read_current_from_device = Mock(return_value=current)
165        mm.update_on_device = Mock(return_value=True)
166
167        results = mm.exec_module()
168
169        assert results['changed'] is True
170        assert results['remote_port'] == 800
171
172    def test_update_local_ip(self, *args):
173        set_module_args(dict(
174            remote_host='10.10.10.10',
175            local_ip='2.2.2.2',
176            provider=dict(
177                server='localhost',
178                password='password',
179                user='admin'
180            )
181        ))
182
183        fixture = load_fixture('load_tm_sys_syslog_1.json')
184        current = fixture['remoteServers']
185
186        module = AnsibleModule(
187            argument_spec=self.spec.argument_spec,
188            supports_check_mode=self.spec.supports_check_mode
189        )
190
191        # Override methods in the specific type of manager
192        mm = ModuleManager(module=module)
193        mm.exists = Mock(return_value=True)
194        mm.read_current_from_device = Mock(return_value=current)
195        mm.update_on_device = Mock(return_value=True)
196
197        results = mm.exec_module()
198
199        assert results['changed'] is True
200        assert results['local_ip'] == '2.2.2.2'
201
202    def test_update_no_name_dupe_host(self, *args):
203        set_module_args(dict(
204            remote_host='10.10.10.10',
205            local_ip='2.2.2.2',
206            provider=dict(
207                server='localhost',
208                password='password',
209                user='admin'
210            )
211        ))
212
213        fixture = load_fixture('load_tm_sys_syslog_2.json')
214        current = fixture['remoteServers']
215
216        module = AnsibleModule(
217            argument_spec=self.spec.argument_spec,
218            supports_check_mode=self.spec.supports_check_mode
219        )
220
221        # Override methods in the specific type of manager
222        mm = ModuleManager(module=module)
223        mm.exists = Mock(return_value=True)
224        mm.read_current_from_device = Mock(return_value=current)
225        mm.update_on_device = Mock(return_value=True)
226
227        with pytest.raises(F5ModuleError) as ex:
228            mm.exec_module()
229
230        assert "Multiple occurrences of hostname" in str(ex.value)
231