-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathday-one-toolkit.py
739 lines (719 loc) · 29.3 KB
/
day-one-toolkit.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
#!/usr/bin/env python
# Author: Daniel Teycheney
# Import Modules
from nornir import InitNornir
from nornir_napalm.plugins.tasks import napalm_get
from nornir_utils.plugins.tasks.files import write_file
import json
import requests
import pathlib
from requests.packages.urllib3.exceptions import InsecureRequestWarning
import datetime as dt
import os
from os import environ
from colorama import Fore, init
# Disable urllib3 warnings
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
# Auto-reset colorama colours back after each print statement
init(autoreset=True)
# Gathering environmental variables and assigning to variables to use throughout code.
# Check whether NORNIR_DEFAULT_USERNAME variable has been set, not mandatory, but recommeneded
if environ.get("NORNIR_DEFAULT_USERNAME") is not None:
# Set the env_uname to this variable so it can be used for the Nornir inventory
env_uname = os.environ["NORNIR_DEFAULT_USERNAME"]
print(f"{Fore.CYAN}Environmental variable NORNIR_DEFAULT_USERNAME is set")
else:
# Print warning
print(
Fore.YELLOW
+ "*" * 15
+ " WARNING: Environmental variable `NORNIR_DEFAULT_USERNAME` not set. "
+ "*" * 15
)
# Set the env_uname to an empty string, so that the code does not error out.
# NOTE: It's valid form to use the groups.yaml and hosts.yaml file(s) to
# store credentials so this will not raise an exception
env_uname = ""
# Print supplementary warning
print(
Fore.MAGENTA
+ "*" * 15
+ " NOTIFICATION: Environmental variable `NORNIR_DEFAULT_USERNAME` now set to ''."
+ "This may cause all authentication to fail. "
+ "*" * 15
)
# Check whether NORNIR_DEFAULT_PASSWORD variable has been set, not mandatory, but recommeneded
if environ.get("NORNIR_DEFAULT_PASSWORD") is not None:
# Set the env_pword to this variable so it can be used for the Nornir inventory
env_pword = os.environ["NORNIR_DEFAULT_PASSWORD"]
print(f"{Fore.CYAN}Environmental variable NORNIR_DEFAULT_PASSWORD is set")
else:
print(
Fore.YELLOW
+ "*" * 15
+ " WARNING: Environmental variable `NORNIR_DEFAULT_PASSWORD` not set. "
+ "*" * 15
)
# Set the env_pword to an empty string, so that the code does not error out.
# NOTE: It's valid form to use the groups.yaml and hosts.yaml file(s) to
# store credentials so this will not raise an exception
env_pword = ""
print(
Fore.MAGENTA
+ "*" * 15
+ " NOTIFICATION: Environmental variable `NORNIR_DEFAULT_PASSWORD` now set to ''."
+ "This may cause all authentication to fail. "
+ "*" * 15
)
# Functions
def collect_getters(task, getter):
"""
This function is used to collect all applicable getters for the applicable OS
and then store these results under the respective facts/<hostname>/ directory.
:param task: The name of the task to be run.
:param getter: The name of the NAPALM getter.
:return: An AggregatedResult of this task.
"""
# Assign facts directory to variable
fact_dir = "facts"
# Assign hostname directory to a variable
host_dir = task.host.name
# Assign the destination directory to a variable. i.e facts/hostname/
entry_dir = fact_dir + "/" + host_dir
# Create facts directory and/or check that it exists
pathlib.Path(fact_dir).mkdir(exist_ok=True)
# Create entry directory and/or check that it exists
pathlib.Path(entry_dir).mkdir(exist_ok=True)
# Try/except block to catch exceptions, such as NotImplementedError
try:
# Gather facts using napalm_get and assign to a variable
facts_result = task.run(task=napalm_get, getters=[getter])
# Write the results to a JSON, using the convention <filter_name>.json
task.run(
task=write_file,
content=json.dumps(facts_result[0].result[getter], indent=2),
filename=f"" + str(entry_dir) + "/" + str(getter) + ".json", # noqa
) # noqa
# Handle NAPALM Not Implemented Error exceptions
except NotImplementedError:
return "Getter Not Implemented"
except AttributeError:
return "AttributeError: Driver has no attribute"
def collect_config(task, getter):
"""
This function is used to collect applicable configs getters for the applicable OS
and then store these results under the respective configs/<hostname>/ directory
:param task: The name of the task to be run.
:param getter: The name of the NAPALM config getter.
:return: An AggregatedResult of this task.
"""
# Assign configs directory to variable
config_dir = "configs"
# Assign hostname directory to a variable
host_dir = task.host.name
# Assign the destination directory to a variable. i.e configs/hostname/
entry_dir = config_dir + "/" + host_dir
# Create facts directory and/or check that it exists
pathlib.Path(config_dir).mkdir(exist_ok=True)
# Create entry directory and/or check that it exists
pathlib.Path(entry_dir).mkdir(exist_ok=True)
# Try/except block to catch exceptions, such as NotImplementedError
try:
# Gather config using napalm_get and assign to a variable
config_result = task.run(task=napalm_get, getters=["config"])
# Write the results to a JSON, using the convention <filter_name>.txt
task.run(
task=write_file,
content=config_result.result["config"][getter],
filename=f"" + str(entry_dir) + "/" + str(getter) + ".txt", # noqa
)
# Handle NAPALM Not Implemented Error exceptions
except NotImplementedError:
print(f"{Fore.YELLOW}NAPALM get filter not implemented " + str(getter))
def getter_collector(): # noqa
"""
This function is the main function of the toolkit.
It performs two roles:
1) Collects configurations for all devices in the inventory,
based on NAPALM support.
These configurations are saved in the configs/ directory using the following convention:
<hostname>/<filter_name>.txt
2) Performs a collection of supported getters based on
the official NAPALM supported filter list:
https://napalm.readthedocs.io/en/latest/support/
It has been written in a way whereby one simply updates the appropriate <os>_getters
list to add or remove supported getters. All getters are stored in the facts/
directory using the following convention:
<hostname>/<filter_name>.json
"""
"""
The following block of code is used to generate a log file in a directory.
These log files will indicate the success/failure of filter collector
for retrospective analysis.
"""
# Capture time
cur_time = dt.datetime.now()
# Cleanup time, so that the format is clean for the output file 2019-07-01-13-04-59
fmt_time = cur_time.strftime("%Y-%m-%d-%H-%M-%S")
# Set log directory variable
log_dir = "logs"
# Create log directory if it doesn't exist.
pathlib.Path(log_dir).mkdir(exist_ok=True)
# Create log file name, with timestamp in the name
filename = str("DISCOVERY-LOG") + "-" + fmt_time + ".txt"
# Join the log file name and log directory together into a variable
log_file_path = log_dir + "/" + filename
# Create the log file
log_file = open(log_file_path, "w")
# Start of logging output
print(f"{Fore.MAGENTA}STARTING DISCOVERY: " + str(fmt_time))
log_file.write("STARTING DISCOVERY: " + str(fmt_time) + "\n\n")
"""
Initialise two counters, so that success and failure can be counted
and incremented as the getters are collected.
"""
# Success Counter
success_count = 0
# Fail Counter
fail_count = 0
# Initialize Nornir and define the inventory variables.
nr = InitNornir(
inventory={
"options": {
"host_file": "inventory/hosts.yaml",
"group_file": "inventory/groups.yaml",
"defaults_file": "inventory/defaults.yaml",
}
}
)
# Set default username and password from environmental variables.
nr.inventory.defaults.username = env_uname
nr.inventory.defaults.password = env_pword
"""
The following block of lists are the supported getters per OS based
on the website https://napalm.readthedocs.io/en/latest/support/
"""
# IOS supported getters
ios_getters = [
"arp_table",
"bgp_neighbors",
"bgp_neighbors_detail",
"environment",
"facts",
"interfaces",
"interfaces_counters",
"interfaces_ip",
"ipv6_neighbors_table",
"lldp_neighbors",
"lldp_neighbors_detail",
"mac_address_table",
"network_instances",
"ntp_peers",
"ntp_servers",
"ntp_stats",
"optics",
"snmp_information",
"users",
]
# JUNOS supported getters
junos_getters = [
"arp_table",
"bgp_config",
"bgp_neighbors",
"bgp_neighbors_detail",
"environment",
"facts",
"interfaces",
"interfaces_counters",
"interfaces_ip",
"ipv6_neighbors_table",
"lldp_neighbors",
"lldp_neighbors_detail",
"mac_address_table",
"network_instances",
"ntp_peers",
"ntp_servers",
"ntp_stats",
"optics",
"snmp_information",
"users",
]
# EOS supported getters
eos_getters = [
"arp_table",
"bgp_config",
"bgp_neighbors",
"bgp_neighbors_detail",
"environment",
"facts",
"interfaces",
"interfaces_counters",
"interfaces_ip",
"lldp_neighbors",
"lldp_neighbors_detail",
"mac_address_table",
"network_instances",
"ntp_servers",
"ntp_stats",
"optics",
"snmp_information",
"users",
]
# NXOS supported getters
nxos_getters = [
"arp_table",
"bgp_neighbors",
"facts",
"interfaces",
"interfaces_ip",
"lldp_neighbors",
"lldp_neighbors_detail",
"mac_address_table",
"ntp_peers",
"ntp_servers",
"ntp_stats",
"snmp_information",
"users",
]
# IOSXR supported getters
iosxr_getters = [
"arp_table",
"bgp_config",
"bgp_neighbors",
"bgp_neighbors_detail",
"environment",
"facts",
"interfaces",
"interfaces_counters",
"interfaces_ip",
"lldp_neighbors",
"lldp_neighbors_detail",
"mac_address_table",
"ntp_peers",
"ntp_servers",
"ntp_stats",
"snmp_information",
"users",
]
"""
The following block of code assigns a filter based on platform to a variable.
This variable is used later on to apply logic in for loops
"""
ios_devices = nr.filter(platform="ios")
junos_devices = nr.filter(platform="junos")
eos_devices = nr.filter(platform="eos")
nxos_devices = nr.filter(platform="nxos")
iosxr_devices = nr.filter(platform="iosxr")
"""
The following block of code is a list of config getters which will be
iterated over to collect the different config types per OS
"""
ios_config_getters = ["running", "startup"]
junos_config_getters = ["running", "candidate"]
eos_config_getters = ["running", "startup"]
nxos_config_getters = ["running", "startup"]
iosxr_config_getters = ["running", "startup"]
"""
The following block is the main component of the program. Each OS collects
the running config, all supported getters and the startup/candidate config
based on the OS. Each OS block is as uniform as possible.
"""
# IOS Platform Block
for host in ios_devices.inventory.hosts.items():
# Assign the hostname to a variable from the host tuple
hostname = host[0]
# Starting processing of a host
print(f"{Fore.MAGENTA}** Start Processing Host: " + str(hostname))
log_file.write("** Start Processing Host: " + str(hostname) + "\n")
for config in ios_config_getters:
# Start collecting the config getters
print("Processing " + str(config) + " config ... ")
log_file.write("Processing " + str(config) + " config ... " + "\n")
# Execute the collect_config function
configs = nr.run(task=collect_config, getter=config, on_failed=True)
"""
Access the specific 'napalm_get' result out of the collect_getters function
and store whether the failed boolean is True (failure) or False (success)
"""
configs_results = configs[hostname][0].failed
# Conditional block to record success/fail count of the 'napalm_get' result
if configs_results is True:
print(
f"{Fore.RED}FAILURE : "
+ str(hostname)
+ " - "
+ str(config)
+ " config"
)
log_file.write(
"FAILURE : "
+ str(hostname)
+ " - "
+ str(config)
+ " config"
+ "\n"
)
fail_count += 1
else:
print(
f"{Fore.GREEN}SUCCESS : "
+ str(hostname)
+ " - "
+ str(config)
+ " config"
)
log_file.write(
"SUCCESS : "
+ str(hostname)
+ " - "
+ str(config)
+ " config"
+ "\n"
)
success_count += 1
# For block to collect all supported getters
for entry in ios_getters:
# Start processing getters
print("Processing Getter: " + str(entry))
log_file.write("Processing Getter: " + str(entry) + "\n")
# Execute collect_getters function
getters = nr.run(task=collect_getters, getter=entry, on_failed=True)
"""
Access the specific 'napalm_get' result out of the collect_getters function
and store whether the failed boolean is True (failure) or False (success)
"""
getters_results = getters[hostname][0].failed
# Conditional block to record success/fail count of the 'napalm_get' result
if getters_results is True:
log_file.write("FAILURE : " + str(hostname) + " - " + str(entry) + "\n")
print(f"{Fore.RED}FAILURE : " + str(hostname) + " - " + str(entry))
fail_count += 1
else:
log_file.write("SUCCESS : " + str(hostname) + " - " + str(entry) + "\n")
print(f"{Fore.GREEN}SUCCESS : " + str(hostname) + " - " + str(entry))
success_count += 1
# Ending processing of host
print(f"{Fore.MAGENTA}** End Processing Host: " + str(hostname))
log_file.write("** End Processing Host: " + str(hostname) + "\n\n")
# EOS Platform Block
for host in eos_devices.inventory.hosts.items():
# Assign the hostname to a variable from the host tuple
hostname = host[0]
# Starting processing of a host
print(f"{Fore.MAGENTA}** Start Processing Host: " + str(hostname))
log_file.write("** Start Processing Host: " + str(hostname) + "\n")
for config in eos_config_getters:
# Start collecting the config getters
print("Processing " + str(config) + " config ... ")
log_file.write("Processing " + str(config) + " config ... " + "\n")
# Execute the collect_config function
configs = nr.run(task=collect_config, getter=config, on_failed=True)
"""
Access the specific 'napalm_get' result out of the collect_getters function
and store whether the failed boolean is True (failure) or False (success)
"""
configs_results = configs[hostname][0].failed
# Conditional block to record success/fail count of the 'napalm_get' result
if configs_results is True:
print(
f"{Fore.RED}FAILURE : "
+ str(hostname)
+ " - "
+ str(config)
+ " config"
)
log_file.write(
"FAILURE : "
+ str(hostname)
+ " - "
+ str(config)
+ " config"
+ "\n"
)
fail_count += 1
else:
print(
f"{Fore.GREEN}SUCCESS : "
+ str(hostname)
+ " - "
+ str(config)
+ " config"
)
log_file.write(
"SUCCESS : "
+ str(hostname)
+ " - "
+ str(config)
+ " config"
+ "\n"
)
success_count += 1
# For block to collect all supported getters
for entry in eos_getters:
# Start processing getters
print("Processing Getter: " + str(entry))
log_file.write("Processing Getter: " + str(entry) + "\n")
# Execute collect_getters function
getters = nr.run(task=collect_getters, getter=entry, on_failed=True)
"""
Access the specific 'napalm_get' result out of the collect_getters function
and store whether the failed boolean is True (failure) or False (success)
"""
getters_results = getters[hostname][0].failed
# Conditional block to record success/fail count of the 'napalm_get' result
if getters_results is True:
log_file.write("FAILURE : " + str(hostname) + " - " + str(entry) + "\n")
print(f"{Fore.RED}FAILURE : " + str(hostname) + " - " + str(entry))
fail_count += 1
else:
log_file.write("SUCCESS : " + str(hostname) + " - " + str(entry) + "\n")
print(f"{Fore.GREEN}SUCCESS : " + str(hostname) + " - " + str(entry))
success_count += 1
# Ending processing of host
print(f"{Fore.MAGENTA}** End Processing Host: " + str(hostname))
log_file.write("** End Processing Host: " + str(hostname) + "\n\n")
# NX-OS Platform Block
for host in nxos_devices.inventory.hosts.items():
# Assign the hostname to a variable from the host tuple
hostname = host[0]
# Starting processing of a host
print(f"{Fore.MAGENTA}** Start Processing Host: " + str(hostname))
log_file.write("** Start Processing Host: " + str(hostname) + "\n")
for config in nxos_config_getters:
# Start collecting the config getters
print("Processing " + str(config) + " config ... ")
log_file.write("Processing " + str(config) + " config ... " + "\n")
# Execute the collect_config function
configs = nr.run(task=collect_config, getter=config, on_failed=True)
"""
Access the specific 'napalm_get' result out of the collect_getters function
and store whether the failed boolean is True (failure) or False (success)
"""
configs_results = configs[hostname][0].failed
# Conditional block to record success/fail count of the 'napalm_get' result
if configs_results is True:
print(
f"{Fore.RED}FAILURE : "
+ str(hostname)
+ " - "
+ str(config)
+ " config"
)
log_file.write(
"FAILURE : "
+ str(hostname)
+ " - "
+ str(config)
+ " config"
+ "\n"
)
fail_count += 1
else:
print(
f"{Fore.GREEN}SUCCESS : "
+ str(hostname)
+ " - "
+ str(config)
+ " config"
)
log_file.write(
"SUCCESS : "
+ str(hostname)
+ " - "
+ str(config)
+ " config"
+ "\n"
)
success_count += 1
# For block to collect all supported getters
for entry in nxos_getters:
# Start processing getters
print("Processing Getter: " + str(entry))
log_file.write("Processing Getter: " + str(entry) + "\n")
# Execute collect_getters function
getters = nr.run(task=collect_getters, getter=entry, on_failed=True)
"""
Access the specific 'napalm_get' result out of the collect_getters function
and store whether the failed boolean is True (failure) or False (success)
"""
getters_results = getters[hostname][0].failed
# Conditional block to record success/fail count of the 'napalm_get' result
if getters_results is True:
log_file.write("FAILURE : " + str(hostname) + " - " + str(entry) + "\n")
print(f"{Fore.RED}FAILURE : " + str(hostname) + " - " + str(entry))
fail_count += 1
else:
log_file.write("SUCCESS : " + str(hostname) + " - " + str(entry) + "\n")
print(f"{Fore.GREEN}SUCCESS : " + str(hostname) + " - " + str(entry))
success_count += 1
# Ending processing of host
print(f"{Fore.MAGENTA}** End Processing Host: " + str(hostname) + "\n")
log_file.write("** End Processing Host: " + str(hostname) + "\n\n")
# JUNOS Platform Block
for host in junos_devices.inventory.hosts.items():
# Assign the hostname to a variable from the host tuple
hostname = host[0]
# Starting processing of a host
print(f"{Fore.MAGENTA}** Start Processing Host: " + str(hostname))
log_file.write("** Start Processing Host: " + str(hostname) + "\n")
for config in junos_config_getters:
# Start collecting the config getters
print("Processing " + str(config) + " config ... ")
log_file.write("Processing " + str(config) + " config ... " + "\n")
# Execute the collect_config function
configs = nr.run(task=collect_config, getter=config, on_failed=True)
"""
Access the specific 'napalm_get' result out of the collect_getters function
and store whether the failed boolean is True (failure) or False (success)
"""
configs_results = configs[hostname][0].failed
# Conditional block to record success/fail count of the 'napalm_get' result
if configs_results is True:
print(
f"{Fore.RED}FAILURE : "
+ str(hostname)
+ " - "
+ str(config)
+ " config"
)
log_file.write(
"FAILURE : "
+ str(hostname)
+ " - "
+ str(config)
+ " config"
+ "\n"
)
fail_count += 1
else:
print(
f"{Fore.GREEN}SUCCESS : "
+ str(hostname)
+ " - "
+ str(config)
+ " config"
)
log_file.write(
"SUCCESS : "
+ str(hostname)
+ " - "
+ str(config)
+ " config"
+ "\n"
)
success_count += 1
for entry in junos_getters:
# Start processing getters
print("Processing Getter: " + str(entry))
log_file.write("Processing Getter: " + str(entry) + "\n")
# Execute collect_getters function
getters = nr.run(task=collect_getters, getter=entry, on_failed=True)
"""
Access the specific 'napalm_get' result out of the collect_getters function
and store whether the failed boolean is True (failure) or False (success)
"""
getters_results = getters[hostname][0].failed
# Conditional block to record success/fail count of the 'napalm_get' result
if getters_results is True:
log_file.write("FAILURE : " + str(hostname) + " - " + str(entry) + "\n")
print(f"{Fore.RED}FAILURE : " + str(hostname) + " - " + str(entry))
fail_count += 1
else:
log_file.write("SUCCESS : " + str(hostname) + " - " + str(entry) + "\n")
print(f"{Fore.GREEN}SUCCESS : " + str(hostname) + " - " + str(entry))
success_count += 1
# Ending processing of host
print("** End Processing Host: " + str(hostname) + "\n")
log_file.write("** End Processing Host: " + str(hostname) + "\n\n")
# IOS-XR Platform Block
for host in iosxr_devices.inventory.hosts.items():
# Assign the hostname to a variable from the host tuple
hostname = host[0]
# Starting processing of a host
print(f"{Fore.MAGENTA}** Start Processing Host: " + str(hostname))
log_file.write("** Start Processing Host: " + str(hostname) + "\n")
for config in iosxr_config_getters:
# Start collecting the config getters
print("Processing " + str(config) + " config ... ")
log_file.write("Processing " + str(config) + " config ... " + "\n")
# Execute the collect_config function
configs = nr.run(task=collect_config, getter=config, on_failed=True)
"""
Access the specific 'napalm_get' result out of the collect_getters function
and store whether the failed boolean is True (failure) or False (success)
"""
configs_results = configs[hostname][0].failed
# Conditional block to record success/fail count of the 'napalm_get' result
if configs_results is True:
print(
f"{Fore.RED}FAILURE : "
+ str(hostname)
+ " - "
+ str(config)
+ " config"
)
log_file.write(
"FAILURE : "
+ str(hostname)
+ " - "
+ str(config)
+ " config"
+ "\n"
)
fail_count += 1
else:
print(
f"{Fore.GREEN}SUCCESS : "
+ str(hostname)
+ " - "
+ str(config)
+ " config"
)
log_file.write(
"SUCCESS : "
+ str(hostname)
+ " - "
+ str(config)
+ " config"
+ "\n"
)
success_count += 1
# For block to collect all supported getters
for entry in iosxr_getters:
# Start processing getters
print("Processing Getter: " + str(entry))
log_file.write("Processing Getter: " + str(entry) + "\n")
# Execute collect_getters function
getters = nr.run(task=collect_getters, getter=entry, on_failed=True)
"""
Access the specific 'napalm_get' result out of the collect_getters function
and store whether the failed boolean is True (failure) or False (success)
"""
getters_results = getters[hostname][0].failed
# Conditional block to record success/fail count of the 'napalm_get' result
if getters_results is True:
log_file.write("FAILURE : " + str(hostname) + " - " + str(entry) + "\n")
print(f"{Fore.RED}FAILURE : " + str(hostname) + " - " + str(entry))
fail_count += 1
else:
log_file.write("SUCCESS : " + str(hostname) + " - " + str(entry) + "\n")
print(f"{Fore.GREEN}SUCCESS : " + str(hostname) + " - " + str(entry))
success_count += 1
# Ending processing of host
print("** End Processing Host: " + str(hostname))
log_file.write("** End Processing Host: " + str(hostname) + "\n\n")
# Add the two variables together to get a total count into a variable
total_count = success_count + fail_count
# Provide a summary of the main function and add to log file
print("SUMMARY" + "\n")
log_file.write("SUMMARY" + "\n\n")
print(f"{Fore.GREEN}SUCCESS COUNT : " + str(success_count))
log_file.write("SUCCESS COUNT : " + str(success_count) + "\n")
print(f"{Fore.RED}FAILURE COUNT : " + str(fail_count))
log_file.write("FAILURE COUNT : " + str(fail_count) + "\n")
print("TOTAL COUNT : " + str(total_count))
log_file.write("TOTAL COUNT : " + str(total_count) + "\n")
# Close the log file
log_file.close()
# Execute main program
getter_collector()