-
Notifications
You must be signed in to change notification settings - Fork 1
/
get_configs.py
150 lines (125 loc) · 4.8 KB
/
get_configs.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
from nornir import InitNornir
from nornir.plugins.tasks.networking import netmiko_send_command
from getpass import getpass
from nornsible import InitNornsible, nornsible_task
from termcolor import colored
from nornir.core.task import Result
import os
def format_dir_vars(dir_var):
if isinstance(dir_var, str) != True:
raise ValueError(f"variable passed into 'format_dir_vars' function is not of type string")
"""
Make sure environment variables which specify a directory are formatted
correctly for use in script functions
"""
if dir_var[-1] != '/':
dir_var = dir_var + '/'
return dir_var
def update_creds(nr):
"""
Update username and password on nornir object at run time with user provided credentials
User provided credentials will only be queried if username/password isn't set in inventory
"""
for host, data in nr.inventory.hosts.items():
if nr.inventory.hosts[host].username == None:
username = input('Username: ')
break
for host, data in nr.inventory.hosts.items():
if nr.inventory.hosts[host].password == None:
password = getpass('Password: ')
break
for host, data in nr.inventory.hosts.items():
if nr.inventory.hosts[host].password:
continue
else:
nr.inventory.hosts[host].password = password
for host, data in nr.inventory.hosts.items():
if nr.inventory.hosts[host].username:
continue
else:
nr.inventory.hosts[host].username = username
@nornsible_task
def get_configs(task):
"""
Get config and state information from devices according to commands specified
in 'get_config_commands' nornir attribute
"""
commands = task.host['get_config_commands']
path = f"{CONFIGS_DIR}{task.host.name}/"
get_config_results = []
if os.path.isdir(path) == False:
os.makedirs(path)
for command in commands:
result = task.run(task=netmiko_send_command, command_string=command)
result = result[0].result
filename = f"{path}{command}.ios"
try:
with open(filename, 'r') as f:
current_contents = f.read()
if result != current_contents:
with open(filename, 'w') as f:
f.write(result)
get_config_results.append({
'command': command,
'color': 'yellow',
'changed': True,
})
elif result == current_contents:
get_config_results.append({
'command': command,
'color': 'green',
'changed': False,
})
except FileNotFoundError:
with open(filename, 'w') as f:
f.write(result)
get_config_results.append({
'command': command,
'color': 'yellow',
'changed': True,
})
task.host['get_config_results'] = get_config_results
@nornsible_task
def print_failed_hosts(task):
"""
Print message indicatin any hosts on which config/state information
extraction failed.
"""
print(colored(f'Failed to get config/state info from {task.host}', 'red'))
@nornsible_task
def print_get_cfg_results(task):
"""
Print Get Config Results with colors indicating whether the file changed or not
"""
results = task.host['get_config_results']
print(colored(f"\n{task.host.name}", 'blue'))
print('-' * 20)
for result in results:
if result['changed'] == True:
print(colored(f"{result['command']} -----> Changed: True", result['color']))
if result['changed'] == False:
print(colored(f"{result['command']} -----> Changed: False", result['color']))
def git_commit():
"""
commit changes to a local git repo for analysis of changes between script executions
"""
os.chdir(CONFIGS_DIR)
os.system('git add --all > /dev/null')
os.system("git commit -m 'Git Commit by Python getconfigs.py Script' > /dev/null")
NORNIR_CONFIG_FILE = os.environ['NORNIR_CONFIG_FILE']
CONFIGS_DIR = format_dir_vars(os.environ['CONFIGS_DIR'])
def main():
# Initialize Nornir objects, filter with nornsible, remove delegate from nornsible returned hosts
nr = InitNornir(config_file=NORNIR_CONFIG_FILE)
nr = InitNornsible(nr)
nr.inventory.hosts.pop('delegate')
# Get credentials and assign to nornir inventory objects if they are not already specified
update_creds(nr)
# Get Configs from devices. Print Results
nr.run(task=get_configs)
nr.run(task=print_failed_hosts, on_good=False, on_failed=True, num_workers=1)
nr.run(task=print_get_cfg_results, num_workers=1)
# Commit to git
git_commit()
if __name__ == "__main__":
main()