1# -*- coding: utf-8 -*- 2# 3# Copyright: (c) 2019, 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 18from ansible_collections.f5networks.f5_modules.plugins.modules.bigip_apm_acl import ( 19 ApiParameters, ModuleParameters, ModuleManager, ArgumentSpec 20) 21from ansible_collections.f5networks.f5_modules.tests.unit.modules.utils import set_module_args 22from ansible_collections.f5networks.f5_modules.tests.unit.compat import unittest 23from ansible_collections.f5networks.f5_modules.tests.unit.compat.mock import ( 24 Mock, patch 25) 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 name='foo', 54 acl_order=0, 55 type='static', 56 path_match_case=True, 57 description='foobar', 58 entries=[ 59 dict(action='allow', 60 dst_port='80', 61 dst_addr='192.168.1.1', 62 src_port='443', 63 src_addr='10.10.10.0', 64 src_mask='255.255.255.128', 65 protocol='tcp', 66 host_name='foobar.com', 67 paths='/shopfront', 68 scheme='https' 69 ) 70 ] 71 ) 72 p = ModuleParameters(params=args) 73 assert p.name == 'foo' 74 assert p.acl_order == 0 75 assert p.type == 'static' 76 assert p.path_match_case == 'true' 77 assert p.description == 'foobar' 78 assert p.entries[0] == dict(action='allow', 79 dstEndPort=80, 80 dstStartPort=80, 81 dstSubnet='192.168.1.1/32', 82 srcEndPort=443, 83 srcStartPort=443, 84 srcSubnet='10.10.10.0/25', 85 protocol=6, 86 host='foobar.com', 87 paths='/shopfront', 88 scheme='https' 89 ) 90 91 def test_api_parameters(self): 92 args = load_fixture('load_apm_acl.json') 93 94 p = ApiParameters(params=args) 95 assert p.name == 'lastone' 96 assert p.acl_order == 2 97 assert p.type == 'static' 98 assert p.path_match_case == 'false' 99 assert p.description == 'foobar' 100 assert p.entries[0] == dict(action='discard', 101 dstEndPort=0, 102 dstStartPort=0, 103 dstSubnet='0.0.0.0/0', 104 srcEndPort=0, 105 srcStartPort=0, 106 srcSubnet='0.0.0.0/0', 107 protocol=1, 108 scheme='any', 109 log='none' 110 ) 111 112 113class TestManager(unittest.TestCase): 114 def setUp(self): 115 self.spec = ArgumentSpec() 116 self.p1 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigip_apm_acl.module_provisioned') 117 self.m1 = self.p1.start() 118 self.m1.return_value = True 119 self.p2 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigip_apm_acl.tmos_version') 120 self.p3 = patch('ansible_collections.f5networks.f5_modules.plugins.modules.bigip_apm_acl.send_teem') 121 self.m2 = self.p2.start() 122 self.m2.return_value = '14.1.0' 123 self.m3 = self.p3.start() 124 self.m3.return_value = True 125 126 def tearDown(self): 127 self.p1.stop() 128 self.p2.stop() 129 self.p3.stop() 130 131 def test_create_L4_L7_ACL(self, *args): 132 set_module_args(dict( 133 name='foo', 134 acl_order=0, 135 type='static', 136 path_match_case=True, 137 description='my description', 138 entries=[ 139 dict(action='allow', 140 dst_port='80', 141 dst_addr='192.168.1.1', 142 src_port='443', 143 src_addr='10.10.10.0', 144 src_mask='255.255.255.128', 145 protocol='tcp', 146 host_name='foobar.com', 147 paths='/shopfront', 148 scheme='https' 149 ) 150 ], 151 provider=dict( 152 server='localhost', 153 password='password', 154 user='admin' 155 ) 156 )) 157 158 module = AnsibleModule( 159 argument_spec=self.spec.argument_spec, 160 supports_check_mode=self.spec.supports_check_mode, 161 ) 162 163 # Override methods in the specific type of manager 164 mm = ModuleManager(module=module) 165 mm.exists = Mock(return_value=False) 166 mm.create_on_device = Mock(return_value=True) 167 168 results = mm.exec_module() 169 170 assert results['changed'] is True 171 assert results['acl_order'] == 0 172 assert results['description'] == 'my description' 173 assert results['type'] == 'static' 174 assert results['path_match_case'] == 'yes' 175 assert results['entries'] == [ 176 dict(action='allow', 177 dst_port='80', 178 dst_addr='192.168.1.1', 179 src_port='443', 180 src_addr='10.10.10.0', 181 src_mask='255.255.255.128', 182 protocol='tcp', 183 host_name='foobar.com', 184 paths='/shopfront', 185 scheme='https' 186 )] 187 188 def test_update_L4_L7_ACL(self, *args): 189 set_module_args(dict( 190 name='lastone', 191 acl_order=0, 192 path_match_case='yes', 193 entries=[ 194 dict(action='allow', 195 dst_port='80', 196 dst_addr='192.168.1.1', 197 src_port='443', 198 src_addr='10.10.10.0', 199 src_mask='255.255.255.128', 200 protocol='tcp', 201 host_name='foobar.com', 202 paths='/shopfront', 203 scheme='https' 204 ) 205 ], 206 provider=dict( 207 server='localhost', 208 password='password', 209 user='admin' 210 ) 211 )) 212 213 current = ApiParameters(params=load_fixture('load_apm_acl.json')) 214 215 module = AnsibleModule( 216 argument_spec=self.spec.argument_spec, 217 supports_check_mode=self.spec.supports_check_mode, 218 ) 219 220 # Override methods in the specific type of manager 221 mm = ModuleManager(module=module) 222 mm.exists = Mock(return_value=True) 223 mm.update_on_device = Mock(return_value=True) 224 mm.read_current_from_device = Mock(return_value=current) 225 226 results = mm.exec_module() 227 228 assert results['changed'] is True 229 assert results['acl_order'] == 0 230 assert results['path_match_case'] == 'yes' 231 assert results['entries'] == [ 232 dict(action='allow', 233 dst_port='80', 234 dst_addr='192.168.1.1', 235 src_port='443', 236 src_addr='10.10.10.0', 237 src_mask='255.255.255.128', 238 protocol='tcp', 239 host_name='foobar.com', 240 paths='/shopfront', 241 scheme='https' 242 )] 243