I'm trying to use CiscoConfParse on Cisco IOS config an parse a full PE configurations.
The goal is to collect all the essential information from a PE Config (VRF, INTERFACE, BGP Setup).
I found out this ciscoconfparse library (https://pypi.python.org/pypi/ciscoconfparse).
The code only partially works and the regex match correctly but only the first match (see also output below).
Code:
import ciscoconfparse
def parse_config(config_file):
# Create a CiscoConfParse object from the configuration file
config = ciscoconfparse.CiscoConfParse(config_file)
# Parse VRF configurations
vrf_configs = []
for vrf_obj in config.find_objects(r'^vrf definition (\S+)'):
vrf_config = {
'name': vrf_obj.re_match(r'vrf definition (\S+)'),
'rd': vrf_obj.re_match(r'rd (\S+)'),
'export_rt': vrf_obj.re_match(r'route-target export (\S+)'),
'import_rt': vrf_obj.re_match(r'route-target import (\S+)'),
}
vrf_configs.append(vrf_config)
# Parse Interface configurations
interface_configs = []
for intf_obj in config.find_objects(r'^interface'):
interface_config = {
'name': intf_obj.re_match(r'interface (\S+)'),
'description': intf_obj.re_match(r'description (.+)'),
'vrf': intf_obj.re_match(r'vrf forwarding (\S+)'),
'interface_ip': intf_obj.re_match(r'ip address (\S+) (\S+)'),
'interface_dot1q': intf_obj.re_match(r'encapsulation dot1q (\S+)'),
}
interface_configs.append(interface_config)
# Parse BGP configurations
bgp_configs = []
for bgp_obj in config.find_objects(r'^router bgp (\S+)'):
bgp_config = {
'as_number PE': bgp_obj.re_match(r'router bgp (\d+)'),
'bgp_address-family': bgp_obj.re_match(r'address-family ipv4 vrf (\S+)'),
'bgp_neighbor_ip': bgp_obj.re_match(r'neighbor (\S+) remote-as (\d+)'),
'bgp_neighbor_as': bgp_obj.re_match(r'remote-as (\d+)'),
}
bgp_configs.append(bgp_config)
return vrf_configs, interface_configs, bgp_configs
# Parse the PE router configuration
vrf_configs, interface_configs, bgp_configs = parse_config('pe_config.txt')
# Print parsed data
print("Parsed VRF configurations from PE config:")
for vrf in vrf_configs:
print(vrf)
print("\nParsed Interface configurations from PE config:")
for intf in interface_configs:
print(intf)
print("\nParsed BGP configurations from PE config:")
for bgp in bgp_configs:
print(bgp)
Output:
Parsed VRF configurations from PE config:
{'name': 'BLUE', 'rd': '', 'export_rt': '', 'import_rt': ''}
{'name': 'RED', 'rd': '', 'export_rt': '', 'import_rt': ''}
Parsed Interface configurations from PE config:
{'name': 'FastEthernet2/0.2', 'description': '', 'vrf': '', 'interface_ip': '', 'interface_dot1q': ''}
{'name': 'FastEthernet3/0.3', 'description': '', 'vrf': '', 'interface_ip': '', 'interface_dot1q': ''}
Parsed BGP configurations from PE config:
{'as_number PE': '100', 'bgp_address-family': '', 'bgp_neighbor_ip': '', 'bgp_neighbor_as': ''}
PE config (pe_config.txt):
!-- BASIC PE configuration ------------
vrf definition BLUE
rd 108:108
route-target export 108:108
route-target import 108:108
!
address-family ipv4
exit-address-family
!
vrf definition RED
rd 79:79
route-target export 79:79
route-target import 79:79
!
address-family ipv4
exit-address-family
!
interface FastEthernet2/0.2
description Customer RED
encapsulation dot1q 2
vrf forwarding RED
ip address 10.57.1.5 255.255.255.0
!
interface FastEthernet3/0.3
description Customer BLUE
encapsulation dot1q 3
vrf forwarding BLUE
ip address 10.58.1.5 255.255.255.0
!
router bgp 100
bgp log-neighbor-changes
no bgp default ipv4-unicast
neighbor 6.6.6.6 remote-as 100
neighbor 6.6.6.6 update-source Loopback0
!
address-family ipv4
exit-address-family
!
address-family vpnv4
neighbor 6.6.6.6 activate
neighbor 6.6.6.6 send-community extended
exit-address-family
!
address-family ipv4 vrf RED
neighbor 10.57.1.7 remote-as 79
neighbor 10.57.1.7 activate
exit-address-family
!
address-family ipv4 vrf BLUE
neighbor 10.58.1.8 remote-as 8
neighbor 10.58.1.8 activate
exit-address-family
!
!-- EOF -------------------------------
Maybe someone has a good idea?
Thank you for your input.
I expect all information about the VRFs, interfaces and BGP configuration to be listed.
Parsed VRF configurations from PE config:
{'name': 'VRF xx', 'rd': 'xx:xx', 'export_rt': 'xx:xx', 'import_rt': 'xx:xx'}
Parsed Interface configurations from PE config:
{'name': 'FastEthernet2/0.2', 'description': 'xxx', 'vrf': 'VRF xx', 'interface_ip': 'A.B.C.D 255.255.255.252', 'interface_dot1q': 'x'}
Parsed BGP configurations from PE config:
{'as_number PE': '100', 'bgp_address-family': 'VRF xx', 'bgp_neighbor_ip': 'A.B.C.D', 'bgp_neighbor_as': 'xx'}
Your Cisco IOS config is not indented correctly, and you can't parse a flat config the way you've tried... specifically, this is broken...
vrf_obj.re_match()cannot simultaneously handlevrf definitionANDroute-targetbecausevrf_objonly hits thevrf definitionline, even in your flat (un-indented) IOS config.Indent your configuration as Cisco IOS does, and use
re_match_iter_typed()to capture first-level children of parents... you should iterate individually for multi-level children... this works...The exact output is: