-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparse-and-upload.py
153 lines (130 loc) · 4.85 KB
/
parse-and-upload.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
import xmltodict
import pprint
import json
import configparser
import sys
import argparse
from pymongo import MongoClient
def parse_command_line():
# hha [-c config file ] cisco_config.xml
# --config -c config file name - default is parse.conf
parser = argparse.ArgumentParser(description='Parce Cisco config in XML form and upload it to MongoDB.')
parser.add_argument('-c', '--config', type=argparse.FileType('r'), nargs='?',default='parse.conf', help='%(prog)s configuration file')
parser.add_argument(metavar='configuration_file.xml', dest='input_file', type=argparse.FileType('r'), help='Cisco router config in XML format "sh run | format xml"')
parser.add_argument('-v','--version', action='version', version='%(prog)s 0.01')
args = parser.parse_args()
return args
#end of parse_command_line()
def load_configuration_file(config_file_handler):
config_defaults = {'database_host': '127.0.0.1',
'database_port': 27017,
'database_user': '',
'database_password': '',
'database_name': 'config-database'
}
config = configparser.ConfigParser(config_defaults)
try:
config.read_file(config_file_handler)
except Error:
print("Unexpected error:", sys.exc_info()[0])
quit(1)
# end of load_configuration_file()
def config_iterator(config_dict, database_export_dict, depth):
# yes, I know how wastefull such recursion is
# print("Down Depth: ", depth)
depth = depth + 1
if type(config_dict) == list: ### !!!! OH it is a list, need to dive to each element of it
for item in config_dict:
config_iterator(item, database_export_dict, depth) # RECURSION !!!!
else: # it is no a list, keep diving.
for config_item in database_export_dict:
if config_item in config_dict: # does this branch present in config?
# print("Desending down to: ", config_item, " Type: ", type(database_export_dict[config_item]))
if type(database_export_dict[config_item]) == str: # end of the way. Leaf.
# print("Leaf reached: ", config_item, "Depth: ", depth)
for item in config_dict:
if item == config_item:
if type(config_dict[item]) == list : # need to iterate over all elements.
collection = db[database_export_dict[config_item]]
for list_item in config_dict[item]:
# print(database_export_dict[config_item], " ---- ", json.dumps(list_item))
collection.insert_one(list_item)
else:
collection = db[database_export_dict[config_item]]
# print(database_export_dict[config_item], " ---- ", json.dumps(config_dict[config_item]))
collection.insert_one(config_dict[config_item])
else:
# we are not yet in leaf
for item in database_export_dict:
if item == config_item:
# print("Item: ", item, "Dept: ", depth)
config_iterator(config_dict[config_item], database_export_dict[item], depth) # RECURSION !!!!
depth = depth - 1
# print("Up Depth: ", depth)
# end of config_iterator
#### --- Main() --- ####
pp = pprint.PrettyPrinter(indent=1)
args = parse_command_line()
load_configuration_file(vars(args)['config'])
file_h = vars(args)['input_file']
config_dict = xmltodict.parse(file_h.read())['Device-Configuration']
database_client = MongoClient()
database_client.drop_database('test-database')
db = database_client['test-database']
database_export_dict = {
'hostname' : 'hostname',
'vrf': {'definition': 'vrf_list'},
'ip': {'vrf': 'vrf_list', 'prefix-list': 'prefix_list'},
'interface' : 'interfaces',
'route-map': 'route_map',
'access-list' : 'access_lists'
}
config_iterator(config_dict, database_export_dict, 0)
file_h.close()
quit()
"""
odict_keys(['version',
'service',
'platform',
'hostname',
'boot-start-marker',
'boot',
'boot-end-marker',
'aqm-register-fnf',
'vrf',
'logging',
'enable',
'aaa',
'process',
'clock',
'ip', - -there are VRF there too.
'login',
'ipv6',
'subscriber',
'mpls',
'clns',
'multilink',
'l2vpn',
'key',
'X-Interface',
'spanning-tree',
'username',
'redundancy',
'class-map',
'policy-map',
'class',
'description',
'interface',
'router',
'access-list',
'route-map',
'snmp-server',
'snmp',
'tacacs-server',
'tacacs',
'control-plane',
'banner',
'line',
'ntp',
'end'])
"""