cisco-config-parser 2.2.4__tar.gz → 2.2.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. cisco_config_parser-2.2.6/PKG-INFO +721 -0
  2. cisco_config_parser-2.2.6/README.md +711 -0
  3. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/__init__.py +2 -2
  4. cisco_config_parser-2.2.6/cisco_config_parser/cisco_config_parser.py +3 -0
  5. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/global_search/global_parser.py +1 -1
  6. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/global_search/global_separator.py +1 -1
  7. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/layer2_interface/l2_interface_parser.py +17 -2
  8. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/layer2_interface/l2_interface_separator.py +1 -1
  9. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/layer3_interface/l3_interface_parser.py +9 -4
  10. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/layer3_interface/l3_interface_separator.py +2 -2
  11. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/layer3_interface/l3_section_parser.py +1 -1
  12. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/old_version/old_parse.py +1 -1
  13. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/parent_child/parent_child_parser.py +1 -34
  14. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/parser/__init__.py +13 -1
  15. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/parser/parser.py +4 -6
  16. cisco_config_parser-2.2.6/cisco_config_parser/parser_regex/__init__.py +4 -0
  17. cisco_config_parser-2.2.6/cisco_config_parser/parser_regex/common_regex.py +18 -0
  18. cisco_config_parser-2.2.4/cisco_config_parser/parser_regex/regex.py → cisco_config_parser-2.2.6/cisco_config_parser/parser_regex/ios_regex.py +2 -12
  19. cisco_config_parser-2.2.6/cisco_config_parser/parser_regex/nxos_regex.py +23 -0
  20. cisco_config_parser-2.2.6/cisco_config_parser/routing_protocol/__init__.py +5 -0
  21. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/routing_protocol/ios/rtp_bgp.py +1 -1
  22. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/routing_protocol/ios/rtp_eigtp.py +4 -4
  23. cisco_config_parser-2.2.6/cisco_config_parser/routing_protocol/ios/rtp_ios_rtp_obj.py +134 -0
  24. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/routing_protocol/ios/rtp_ospf.py +3 -2
  25. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/routing_protocol/ios/rtp_static.py +3 -3
  26. cisco_config_parser-2.2.4/cisco_config_parser/routing_protocol/ios/rtp_ios_rtp_obj.py → cisco_config_parser-2.2.6/cisco_config_parser/routing_protocol/nxos/rtp_nxos_rtp_obj.py +4 -8
  27. cisco_config_parser-2.2.6/cisco_config_parser/routing_protocol/nxos/rtp_static.py +91 -0
  28. cisco_config_parser-2.2.6/cisco_config_parser/routing_protocol/nxos/rtp_vxlan.py +0 -0
  29. cisco_config_parser-2.2.6/cisco_config_parser/routing_protocol/utils/__init__.py +3 -0
  30. cisco_config_parser-2.2.4/cisco_config_parser/routing_protocol/utils/rtp_separator.py → cisco_config_parser-2.2.6/cisco_config_parser/routing_protocol/utils/rtp_ios_separator.py +1 -1
  31. cisco_config_parser-2.2.6/cisco_config_parser/routing_protocol/utils/rtp_nxos_separator.py +68 -0
  32. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/routing_protocol/utils/utils.py +13 -2
  33. cisco_config_parser-2.2.6/cisco_config_parser/routing_protocol/xr/__init__.py +0 -0
  34. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/separator/separator.py +2 -3
  35. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/setup.py +1 -1
  36. cisco_config_parser-2.2.6/cisco_config_parser.egg-info/PKG-INFO +721 -0
  37. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser.egg-info/SOURCES.txt +10 -2
  38. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/setup.py +1 -1
  39. cisco_config_parser-2.2.4/PKG-INFO +0 -385
  40. cisco_config_parser-2.2.4/README.md +0 -375
  41. cisco_config_parser-2.2.4/cisco_config_parser/cisco_config_parser.py +0 -3
  42. cisco_config_parser-2.2.4/cisco_config_parser/parser_regex/__init__.py +0 -2
  43. cisco_config_parser-2.2.4/cisco_config_parser/routing_protocol/__init__.py +0 -5
  44. cisco_config_parser-2.2.4/cisco_config_parser.egg-info/PKG-INFO +0 -385
  45. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/global_search/__init__.py +0 -0
  46. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/global_search/global_obj.py +0 -0
  47. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/global_search/ios/__init__.py +0 -0
  48. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/global_search/nxos/__init__.py +0 -0
  49. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/global_search/xr/__init__.py +0 -0
  50. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/helper/__init__.py +0 -0
  51. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/helper/help.py +0 -0
  52. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/helper/helper.py +0 -0
  53. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/layer2_interface/__init__.py +0 -0
  54. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/layer2_interface/l2_interface_obj.py +0 -0
  55. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/layer2_interface/l2_section_parser.py +0 -0
  56. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/layer3_interface/__init__.py +0 -0
  57. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/layer3_interface/l3_interface_obj.py +0 -0
  58. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/old_version/__init__.py +0 -0
  59. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/old_version/exceptions.py +0 -0
  60. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/old_version/obj.py +0 -0
  61. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/old_version/ssh.py +0 -0
  62. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/old_version/utils.py +0 -0
  63. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/parent_child/__init__.py +0 -0
  64. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/parent_child/parent_child_obj.py +0 -0
  65. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/parent_child/parent_child_separator.py +0 -0
  66. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/routing_protocol/ios/__init__.py +0 -0
  67. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/routing_protocol/nxos/__init__.py +0 -0
  68. /cisco_config_parser-2.2.4/cisco_config_parser/routing_protocol/utils/__init__.py → /cisco_config_parser-2.2.6/cisco_config_parser/routing_protocol/nxos/rtp_bgp.py +0 -0
  69. /cisco_config_parser-2.2.4/cisco_config_parser/routing_protocol/xr/__init__.py → /cisco_config_parser-2.2.6/cisco_config_parser/routing_protocol/nxos/rtp_ospf.py +0 -0
  70. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser/separator/__init__.py +0 -0
  71. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser.egg-info/dependency_links.txt +0 -0
  72. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/cisco_config_parser.egg-info/top_level.txt +0 -0
  73. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/pyproject.toml +0 -0
  74. {cisco_config_parser-2.2.4 → cisco_config_parser-2.2.6}/setup.cfg +0 -0
