1#
2# (c) 2021, Ansible by Red Hat, inc
3# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
4#
5
6from __future__ import absolute_import, division, print_function
7
8__metaclass__ = type
9
10from textwrap import dedent
11from ansible_collections.cisco.ios.tests.unit.compat.mock import patch
12from ansible_collections.cisco.ios.plugins.modules import ios_ntp_global
13from ansible_collections.cisco.ios.tests.unit.modules.utils import (
14    set_module_args,
15)
16from .ios_module import TestIosModule
17
18
19class TestIosNtpGlobalModule(TestIosModule):
20    module = ios_ntp_global
21
22    def setUp(self):
23        super(TestIosNtpGlobalModule, self).setUp()
24
25        self.mock_get_config = patch(
26            "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.get_config"
27        )
28        self.get_config = self.mock_get_config.start()
29
30        self.mock_load_config = patch(
31            "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.load_config"
32        )
33        self.load_config = self.mock_load_config.start()
34
35        self.mock_get_resource_connection_config = patch(
36            "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base."
37            "get_resource_connection"
38        )
39        self.get_resource_connection_config = (
40            self.mock_get_resource_connection_config.start()
41        )
42
43        self.mock_get_resource_connection_facts = patch(
44            "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module_base."
45            "get_resource_connection"
46        )
47        self.get_resource_connection_facts = (
48            self.mock_get_resource_connection_facts.start()
49        )
50
51        self.mock_edit_config = patch(
52            "ansible_collections.cisco.ios.plugins.module_utils.network.ios.providers.providers.CliProvider.edit_config"
53        )
54        self.edit_config = self.mock_edit_config.start()
55
56        self.mock_execute_show_command = patch(
57            "ansible_collections.cisco.ios.plugins.module_utils.network.ios.facts.ntp_global.ntp_global."
58            "Ntp_globalFacts.get_ntp_data"
59        )
60        self.execute_show_command = self.mock_execute_show_command.start()
61
62    def tearDown(self):
63        super(TestIosNtpGlobalModule, self).tearDown()
64        self.mock_get_resource_connection_config.stop()
65        self.mock_get_resource_connection_facts.stop()
66        self.mock_edit_config.stop()
67        self.mock_get_config.stop()
68        self.mock_load_config.stop()
69        self.mock_execute_show_command.stop()
70
71    def test_ios_ntp_global_merged_idempotent(self):
72        self.execute_show_command.return_value = dedent(
73            """\
74            ntp allow mode control 4
75            ntp allow mode private
76            ntp authenticate
77            ntp broadcastdelay 22
78            ntp clock-period 5
79            ntp logging
80            ntp master 4
81            ntp max-associations 34
82            ntp maxdistance 3
83            ntp mindistance 10
84            ntp orphan 4
85            ntp panic update
86            ntp source GigabitEthernet0/1
87            ntp update-calendar
88            ntp access-group ipv4 peer DHCP-Server kod
89            ntp access-group ipv6 peer preauth_ipv6_acl kod
90            ntp access-group peer 2 kod
91            ntp access-group query-only 10
92            ntp authentication-key 2 md5 SomeSecurePassword 7
93            ntp peer 172.16.1.10 version 2
94            ntp peer 172.16.1.11 key 2 minpoll 5 prefer version 2
95            ntp peer ip checkPeerDomainIpv4.com prefer
96            ntp peer ipv6 checkPeerDomainIpv6.com
97            ntp peer ipv6 testPeerDomainIpv6.com prefer
98            ntp server 172.16.1.12 version 2
99            ntp server ipv6 checkServerDomainIpv6.com
100            ntp server 172.16.1.13 source GigabitEthernet0/1
101            ntp trusted-key 3 - 13
102            ntp trusted-key 21
103            """
104        )
105        set_module_args(
106            dict(
107                config=dict(
108                    access_group=dict(
109                        peer=[
110                            dict(access_list="2", kod=True),
111                            dict(
112                                access_list="preauth_ipv6_acl",
113                                ipv6=True,
114                                kod=True,
115                            ),
116                        ]
117                    ),
118                    allow=dict(control=dict(rate_limit=4)),
119                    authenticate=True,
120                    authentication_keys=[
121                        dict(
122                            algorithm="md5",
123                            encryption=7,
124                            id=2,
125                            key="SomeSecurePassword",
126                        )
127                    ],
128                    broadcast_delay=22,
129                    logging=True,
130                    master=dict(stratum=4),
131                    max_associations=34,
132                    max_distance=3,
133                    min_distance=10,
134                    orphan=4,
135                    panic_update=True,
136                    peers=[
137                        dict(peer="172.16.1.10", version=2),
138                        dict(
139                            key=2,
140                            minpoll=5,
141                            peer="172.16.1.11",
142                            prefer=True,
143                            version=2,
144                        ),
145                        dict(
146                            peer="checkPeerDomainIpv4.com",
147                            prefer=True,
148                            use_ipv4=True,
149                        ),
150                        dict(peer="checkPeerDomainIpv6.com", use_ipv6=True),
151                        dict(
152                            peer="testPeerDomainIpv6.com",
153                            prefer=True,
154                            use_ipv6=True,
155                        ),
156                    ],
157                    servers=[
158                        dict(server="172.16.1.12", version=2),
159                        dict(
160                            server="172.16.1.13", source="GigabitEthernet0/1"
161                        ),
162                        dict(
163                            server="checkServerDomainIpv6.com", use_ipv6=True
164                        ),
165                    ],
166                    source="GigabitEthernet0/1",
167                    trusted_keys=[
168                        dict(range_start=21),
169                        dict(range_end=13, range_start=3),
170                    ],
171                    update_calendar=True,
172                ),
173                state="merged",
174            )
175        )
176        commands = []
177        result = self.execute_module(changed=False)
178        self.assertEqual(sorted(result["commands"]), sorted(commands))
179
180    def test_ios_ntp_global_merged(self):
181        self.execute_show_command.return_value = dedent(
182            """\
183            ntp allow mode control 4
184            ntp allow mode private
185            """
186        )
187        set_module_args(
188            dict(
189                config=dict(
190                    access_group=dict(
191                        peer=[
192                            dict(access_list="2", kod=True),
193                            dict(
194                                access_list="preauth_ipv6_acl",
195                                ipv6=True,
196                                kod=True,
197                            ),
198                        ]
199                    ),
200                    allow=dict(control=dict(rate_limit=4)),
201                    authenticate=True,
202                    authentication_keys=[
203                        dict(
204                            algorithm="md5",
205                            encryption=7,
206                            id=2,
207                            key="SomeSecurePassword",
208                        )
209                    ],
210                    broadcast_delay=22,
211                    logging=True,
212                    master=dict(stratum=4),
213                    max_associations=34,
214                    max_distance=3,
215                    min_distance=10,
216                    orphan=4,
217                    panic_update=True,
218                    peers=[
219                        dict(peer="172.16.1.10", version=2),
220                        dict(
221                            key=2,
222                            minpoll=5,
223                            peer="172.16.1.11",
224                            prefer=True,
225                            version=2,
226                        ),
227                        dict(
228                            peer="checkPeerDomainIpv4.com",
229                            prefer=True,
230                            use_ipv4=True,
231                        ),
232                        dict(peer="checkPeerDomainIpv6.com", use_ipv6=True),
233                        dict(
234                            peer="testPeerDomainIpv6.com",
235                            prefer=True,
236                            use_ipv6=True,
237                        ),
238                    ],
239                    servers=[
240                        dict(server="172.16.1.12", version=2),
241                        dict(
242                            server="172.16.1.13", source="GigabitEthernet0/1"
243                        ),
244                        dict(
245                            server="checkServerDomainIpv6.com", use_ipv6=True
246                        ),
247                    ],
248                    source="GigabitEthernet0/1",
249                    trusted_keys=[
250                        dict(range_start=21),
251                        dict(range_end=13, range_start=3),
252                    ],
253                    update_calendar=True,
254                ),
255                state="merged",
256            )
257        )
258        commands = [
259            "ntp authenticate",
260            "ntp broadcastdelay 22",
261            "ntp logging",
262            "ntp master 4",
263            "ntp max-associations 34",
264            "ntp maxdistance 3",
265            "ntp mindistance 10",
266            "ntp orphan 4",
267            "ntp panic update",
268            "ntp source GigabitEthernet0/1",
269            "ntp update-calendar",
270            "ntp access-group peer 2 kod",
271            "ntp access-group ipv6 peer preauth_ipv6_acl kod",
272            "ntp authentication-key 2 md5 SomeSecurePassword 7",
273            "ntp peer 172.16.1.10 version 2",
274            "ntp peer 172.16.1.11 key 2 minpoll 5 prefer version 2",
275            "ntp peer ip checkPeerDomainIpv4.com prefer",
276            "ntp peer ipv6 checkPeerDomainIpv6.com",
277            "ntp peer ipv6 testPeerDomainIpv6.com prefer",
278            "ntp server 172.16.1.12 version 2",
279            "ntp server 172.16.1.13 source GigabitEthernet0/1",
280            "ntp server ipv6 checkServerDomainIpv6.com",
281            "ntp trusted-key 21",
282            "ntp trusted-key 3 - 13",
283        ]
284        result = self.execute_module(changed=True)
285        self.assertEqual(sorted(result["commands"]), sorted(commands))
286
287    def test_ios_ntp_global_deleted(self):
288        self.execute_show_command.return_value = dedent(
289            """\
290            ntp allow mode control 4
291            ntp allow mode private
292            ntp authenticate
293            ntp broadcastdelay 22
294            ntp clock-period 5
295            ntp logging
296            ntp master 4
297            ntp max-associations 34
298            ntp maxdistance 3
299            ntp mindistance 10
300            ntp orphan 4
301            ntp panic update
302            ntp source GigabitEthernet0/1
303            ntp update-calendar
304            ntp access-group ipv4 peer DHCP-Server kod
305            ntp access-group ipv6 peer preauth_ipv6_acl kod
306            ntp access-group peer 2 kod
307            ntp access-group query-only 10
308            ntp authentication-key 2 md5 SomeSecurePassword 7
309            ntp peer 172.16.1.10 version 2
310            ntp peer 172.16.1.11 key 2 minpoll 5 prefer version 2
311            ntp peer ip checkPeerDomainIpv4.com prefer
312            ntp peer ipv6 checkPeerDomainIpv6.com
313            ntp peer ipv6 testPeerDomainIpv6.com prefer
314            ntp server 172.16.1.12 version 2
315            ntp server ipv6 checkServerDomainIpv6.com
316            ntp server 172.16.1.13 source GigabitEthernet0/1
317            ntp trusted-key 3 - 13
318            ntp trusted-key 21
319            """
320        )
321        set_module_args(dict(config=dict(), state="deleted"))
322        commands = [
323            "no ntp allow mode control 4",
324            "no ntp allow mode private",
325            "no ntp authenticate",
326            "no ntp broadcastdelay 22",
327            "no ntp clock-period 5",
328            "no ntp logging",
329            "no ntp master 4",
330            "no ntp max-associations 34",
331            "no ntp maxdistance 3",
332            "no ntp mindistance 10",
333            "no ntp orphan 4",
334            "no ntp panic update",
335            "no ntp source GigabitEthernet0/1",
336            "no ntp update-calendar",
337            "no ntp access-group peer 2 kod",
338            "no ntp access-group ipv4 peer DHCP-Server kod",
339            "no ntp access-group ipv6 peer preauth_ipv6_acl kod",
340            "no ntp access-group query-only 10",
341            "no ntp authentication-key 2 md5 SomeSecurePassword 7",
342            "no ntp peer 172.16.1.10 version 2",
343            "no ntp peer 172.16.1.11 key 2 minpoll 5 prefer version 2",
344            "no ntp peer ip checkPeerDomainIpv4.com prefer",
345            "no ntp peer ipv6 checkPeerDomainIpv6.com",
346            "no ntp peer ipv6 testPeerDomainIpv6.com prefer",
347            "no ntp server 172.16.1.12 version 2",
348            "no ntp server 172.16.1.13 source GigabitEthernet0/1",
349            "no ntp server ipv6 checkServerDomainIpv6.com",
350            "no ntp trusted-key 21",
351            "no ntp trusted-key 3 - 13",
352        ]
353        result = self.execute_module(changed=True)
354        self.assertEqual(sorted(result["commands"]), sorted(commands))
355
356    def test_ios_ntp_global_deleted_blank(self):
357        self.execute_show_command.return_value = dedent(
358            """\
359            """
360        )
361        set_module_args(dict(config=dict(), state="deleted"))
362        commands = []
363        result = self.execute_module(changed=False)
364        self.assertEqual(sorted(result["commands"]), sorted(commands))
365
366    def test_ios_ntp_global_replaced_overridden(self):
367        """ both the replaced and overridden states are supported to have same behaviour """
368        self.execute_show_command.return_value = dedent(
369            """\
370            ntp allow mode control 4
371            ntp allow mode private
372            ntp authenticate
373            ntp broadcastdelay 22
374            ntp clock-period 15
375            ntp logging
376            ntp master 14
377            ntp max-associations 134
378            ntp maxdistance 3
379            ntp mindistance 100
380            ntp orphan 4
381            ntp panic update
382            ntp source Loopback888
383            ntp update-calendar
384            ntp access-group ipv4 peer DHCPAC kod
385            ntp access-group ipv6 peer preauth_ipv6_acl kod
386            ntp access-group peer 2 kod
387            ntp access-group query-only 10
388            ntp authentication-key 2 md5 SomeSecurePassword 7
389            ntp peer 172.16.1.9 version 2
390            ntp peer 172.16.1.1 key 2 minpoll 5 prefer version 2
391            ntp peer ip checkPeerDomainIpv4.com prefer
392            ntp peer ipv6 checkPeerDomainIpv6.com
393            ntp peer ipv6 testPeerDomainIpv6.com prefer
394            ntp server 172.16.1.19 version 2
395            ntp server ipv6 checkServerDomainIpv6.com
396            ntp server 172.16.1.111 source GigabitEthernet0/1
397            ntp trusted-key 3 - 130
398            ntp trusted-key 21
399            """
400        )
401        set_module_args(
402            dict(
403                config=dict(
404                    access_group=dict(
405                        peer=[
406                            dict(access_list="2", kod=True),
407                            dict(
408                                access_list="preauth_ipv6_acl",
409                                ipv6=True,
410                                kod=True,
411                            ),
412                        ]
413                    ),
414                    allow=dict(control=dict(rate_limit=4)),
415                    authenticate=True,
416                    authentication_keys=[
417                        dict(
418                            algorithm="md5",
419                            encryption=7,
420                            id=2,
421                            key="SomeSecurePassword",
422                        )
423                    ],
424                    broadcast_delay=22,
425                    logging=True,
426                    master=dict(stratum=4),
427                    max_associations=34,
428                    max_distance=3,
429                    min_distance=10,
430                    orphan=4,
431                    panic_update=True,
432                    peers=[
433                        dict(peer="172.16.1.10", version=2),
434                        dict(
435                            key=2,
436                            minpoll=5,
437                            peer="172.16.1.11",
438                            prefer=True,
439                            version=2,
440                        ),
441                        dict(
442                            peer="checkPeerDomainIpv4.com",
443                            prefer=True,
444                            use_ipv4=True,
445                        ),
446                        dict(peer="checkPeerDomainIpv6.com", use_ipv6=True),
447                        dict(
448                            peer="testPeerDomainIpv6.com",
449                            prefer=True,
450                            use_ipv6=True,
451                        ),
452                    ],
453                    servers=[
454                        dict(server="172.16.1.12", version=2),
455                        dict(
456                            server="172.16.1.13", source="GigabitEthernet0/1"
457                        ),
458                        dict(
459                            server="checkServerDomainIpv6.com", use_ipv6=True
460                        ),
461                    ],
462                    source="GigabitEthernet0/1",
463                    trusted_keys=[
464                        dict(range_start=21),
465                        dict(range_end=13, range_start=3),
466                    ],
467                    update_calendar=True,
468                ),
469                state="replaced",
470            )
471        )
472        commands = [
473            "no ntp allow mode private",
474            "no ntp clock-period 15",
475            "ntp master 4",
476            "ntp max-associations 34",
477            "ntp mindistance 10",
478            "ntp source GigabitEthernet0/1",
479            "no ntp access-group ipv4 peer DHCPAC kod",
480            "no ntp access-group query-only 10",
481            "ntp peer 172.16.1.10 version 2",
482            "ntp peer 172.16.1.11 key 2 minpoll 5 prefer version 2",
483            "no ntp peer 172.16.1.1 key 2 minpoll 5 prefer version 2",
484            "no ntp peer 172.16.1.9 version 2",
485            "ntp server 172.16.1.12 version 2",
486            "ntp server 172.16.1.13 source GigabitEthernet0/1",
487            "no ntp server 172.16.1.111 source GigabitEthernet0/1",
488            "no ntp server 172.16.1.19 version 2",
489            "no ntp trusted-key 3 - 130",
490            "ntp trusted-key 3 - 13",
491        ]
492        result = self.execute_module(changed=True)
493        self.assertEqual(sorted(result["commands"]), sorted(commands))
494
495    def test_ios_ntp_global_replaced_overridden_idempotent(self):
496        """ both the replaced and overridden states are supported to have same behaviour """
497        self.execute_show_command.return_value = dedent(
498            """\
499            ntp allow mode control 4
500            ntp authenticate
501            ntp broadcastdelay 22
502            ntp logging
503            ntp master 4
504            ntp max-associations 34
505            ntp maxdistance 3
506            ntp mindistance 10
507            ntp orphan 4
508            ntp panic update
509            ntp source Loopback888
510            ntp update-calendar
511            ntp access-group ipv6 peer preauth_ipv6_acl kod
512            ntp access-group peer 2 kod
513            ntp authentication-key 2 md5 SomeSecurePassword 7
514            ntp peer 172.16.1.11 key 2 minpoll 5 prefer version 2
515            ntp peer ip checkPeerDomainIpv4.com prefer
516            ntp server ipv6 checkServerDomainIpv6.com
517            ntp server 172.16.1.13 source GigabitEthernet0/1
518            ntp trusted-key 3 - 13
519            ntp trusted-key 21
520            """
521        )
522        set_module_args(
523            dict(
524                config=dict(
525                    access_group=dict(
526                        peer=[
527                            dict(access_list="2", kod=True),
528                            dict(
529                                access_list="preauth_ipv6_acl",
530                                ipv6=True,
531                                kod=True,
532                            ),
533                        ]
534                    ),
535                    allow=dict(control=dict(rate_limit=4)),
536                    authenticate=True,
537                    authentication_keys=[
538                        dict(
539                            algorithm="md5",
540                            encryption=7,
541                            id=2,
542                            key="SomeSecurePassword",
543                        )
544                    ],
545                    broadcast_delay=22,
546                    logging=True,
547                    master=dict(stratum=4),
548                    max_associations=34,
549                    max_distance=3,
550                    min_distance=10,
551                    orphan=4,
552                    panic_update=True,
553                    peers=[
554                        dict(
555                            key=2,
556                            minpoll=5,
557                            peer="172.16.1.11",
558                            prefer=True,
559                            version=2,
560                        ),
561                        dict(
562                            peer="checkPeerDomainIpv4.com",
563                            prefer=True,
564                            use_ipv4=True,
565                        ),
566                    ],
567                    servers=[
568                        dict(
569                            server="172.16.1.13", source="GigabitEthernet0/1"
570                        ),
571                        dict(
572                            server="checkServerDomainIpv6.com", use_ipv6=True
573                        ),
574                    ],
575                    source="Loopback888",
576                    trusted_keys=[
577                        dict(range_start=21),
578                        dict(range_end=13, range_start=3),
579                    ],
580                    update_calendar=True,
581                ),
582                state="overridden",
583            )
584        )
585        commands = []
586        result = self.execute_module(changed=False)
587        self.assertEqual(sorted(result["commands"]), sorted(commands))
588