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