1# (c) 2021 Red Hat Inc. 2# 3# This file is part of Ansible 4# 5# Ansible is free software: you can redistribute it and/or modify 6# it under the terms of the GNU General Public License as published by 7# the Free Software Foundation, either version 3 of the License, or 8# (at your option) any later version. 9# 10# Ansible is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13# GNU General Public License for more details. 14# 15# You should have received a copy of the GNU General Public License 16# along with Ansible. If not, see <http://www.gnu.org/licenses/>. 17 18# Make coding more python3-ish 19 20from __future__ import absolute_import, division, print_function 21 22__metaclass__ = type 23 24from ansible_collections.cisco.iosxr.tests.unit.compat.mock import patch 25from ansible_collections.cisco.iosxr.plugins.modules import ( 26 iosxr_acl_interfaces, 27) 28from ansible_collections.cisco.iosxr.tests.unit.modules.utils import ( 29 set_module_args, 30) 31from .iosxr_module import TestIosxrModule, load_fixture 32 33 34class TestIosxrAclInterfacesModule(TestIosxrModule): 35 module = iosxr_acl_interfaces 36 37 def setUp(self): 38 super(TestIosxrAclInterfacesModule, self).setUp() 39 40 self.mock_get_resource_connection = patch( 41 "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module_base.get_resource_connection" 42 ) 43 self.get_resource_connection = ( 44 self.mock_get_resource_connection.start() 45 ) 46 47 self.mock_execute_show_command = patch( 48 "ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.facts.acl_interfaces.acl_interfaces.Acl_interfacesFacts.get_config" 49 ) 50 self.execute_show_command = self.mock_execute_show_command.start() 51 52 def tearDown(self): 53 super(TestIosxrAclInterfacesModule, self).tearDown() 54 self.get_resource_connection.stop() 55 self.mock_execute_show_command.stop() 56 57 def _prepare(self): 58 def load_from_file(*args, **kwargs): 59 return load_fixture("iosxr_acl_interfaces_config.cfg") 60 61 self.execute_show_command.side_effect = load_from_file 62 63 def test_iosxr_acl_interfaces_merged_idempotent(self): 64 self._prepare() 65 set_module_args( 66 dict( 67 config=[ 68 dict( 69 name="GigabitEthernet0/0/0/0", 70 access_groups=[ 71 dict( 72 afi="ipv4", 73 acls=[ 74 dict(name="acl_1", direction="in"), 75 dict(name="acl_2", direction="out"), 76 ], 77 ), 78 dict( 79 afi="ipv6", 80 acls=[ 81 dict(name="acl6_1", direction="in"), 82 dict(name="acl6_2", direction="out"), 83 ], 84 ), 85 ], 86 ), 87 dict( 88 name="GigabitEthernet0/0/0/1", 89 access_groups=[ 90 dict( 91 afi="ipv4", 92 acls=[dict(name="acl_1", direction="out")], 93 ) 94 ], 95 ), 96 ], 97 state="merged", 98 ) 99 ) 100 self.execute_module(changed=False, commands=[]) 101 102 def test_iosxr_acl_interfaces_merged(self): 103 set_module_args( 104 dict( 105 config=[ 106 dict( 107 name="GigabitEthernet0/0/0/0", 108 access_groups=[ 109 dict( 110 afi="ipv4", 111 acls=[ 112 dict(name="acl_1", direction="in"), 113 dict(name="acl_2", direction="out"), 114 ], 115 ), 116 dict( 117 afi="ipv6", 118 acls=[ 119 dict(name="acl6_1", direction="in"), 120 dict(name="acl6_2", direction="out"), 121 ], 122 ), 123 ], 124 ), 125 dict( 126 name="GigabitEthernet0/0/0/1", 127 access_groups=[ 128 dict( 129 afi="ipv4", 130 acls=[dict(name="acl_1", direction="in")], 131 ) 132 ], 133 ), 134 ], 135 state="merged", 136 ) 137 ) 138 commands = [ 139 "interface GigabitEthernet0/0/0/0", 140 "ipv4 access-group acl_1 ingress", 141 "ipv4 access-group acl_2 egress", 142 "ipv6 access-group acl6_1 ingress", 143 "ipv6 access-group acl6_2 egress", 144 "interface GigabitEthernet0/0/0/1", 145 "ipv4 access-group acl_1 ingress", 146 ] 147 result = self.execute_module(changed=True) 148 self.assertEqual(sorted(result["commands"]), sorted(commands)) 149 150 def test_iosxr_acl_interfaces_replaced(self): 151 self._prepare() 152 set_module_args( 153 dict( 154 config=[ 155 dict( 156 name="GigabitEthernet0/0/0/0", 157 access_groups=[ 158 dict( 159 afi="ipv6", 160 acls=[dict(name="acl6_3", direction="in")], 161 ) 162 ], 163 ) 164 ], 165 state="replaced", 166 ) 167 ) 168 commands = [ 169 "interface GigabitEthernet0/0/0/0", 170 "no ipv4 access-group acl_1 ingress", 171 "no ipv4 access-group acl_2 egress", 172 "no ipv6 access-group acl6_2 egress", 173 "ipv6 access-group acl6_3 ingress", 174 ] 175 result = self.execute_module(changed=True) 176 self.assertEqual(sorted(result["commands"]), sorted(commands)) 177 178 def test_iosxr_acl_interfaces_deleted(self): 179 self._prepare() 180 set_module_args(dict(state="deleted")) 181 182 commands = [ 183 "interface GigabitEthernet0/0/0/0", 184 "no ipv4 access-group acl_1 ingress", 185 "no ipv4 access-group acl_2 egress", 186 "no ipv6 access-group acl6_1 ingress", 187 "no ipv6 access-group acl6_2 egress", 188 "interface GigabitEthernet0/0/0/1", 189 "no ipv4 access-group acl_1 egress", 190 ] 191 result = self.execute_module(changed=True) 192 self.assertEqual(sorted(result["commands"]), sorted(commands)) 193 194 def test_iosxr_acl_interfaces_rendered(self): 195 set_module_args( 196 dict( 197 config=[ 198 dict( 199 name="GigabitEthernet0/0/0/0", 200 access_groups=[ 201 dict( 202 afi="ipv4", 203 acls=[ 204 dict(name="acl_1", direction="in"), 205 dict(name="acl_2", direction="out"), 206 ], 207 ), 208 dict( 209 afi="ipv6", 210 acls=[ 211 dict(name="acl6_1", direction="in"), 212 dict(name="acl6_2", direction="out"), 213 ], 214 ), 215 ], 216 ), 217 dict( 218 name="GigabitEthernet0/0/0/1", 219 access_groups=[ 220 dict( 221 afi="ipv4", 222 acls=[dict(name="acl_1", direction="in")], 223 ) 224 ], 225 ), 226 ], 227 state="rendered", 228 ) 229 ) 230 231 commands = [ 232 "interface GigabitEthernet0/0/0/0", 233 "ipv4 access-group acl_1 ingress", 234 "ipv4 access-group acl_2 egress", 235 "ipv6 access-group acl6_1 ingress", 236 "ipv6 access-group acl6_2 egress", 237 "interface GigabitEthernet0/0/0/1", 238 "ipv4 access-group acl_1 ingress", 239 ] 240 result = self.execute_module(changed=False) 241 self.assertEqual(sorted(result["rendered"]), sorted(commands)) 242 243 def test_iosxr_acl_interfaces_parsed(self): 244 self.maxDiff = None 245 set_module_args( 246 dict( 247 running_config="interface GigabitEthernet0/0/0/0\r\n shutdown\r\n ipv4 access-group acl_1 ingress\r\n" 248 " ipv4 access-group acl_2 egress\r\n ipv6 access-group acl6_1 ingress\r\n ipv6 " 249 "access-group acl6_2 egress\r\n!\r\ninterface GigabitEthernet0/0/0/1\r\n " 250 "shutdown\r\n ipv4 access-group acl_1 egress\r\n!", 251 state="parsed", 252 ) 253 ) 254 result = self.execute_module(changed=False) 255 print(result["parsed"]) 256 parsed_list = [ 257 { 258 "name": "GigabitEthernet0/0/0/0", 259 "access_groups": [ 260 { 261 "afi": "ipv4", 262 "acls": [ 263 {"name": "acl_1", "direction": "in"}, 264 {"name": "acl_2", "direction": "out"}, 265 ], 266 }, 267 { 268 "afi": "ipv6", 269 "acls": [ 270 {"name": "acl6_1", "direction": "in"}, 271 {"name": "acl6_2", "direction": "out"}, 272 ], 273 }, 274 ], 275 }, 276 { 277 "name": "GigabitEthernet0/0/0/1", 278 "access_groups": [ 279 { 280 "afi": "ipv4", 281 "acls": [{"name": "acl_1", "direction": "out"}], 282 } 283 ], 284 }, 285 ] 286 self.assertEqual(parsed_list, result["parsed"]) 287 288 def test_iosxr_acl_interfaces_overridden(self): 289 self.maxDiff = None 290 self._prepare() 291 set_module_args( 292 dict( 293 config=[ 294 dict( 295 name="GigabitEthernet0/0/0/0", 296 access_groups=[ 297 dict( 298 afi="ipv6", 299 acls=[dict(name="acl6_3", direction="in")], 300 ) 301 ], 302 ), 303 dict( 304 name="GigabitEthernet0/0/0/1", 305 access_groups=[ 306 dict( 307 afi="ipv4", 308 acls=[dict(name="acl_2", direction="in")], 309 ), 310 dict( 311 afi="ipv6", 312 acls=[dict(name="acl6_3", direction="out")], 313 ), 314 ], 315 ), 316 ], 317 state="overridden", 318 ) 319 ) 320 commands = [ 321 "interface GigabitEthernet0/0/0/0", 322 "no ipv4 access-group acl_1 ingress", 323 "no ipv4 access-group acl_2 egress", 324 "no ipv6 access-group acl6_2 egress", 325 "ipv6 access-group acl6_3 ingress", 326 "interface GigabitEthernet0/0/0/1", 327 "no ipv4 access-group acl_1 egress", 328 "ipv4 access-group acl_2 ingress", 329 "ipv6 access-group acl6_3 egress", 330 ] 331 332 result = self.execute_module(changed=True) 333 self.assertEqual(sorted(result["commands"]), sorted(commands)) 334