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_selfip import ( 20 ApiParameters, ModuleParameters, ModuleManager, ArgumentSpec 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 address='10.10.10.10', 54 allow_service=[ 55 'tcp:80', 56 'udp:53', 57 'gre' 58 ], 59 name='net1', 60 netmask='255.255.255.0', 61 partition='Common', 62 route_domain='1', 63 state='present', 64 traffic_group='traffic-group-local-only', 65 vlan='net1' 66 ) 67 p = ModuleParameters(params=args) 68 assert p.address == '10.10.10.10%1/24' 69 assert p.allow_service == ['gre:0', 'tcp:80', 'udp:53'] 70 assert p.name == 'net1' 71 assert p.netmask == 24 72 assert p.route_domain == 1 73 assert p.traffic_group == '/Common/traffic-group-local-only' 74 assert p.vlan == '/Common/net1' 75 76 def test_module_invalid_service(self): 77 args = dict( 78 allow_service=[ 79 'tcp:80', 80 'udp:53', 81 'grp' 82 ] 83 ) 84 p = ModuleParameters(params=args) 85 with pytest.raises(F5ModuleError) as ex: 86 assert p.allow_service == ['grp', 'tcp:80', 'udp:53'] 87 assert 'The provided protocol' in str(ex.value) 88 89 def test_api_parameters(self): 90 args = dict( 91 address='10.10.10.10%1/24', 92 allowService=[ 93 'tcp:80', 94 'udp:53', 95 'gre' 96 ], 97 name='net1', 98 state='present', 99 trafficGroup='/Common/traffic-group-local-only', 100 vlan='net1' 101 ) 102 p = ApiParameters(params=args) 103 assert p.address == '10.10.10.10%1/24' 104 assert p.allow_service == ['gre', 'tcp:80', 'udp:53'] 105 assert p.name == 'net1' 106 assert p.netmask == 24 107 assert p.traffic_group == '/Common/traffic-group-local-only' 108 assert p.vlan == '/Common/net1' 109 110 111class TestManager(unittest.TestCase): 112 def setUp(self): 113 self.spec = ArgumentSpec() 114 self.p2 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigip_selfip.tmos_version') 115 self.p3 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigip_selfip.send_teem') 116 self.m2 = self.p2.start() 117 self.m2.return_value = '14.1.0' 118 self.m3 = self.p3.start() 119 self.m3.return_value = True 120 121 def tearDown(self): 122 self.p2.stop() 123 self.p3.stop() 124 125 def test_create_selfip(self, *args): 126 set_module_args(dict( 127 address='10.10.10.10', 128 allow_service=[ 129 'tcp:80', 130 'udp:53', 131 'gre' 132 ], 133 name='net1', 134 netmask='255.255.255.0', 135 partition='Common', 136 route_domain='1', 137 state='present', 138 traffic_group='traffic-group-local-only', 139 vlan='net1', 140 provider=dict( 141 server='localhost', 142 password='password', 143 user='admin' 144 ) 145 )) 146 147 module = AnsibleModule( 148 argument_spec=self.spec.argument_spec, 149 supports_check_mode=self.spec.supports_check_mode 150 ) 151 mm = ModuleManager(module=module) 152 153 # Override methods to force specific logic in the module to happen 154 mm.exists = Mock(side_effect=[False, True]) 155 mm.create_on_device = Mock(return_value=True) 156 157 results = mm.exec_module() 158 159 assert results['changed'] is True 160 161 def test_create_selfip_idempotent(self, *args): 162 set_module_args(dict( 163 address='10.10.10.10', 164 allow_service=[ 165 'tcp:80', 166 'udp:53', 167 'gre' 168 ], 169 name='net1', 170 netmask='255.255.255.0', 171 partition='Common', 172 route_domain='1', 173 state='present', 174 traffic_group='traffic-group-local-only', 175 vlan='net1', 176 provider=dict( 177 server='localhost', 178 password='password', 179 user='admin' 180 ) 181 )) 182 183 current = ApiParameters(params=load_fixture('load_tm_net_self.json')) 184 185 module = AnsibleModule( 186 argument_spec=self.spec.argument_spec, 187 supports_check_mode=self.spec.supports_check_mode 188 ) 189 mm = ModuleManager(module=module) 190 191 # Override methods to force specific logic in the module to happen 192 mm.exists = Mock(side_effect=[True, True]) 193 mm.read_current_from_device = Mock(return_value=current) 194 195 results = mm.exec_module() 196 197 assert results['changed'] is False 198