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_virtual_address 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 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 state='present', 53 address='1.1.1.1', 54 netmask='2.2.2.2', 55 connection_limit='10', 56 arp='enabled', 57 auto_delete='enabled', 58 icmp_echo='enabled', 59 availability_calculation='always', 60 ) 61 p = ModuleParameters(params=args) 62 assert p.state == 'present' 63 assert p.address == '1.1.1.1' 64 assert p.netmask == '2.2.2.2' 65 assert p.connection_limit == 10 66 assert p.arp == 'enabled' 67 assert p.auto_delete == 'true' 68 assert p.icmp_echo == 'enabled' 69 assert p.availability_calculation == 'none' 70 71 def test_api_parameters(self): 72 args = load_fixture('load_ltm_virtual_address_default.json') 73 p = ApiParameters(params=args) 74 assert p.name == '1.1.1.1' 75 assert p.address == '1.1.1.1' 76 assert p.arp == 'enabled' 77 assert p.auto_delete == 'true' 78 assert p.connection_limit == 0 79 assert p.state == 'enabled' 80 assert p.icmp_echo == 'enabled' 81 assert p.netmask == '255.255.255.255' 82 assert p.route_advertisement_type == 'disabled' 83 assert p.availability_calculation == 'any' 84 85 def test_module_parameters_advertise_route_all(self): 86 args = dict( 87 availability_calculation='when_all_available' 88 ) 89 p = ModuleParameters(params=args) 90 assert p.availability_calculation == 'all' 91 92 def test_module_parameters_advertise_route_any(self): 93 args = dict( 94 availability_calculation='when_any_available' 95 ) 96 p = ModuleParameters(params=args) 97 assert p.availability_calculation == 'any' 98 99 def test_module_parameters_icmp_echo_disabled(self): 100 args = dict( 101 icmp_echo='disabled' 102 ) 103 p = ModuleParameters(params=args) 104 assert p.icmp_echo == 'disabled' 105 106 def test_module_parameters_icmp_echo_selective(self): 107 args = dict( 108 icmp_echo='selective' 109 ) 110 p = ModuleParameters(params=args) 111 assert p.icmp_echo == 'selective' 112 113 def test_module_parameters_auto_delete_disabled(self): 114 args = dict( 115 auto_delete='disabled' 116 ) 117 p = ModuleParameters(params=args) 118 assert p.auto_delete == 'false' 119 120 def test_module_parameters_arp_disabled(self): 121 args = dict( 122 arp='disabled' 123 ) 124 p = ModuleParameters(params=args) 125 assert p.arp == 'disabled' 126 127 def test_module_parameters_state_present(self): 128 args = dict( 129 state='present' 130 ) 131 p = ModuleParameters(params=args) 132 assert p.state == 'present' 133 assert p.enabled == 'yes' 134 135 def test_module_parameters_state_absent(self): 136 args = dict( 137 state='absent' 138 ) 139 p = ModuleParameters(params=args) 140 assert p.state == 'absent' 141 142 def test_module_parameters_state_enabled(self): 143 args = dict( 144 state='enabled' 145 ) 146 p = ModuleParameters(params=args) 147 assert p.state == 'enabled' 148 assert p.enabled == 'yes' 149 150 def test_module_parameters_state_disabled(self): 151 args = dict( 152 state='disabled' 153 ) 154 p = ModuleParameters(params=args) 155 assert p.state == 'disabled' 156 assert p.enabled == 'no' 157 158 159class TestManager(unittest.TestCase): 160 def setUp(self): 161 self.spec = ArgumentSpec() 162 self.p2 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigip_virtual_address.tmos_version') 163 self.p3 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigip_virtual_address.send_teem') 164 self.m2 = self.p2.start() 165 self.m2.return_value = '14.1.0' 166 self.m3 = self.p3.start() 167 self.m3.return_value = True 168 169 def tearDown(self): 170 self.p2.stop() 171 self.p3.stop() 172 173 def test_create_virtual_address(self, *args): 174 set_module_args(dict( 175 state='present', 176 address='1.1.1.1', 177 netmask='2.2.2.2', 178 connection_limit='10', 179 arp='yes', 180 auto_delete='yes', 181 icmp_echo='enabled', 182 advertise_route='always', 183 provider=dict( 184 server='localhost', 185 password='password', 186 user='admin' 187 ) 188 )) 189 190 module = AnsibleModule( 191 argument_spec=self.spec.argument_spec, 192 supports_check_mode=self.spec.supports_check_mode, 193 required_one_of=self.spec.required_one_of 194 ) 195 mm = ModuleManager(module=module) 196 197 # Override methods to force specific logic in the module to happen 198 mm.exists = Mock(side_effect=[False, True]) 199 mm.create_on_device = Mock(return_value=True) 200 201 results = mm.exec_module() 202 assert results['changed'] is True 203 204 def test_delete_virtual_address(self, *args): 205 set_module_args(dict( 206 state='absent', 207 address='1.1.1.1', 208 provider=dict( 209 server='localhost', 210 password='password', 211 user='admin' 212 ) 213 )) 214 215 module = AnsibleModule( 216 argument_spec=self.spec.argument_spec, 217 supports_check_mode=self.spec.supports_check_mode, 218 required_one_of=self.spec.required_one_of 219 ) 220 mm = ModuleManager(module=module) 221 222 # Override methods to force specific logic in the module to happen 223 mm.exists = Mock(side_effect=[True, False]) 224 mm.remove_from_device = Mock(return_value=True) 225 226 results = mm.exec_module() 227 assert results['changed'] is True 228