@@ -0,0 +1,721 @@
1
+ Metadata-Version: 2.1
2
+ Name: cisco_config_parser
3
+ Version: 2.2.6
4
+ Summary: This library is used for Network Automation involving Cisco Routers and Switch. It will parse Cisco IOS, IOS-XE, IOS-XR, and NXOS configuration file into objects and/or json format
5
+ Home-page: https://github.com/arezazadeh/cisco_config_parser
6
+ Author: Ahmad Rezazadeh
7
+ Author-email: ahmad@klevernet.io
8
+ License: MIT License
9
+ Description-Content-Type: text/markdown
10
+
11
+ # Cisco Configuration Parser
12
+
13
+ ## Overview
14
+ The **Cisco Configuration Parser** is a Python library designed for network automation tasks, specifically focusing on parsing configuration files from Cisco routers and switches. It supports Cisco IOS, IOS-XE, IOS-XR, and NXOS platforms. This library allows you to convert running configuration files into structured Python objects or JSON/dictionary formats for easier analysis, modification, or automation.
15
+
16
+ ## Key Features
17
+
18
+ ### <li> Platform Detection
19
+ This library is designed to be **platform agnostic**, meaning it can automatically determine the Cisco platform based on the syntax of the configuration file. In cases where the platform cannot be determined automatically, you can manually specify the platform by passing `platform="IOS/XR/NXOS"` to the parser.
20
+
21
+ ### <li> Flexible Data Handling
22
+ The parser can convert configuration data into either Python objects or JSON/dictionary formats. You can control the format by passing the `return_json=True` flag to the relevant method. This flexibility allows you to integrate with a wide range of automation workflows and tools.
23
+
24
+ ### <li> Configuration Hierarchy Recognition
25
+ Cisco configurations often feature a mix of parent-child relationships and standalone entries. This library is adept at recognizing and parsing these patterns to capture both common and critical configuration attributes. For instance:
26
+
27
+ - **Standalone Configuration Example:**
28
+ ```bash
29
+ hostname switch01.net
30
+ ```
31
+
32
+ - **Parent-Child Configuration Example:**
33
+
34
+ ```bash
35
+ Vlan 100 <<<< Parent
36
+ name DATA_VLAN <<<< Child
37
+ ```
38
+
39
+ This library tries to captures the important and common attributes of the configurations for different sections and convert them to python objects or json/dict format.
40
+
41
+ Some of those configs are as follow:
42
+
43
+ ```python
44
+ - Hostname,
45
+ - AAA,
46
+ - Interface,
47
+ - VLAN,
48
+ - Interface (Layer2 and Layer3),
49
+ - Access-list,
50
+ - Prefix-list,
51
+ - Prefix-set (IOS-XR)
52
+ - Route-map,
53
+ - Route-policy (IOS-XR),
54
+ - Static Routes,
55
+ - Dynamic Routes
56
+ - RIP
57
+ - EIGRP
58
+ - OSPF
59
+ - IS-IS
60
+ - BGP
61
+ - VXLAN Related Configs (NXOS)
62
+ - BGP EVPN MP-BGP
63
+ - NVE Config
64
+ - Anycast Gateway Config
65
+
66
+ - Line-vty
67
+ - Line-con
68
+ - Banner
69
+ ```
70
+ Above configuration sections are captured along with the most common attributes/children. and the rest of them are captured inside method `obj.children`.
71
+
72
+ ### <li> Parent/Child Regex Parsing Capabilities
73
+ In addition to above default behavior or the library, you also have the option to pass your own regex to the `ConfigParser` as either `parent_regex=r"<custom_regex>", child_regex=r"<custom_regex>"` or only `parent_regex=r"<custom_regex>"`.
74
+
75
+ **Note:** If you pass both `parent_regex` and `child_regex`, the library attempt to search for the parent and the only child that you have searched for. If you would like to get all the children, then just pass the `parent_regex` to the class. I will have some example at the bottom this document.
76
+
77
+
78
+ ## <li> Install the package
79
+ This package is available on `pypi.org` you can install the package via `pip`.
80
+
81
+ https://pypi.org/project/cisco-config-parser/
82
+
83
+ ```bash
84
+ pip install cisco-config-parser
85
+ ```
86
+
87
+
88
+ ## <li> Current Classes in this library
89
+
90
+ ```python
91
+ IOSStaticRouteConfig
92
+ IOSOSPFConfig
93
+ IOSEIGRPConfig
94
+ IOSBGPConfig
95
+ IOSBGPConfig
96
+ L3InterfaceParser
97
+ L2InterfaceParser
98
+ ParentChildParser
99
+ ```
100
+
101
+ There more Classes are being built, and will be released in the upcoming versions.
102
+
103
+ ## <li> Get Example usage:
104
+ A short documentation is embeded in the code base. you can view those example by importing `helper` and calling the class
105
+
106
+ ```python
107
+ from cisco_config_parser.helper import helper
108
+
109
+ helper = helper.IOSStaticRouteConfig()
110
+
111
+ print(helper)
112
+ ```
113
+
114
+ **Output**:
115
+ ```
116
+
117
+ Example Usage:
118
+ ====================================================================================================
119
+
120
+ with open("show_run.txt", "r") as file_output:
121
+ content = file_output.read()
122
+
123
+
124
+ obj = ConfigParser(content)
125
+
126
+ obj.get_static_routes() << Returns a list of objects
127
+ obj.get_static_routes(return_json=True) << Returns a list of dictionaries
128
+
129
+ ```
130
+ ## <li> Examples:
131
+
132
+ ## <li> Loading the Running-Config File
133
+
134
+ ```python
135
+ >>> ios_file = "/Users/fileFolder/devFolder/config.txt"
136
+ >>> with open(ios_file, "r") as f:
137
+ running_config = f.read()
138
+
139
+ >>> from cisco_config_parser import ConfigParser
140
+ >>>
141
+ >>> parser = ConfigParser(running_config)
142
+ ```
143
+
144
+
145
+ ## <li> Layer3 Interface
146
+
147
+ In layer-3 interface, the class attempts to capture all the important attributes of the interface, such as:
148
+
149
+ - IPv4 Address
150
+ - Subnet
151
+ - Subnet Mask
152
+ - Secondary IPv4 Address
153
+ - Secondary Subnet
154
+ - Secondary Subnet Mask
155
+ - HSRP or VRRP Config
156
+ - VIP
157
+
158
+ ### <li> Subnet list and their Usages
159
+
160
+ One of the great feature in this library is it captures all the subnets that are being used in your Network Device along with their usage.
161
+ Also it tells you how many of each subnet masks are being used as well. I personaly use this feature when i need to automate DHCP/IPAM documentaion cleanup.
162
+
163
+ **Example below illustriates this feature:**
164
+
165
+ ```python
166
+ >>> subnet_usage = parser.get_subnet_and_usage(include_subnet_count=True)
167
+ >>> print(json.dumps(subnet_usage, indent=4))
168
+
169
+ {
170
+ "Loopback100": "10.241.17.8/32",
171
+ "Loopback200": "10.252.248.1/32",
172
+ "Vlan200": "10.252.182.0/23",
173
+ "Vlan300": "10.244.16.160/27",
174
+ "Vlan310": "10.241.101.80/28",
175
+ "Vlan400": "10.39.10.32/27",
176
+ "Vlan700": "172.31.81.0/25",
177
+ "Vlan1100": "10.242.12.0/26",
178
+ "Vlan1125": "10.241.8.0/27",
179
+ "Vlan1126": "10.241.8.32/27",
180
+ "Vlan1127": "10.241.8.64/27",
181
+ "subnet_count": {
182
+ "/32": 2,
183
+ "/23": 1,
184
+ "/27": 5,
185
+ "/28": 1,
186
+ "/25": 1,
187
+ "/26": 1,
188
+ }
189
+ }
190
+ ```
191
+
192
+ ### <li> Layer3 Interfaces - List of Objects
193
+
194
+ ```python
195
+ >>> l3_interfaces = parser.get_l3_interfaces()
196
+ >>>for l3 in l3_interfaces:
197
+ print(l3.name)
198
+ print(l3.ip_address, l3.subnet)
199
+ print("!")
200
+
201
+ Loopback100
202
+ 10.241.17.8 10.241.17.8/32
203
+ !
204
+ Loopback200
205
+ 10.252.248.1 10.252.248.1/32
206
+ !
207
+ Loopback202
208
+ 10.245.0.199 10.245.0.199/32
209
+ ```
210
+ ### <li> Layer3 Interfaces - Json/Dict Format
211
+
212
+ ```python
213
+ >>> l3_interfaces = parser.get_l3_interfaces(return_json=True)
214
+ >>> print(json.dumps(l3_interfaces, indent=4))
215
+ [
216
+ {
217
+ "name": "Loopback100",
218
+ "description": "SWITCH01-SA01 Loopback IP",
219
+ "ip_address": "10.241.17.8",
220
+ "mask": "255.255.255.255",
221
+ "subnet": "10.241.17.8/32",
222
+ "helpers": null,
223
+ "sec_ip_address": null,
224
+ "sec_mask": null,
225
+ "sec_subnet": null,
226
+ "vrf": "mgt100",
227
+ "state": null,
228
+ "vip": null,
229
+ "children": [
230
+ "description SWITCH01-SA01 Loopback IP",
231
+ "ip vrf forwarding mgt100",
232
+ "ip address 10.241.17.8 255.255.255.255",
233
+ "ip pim sparse-mode",
234
+ "ip ospf 100 area 0"
235
+ ]
236
+ },
237
+ ]
238
+ ```
239
+
240
+ ### <li> Layer3 Interfaces - Custom Key/Value and Regex
241
+
242
+ ```python
243
+ >>> l3_interfaces = parser.get_l3_interfaces(ip_pim="ip pim.*")
244
+ >>> for i in l3_interfaces:
245
+ print(i.name)
246
+ print(i.ip_pim)
247
+ print("!")
248
+
249
+ Loopback100
250
+ ip pim sparse-mode
251
+ !
252
+ Loopback200
253
+ ip pim sparse-mode
254
+ !
255
+ ```
256
+
257
+ ## <li> Layer2 `Access` and `Trunk` Interface
258
+
259
+ ### <li> `Access Port` List of Objects
260
+
261
+ ```python
262
+ >>> access_ports = parser.get_l2_access_interfaces()
263
+ >>>
264
+ >>> for intf in access_ports:
265
+ print(intf.name)
266
+ print(intf.description)
267
+ print(intf.children)
268
+ print("!")
269
+ ...
270
+ GigabitEthernet1/1
271
+ Data Users
272
+ ['description Data Users', 'switchport access vlan 200', 'switchport mode access', 'switchport voice vlan 700', 'no logging event power-inline-status', 'ip dhcp snooping information option allow-untrusted']
273
+ !
274
+ GigabitEthernet1/2
275
+ Data Users
276
+ ['description Data Users', 'switchport access vlan 200', 'switchport mode access', 'switchport voice vlan 700', 'no logging event power-inline-status', 'ip dhcp snooping information option allow-untrusted']
277
+ !
278
+ ```
279
+
280
+ ### <li> `Access Port` the json/dict format:
281
+
282
+ ```python
283
+ >>> access_ports = parser.get_l2_access_interfaces(return_json=True)
284
+
285
+ >>> print(json.dumps(access_ports, indent=4))
286
+
287
+ [
288
+ {
289
+ "name": "GigabitEthernet1/1",
290
+ "description": "DATA Users",
291
+ "data_vlan": "200",
292
+ "voice_vlan": "700",
293
+ "state": null,
294
+ "spanning_tree": null,
295
+ "native_vlan": null,
296
+ "children": [
297
+ "description DATA Users",
298
+ "switchport access vlan 200",
299
+ "switchport mode access",
300
+ "switchport voice vlan 700",
301
+ "no logging event power-inline-status",
302
+ "ip dhcp snooping information option allow-untrusted"
303
+ ]
304
+ },
305
+ ]
306
+ ```
307
+ ### <li> `Access Port` Custom Key/method search
308
+
309
+ You can use your own custom regex with your own key, this key then become a dynamic method of the class where you can either call it or recieve it as json format.
310
+
311
+
312
+ ```python
313
+ >>> access_ports = parser.get_l2_access_interfaces(logging="no loggin.*", return_json=True)
314
+
315
+ >>> print(json.dumps(access_ports, indent=4))
316
+
317
+ [
318
+ {
319
+ "name": "GigabitEthernet1/1",
320
+ "description": "SHC-Users",
321
+ "data_vlan": "200",
322
+ "voice_vlan": "700",
323
+ "state": null,
324
+ "spanning_tree": null,
325
+ "native_vlan": null,
326
+ "children": [
327
+ "description SHC-Users",
328
+ "switchport access vlan 200",
329
+ "switchport mode access",
330
+ "switchport voice vlan 700",
331
+ "no logging event power-inline-status",
332
+ "ip dhcp snooping information option allow-untrusted"
333
+ ],
334
+ "logging": "no logging event power-inline-status" <<<<< custom Key to find logging command
335
+ },
336
+ ]
337
+ ```
338
+
339
+ ### <li> `Trunk Port` List of Objects
340
+
341
+ ```python
342
+ >>> trunk_interfaces = parser.get_l2_trunk_interfaces()
343
+
344
+ >>> for intf in trunk_interfaces:
345
+ print(intf.name)
346
+ print(intf.description)
347
+ print("!")
348
+
349
+ TenGigabitEthernet5/1
350
+ (MP)SWITCH-SD03:Twe1/0/6
351
+ !
352
+ TenGigabitEthernet5/2
353
+ Link to SWITCH-SA01 Te6/2 Decomm
354
+ !
355
+ TenGigabitEthernet6/1
356
+ (MP)SWITCH-SD04:Te1/1
357
+ !
358
+ ```
359
+
360
+ ### <li> `Trunk Port` Json/Dict format
361
+
362
+ ```python
363
+ >>> trunk_interfaces = parser.get_l2_trunk_interfaces(return_json=True)
364
+ >>> print(json.dumps(trunk_interfaces, indent=4))
365
+
366
+ [
367
+ {
368
+ "name": "TenGigabitEthernet5/1",
369
+ "description": "(MP)SWITCH-SD03:Twe1/0/6",
370
+ "allowed_vlans": null,
371
+ "dhcp_snooping": null,
372
+ "dhcp_relay": null,
373
+ "voice_vlan": null,
374
+ "state": null,
375
+ "spanning_tree": null,
376
+ "native_vlan": "256",
377
+ "children": [
378
+ "description (MP)SWITCH-SD03:Twe1/0/6",
379
+ "switchport trunk native vlan 256",
380
+ "switchport trunk allowed vlan 182,256,504,1100,3101,3201,3301,3311,3321,3331",
381
+ "switchport trunk allowed vlan add 3351,3401,3411,3911",
382
+ "switchport mode trunk",
383
+ "load-interval 30",
384
+ "udld port aggressive",
385
+ "service-policy output egress_queueing",
386
+ "ip dhcp snooping trust"
387
+ ],
388
+ "allowed_vlan": "182,256,504,1100,3101,3201,3301,3311,3321,3331"
389
+ },
390
+ ]
391
+ ```
392
+ ### <li> `Trunk Port` Custom Key/method search
393
+
394
+ ```python
395
+ >>> access_ports = parser.parser.get_l2_trunk_interfaces(load="load.*", return_json=True)
396
+
397
+ >>> print(json.dumps(access_ports, indent=4))
398
+
399
+ {
400
+ "name": "TenGigabitEthernet5/1",
401
+ "description": "(MP)SWITCH-SD03:Twe1/0/6",
402
+ "allowed_vlans": null,
403
+ "dhcp_snooping": null,
404
+ "dhcp_relay": null,
405
+ "voice_vlan": null,
406
+ "state": null,
407
+ "spanning_tree": null,
408
+ "native_vlan": "256",
409
+ "children": [
410
+ "description (MP)STNMED-LPCH-SD03:Twe1/0/6",
411
+ "switchport trunk native vlan 256",
412
+ "switchport trunk allowed vlan 182,256,504,1100,3101,3201,3301,3311,3321,3331",
413
+ "switchport trunk allowed vlan add 3351,3401,3411,3911",
414
+ "switchport mode trunk",
415
+ "load-interval 30",
416
+ "udld port aggressive",
417
+ "service-policy output egress_queueing",
418
+ "ip dhcp snooping trust"
419
+ ],
420
+ "allowed_vlan": "182,256,504,1100,3101,3201,3301,3311,3321,3331",
421
+ "load": "load-interval 30" <<<<< Custom Key and Value
422
+ },
423
+ ```
424
+
425
+
426
+ ## <li> Static Route Config
427
+
428
+ **Features**
429
+ - Parse Static Routes: Extract and parse static routing commands (ip route entries) from Cisco running configurations.
430
+ - Convert to Python Objects: Represent these routes as structured Python objects, enabling programmatic manipulation and easy integration with Python-based tools.
431
+ - Export to JSON/Dict: Convert static routing information into JSON or dictionary format, making it straightforward to use in web applications, APIs, or data storage solutions.
432
+
433
+ #### Example
434
+
435
+ **Python Object:**
436
+ ```python
437
+
438
+ >>> static = parser.get_static_config()
439
+ >>> for i in static:
440
+ print(i.subnet, i.name, i.nexthop_ip)
441
+
442
+ 0.0.0.0/0 MC-RS01 10.240.129.3
443
+ 0.0.0.0/0 NC-RS01 10.240.129.11
444
+ 10.243.98.32/28 P2P_Subnet 10.243.99.186
445
+ ```
446
+
447
+ **Json/Dict:**
448
+ ```python
449
+ static = parser.get_static_config()
450
+ [
451
+ {
452
+ "network": "0.0.0.0",
453
+ "mask": "0.0.0.0",
454
+ "nexthop_ip": "10.240.129.3",
455
+ "subnet": "0.0.0.0/0",
456
+ "vrf": "default",
457
+ "name": "MC-RS01",
458
+ "admin_distance": null
459
+ },
460
+ ]
461
+ ```
462
+
463
+
464
+ ## <li> Dynamic Route Config
465
+
466
+ ### <li> EIGRP
467
+
468
+ `eigrp_configs = parser.get_eigrp_config(return_json=True)`
469
+
470
+ ```json
471
+ [
472
+ {
473
+ "as_number": 300,
474
+ "network": [
475
+ {
476
+ "network": "10.242.96.240",
477
+ "subnet_mask": "255.255.255.252",
478
+ "wildcard_mask": "0.0.0.3"
479
+ },
480
+ {
481
+ "network": "10.242.97.244",
482
+ "subnet_mask": "255.255.255.252",
483
+ "wildcard_mask": "0.0.0.3"
484
+ },
485
+ {
486
+ "network": "10.242.98.248",
487
+ "subnet_mask": "255.255.255.252",
488
+ "wildcard_mask": "0.0.0.3"
489
+ },
490
+ {
491
+ "network": "10.242.99.252",
492
+ "subnet_mask": "255.255.255.252",
493
+ "wildcard_mask": "0.0.0.3"
494
+ }
495
+ ],
496
+ "vrf": "Global",
497
+ "wild_card_mask": null,
498
+ "subnet": null,
499
+ "has_vrf": true,
500
+ "vrf_count": 8,
501
+ "passive_interface": null,
502
+ "no_passive_interface": null,
503
+ "auto_cost": null,
504
+ "interfaces": null,
505
+ "children": [
506
+ "network 10.242.96.240 0.0.0.3",
507
+ "network 10.242.97.244 0.0.0.3",
508
+ "network 10.242.98.248 0.0.0.3",
509
+ "network 10.242.99.252 0.0.0.3",
510
+ "no passive-interface GigabitEthernet1/9",
511
+ "no passive-interface GigabitEthernet1/10",
512
+ "passive-interface default",
513
+ "no auto-summary"
514
+ ],
515
+ "vrf_children": [
516
+ {
517
+ "vrf": "mgt100",
518
+ "network": [
519
+ {
520
+ "network": "10.242.96.240",
521
+ "subnet_mask": "255.255.255.252",
522
+ "wildcard_mask": "0.0.0.3"
523
+ }
524
+ ],
525
+ "wild_card_mask": null,
526
+ "subnet": null,
527
+ "passive_interface": null,
528
+ "no_passive_interface": null,
529
+ "auto_cost": null,
530
+ "interfaces": null,
531
+ "children": [
532
+ "redistribute bgp 65240 metric 1000 100 255 1 1500 route-map MGT100_EIGRP_REDIST_BGP",
533
+ "network 10.242.96.240 0.0.0.3",
534
+ "passive-interface default",
535
+ "no passive-interface TenGigabitEthernet1/9.3131",
536
+ "distribute-list route-map route_map_inbound in",
537
+ "autonomous-system 300",
538
+ "exit-address-family"
539
+ ]
540
+ },
541
+ ]
542
+ }
543
+
544
+ ]
545
+ ```
546
+
547
+ ### <li> BGP Route Config:
548
+
549
+ **Example:**
550
+ `bgp_configs = parser.get_bgp_config(return_json=True)`
551
+
552
+ ```json
553
+ [
554
+ {
555
+ "router_id": "10.240.129.45",
556
+ "vrf_list": [
557
+ "blu300",
558
+ ],
559
+ "vrf": "Global",
560
+ "network": [
561
+ "10.245.49.132/32"
562
+ ],
563
+ "peer_group": [
564
+ {
565
+ "peer_group": {
566
+ "name": "RR",
567
+ "remote_as": "65234",
568
+ "update_source": "Loopback1",
569
+ "route_map": {
570
+ "in": "PEER_GROUP_RR_INBOUND",
571
+ "out": "PEER_GROUP_RR_OUTBOUND"
572
+ },
573
+ "neighbors": [
574
+ {
575
+ "ip": "10.252.248.251",
576
+ "description": "RR-Router-01"
577
+ },
578
+ ]
579
+ }
580
+ },
581
+ ],
582
+ "neighbors": null,
583
+ "redistribute": [
584
+ {
585
+ "vrf": "Global",
586
+ "protocol": "eigrp 100",
587
+ "route_map": ""
588
+ }
589
+ ],
590
+ "vrf_children": [
591
+ {
592
+ "vrf": "blu300",
593
+ "network": [
594
+ "10.245.17.132/32"
595
+ ],
596
+ "peer_group": null,
597
+ "neighbors": [
598
+ {
599
+ "vrf": "blu300",
600
+ "ip": "10.245.20.30",
601
+ "remote_as": "65245",
602
+ "description": "REMOTE_ROUTER-SA01_BLU300",
603
+ "update_source": "TenGigabitEthernet10/14.3301",
604
+ "route_map": {
605
+ "in": "ALLVRF_BGP_RM_INBOUND",
606
+ "out": "ALLVRF_BGP_RM_OUTBOUND"
607
+ }
608
+ }
609
+ ],
610
+ "redistribute": [
611
+ {
612
+ "vrf": "blu300",
613
+ "protocol": "eigrp 252",
614
+ "route_map": " BLU300_BGP_REDIST_EIGRP"
615
+ },
616
+ {
617
+ "vrf": "blu300",
618
+ "protocol": "static",
619
+ "route_map": " BLU300_BGP_REDIST_STATIC"
620
+ }
621
+ ],
622
+ }
623
+ ]
624
+ }
625
+ ]
626
+ ```
627
+
628
+ ### <li> OSPF Route Config
629
+
630
+ In ospf, ConfigParser attemps to capture any interfaces that are participating in OSPF as well.
631
+
632
+ **Example:**
633
+
634
+ `ospf = parser.get_ospf_config(return_json=True)`
635
+
636
+ ```json
637
+ [
638
+ {
639
+ "process_id": "240",
640
+ "router_id": "10.240.129.45",
641
+ "network": [
642
+ {
643
+ "network": "10.3.3.0",
644
+ "subnet_mask": "255.255.255.0",
645
+ "wildcard_mask": "0.0.0.255",
646
+ "area": "0"
647
+ }
648
+ ],
649
+ "wild_card_mask": null,
650
+ "subnet": null,
651
+ "vrf": null,
652
+ "passive_interface": [
653
+ {
654
+ "interface": "default"
655
+ }
656
+ ],
657
+ "no_passive_interface": [
658
+ {
659
+ "interface": "GigabitEthernet1/0"
660
+ }
661
+ ],
662
+ "auto_cost": "10000",
663
+ "interfaces": [
664
+ {
665
+ "interface": "Loopback0",
666
+ "area": "0",
667
+ "process_id": "240"
668
+ }
669
+ ]
670
+ }
671
+ ]
672
+ ```
673
+
674
+ ## <li> Custom Parsing
675
+
676
+ **Example:**
677
+ `custom_search = parser.get_parent_child(parent_regex="aaa.*", child_regex="server.*", return_json=True)`
678
+
679
+ ```json
680
+
681
+ [
682
+ {
683
+ "parent": "aaa group server tacacs+ ISE_TACACS",
684
+ "children": "server tacacs+ ISE_TACACS"
685
+ }
686
+ ]
687
+ ```
688
+
689
+
690
+
691
+ ## Future Enhancements
692
+ I am actively working on expanding the capabilities of this library. Upcoming features include:
693
+
694
+ - **Enhanced support for NXOS**: Additional parsing for NXOS-specific configurations and features.
695
+ - **Full support for IOS-XR**: Expanding coverage for IOS-XR configurations to include more advanced routing and service configurations.
696
+ - **More configuration sections**: Additional Cisco configuration types and attributes will be parsed in future releases.
697
+
698
+ Stay tuned for these updates and more in future versions of the library!
699
+
700
+
701
+
702
+ ## Contribution
703
+ Contributions are welcome! To contribute:
704
+
705
+ 1. Fork this repository.
706
+ 2. Create a feature branch.
707
+ 3. Make your changes and add tests if applicable.
708
+ 4. Submit a pull request for review.
709
+ 5. Feel free to open an issue for any bug reports or feature requests.
710
+
711
+
712
+
713
+ ## License
714
+ This project is licensed under the MIT License.
715
+
716
+ ### Key Improvements:
717
+ 1. **Title and Overview:** I emphasized the functionality of the library with clear mention of automation, parsing, and supported platforms.
718
+ 2. **Key Features:** I made the features section clearer and more structured.
719
+ 3. **Usage Example:** Added a usage example to make it easy for users to get started.
720
+ 4. **Installation:** Provided simple installation instructions using `pip`.
721
+ 5. **Contribution and License Sections:** These are standard in open-source projects and help potential contributors know how to get involved.