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