ciscoconfparse BGP no description on one of the neighbor

249 views Asked by At

i am trying to use ciscoconfparse to extract neighbor, remote as, and description into the dictionary. however one of the neighbor does not have description. hence it will not return the value

can anyone help what it would be the correct way to also get all neighbor values


Config:
router bgp 42098001
 neighbor SERVER peer-group
 neighbor SERVER remote-as 64700
 neighbor 10.29.0.65 remote-as 1111
 neighbor 10.29.0.65 description to ZZZ
 neighbor 10.29.0.73 remote-as 2222
 neighbor 10.29.0.73 description to AAA
 neighbor 10.29.0.81 remote-as 3333
 neighbor 10.29.0.81 description to BBB
 neighbor 10.29.0.90 remote-as 4209800190
 neighbor 10.29.0.90 description to ABC 
 neighbor 10.232.122.170 remote-as 64700
 neighbor 10.232.122.170 description ABD
 neighbor 10.237.34.2 remote-as 4209800192
 neighbor 10.237.34.2 description to CCC
    bgp_as_name = confparse.find_all_children(r"^router bgp")

    for details in bgp_as_name:
        if 'remote-as' in details:
            remote_ip = details.strip().rsplit(' ')[1]
            as_number = details.strip().rsplit(' ')[3]
            #print(remote_ip)

        if 'description' in details:
            description = details.strip().rsplit(' ')[3:]
            desc = (' ').join(description)
            bgp_as_ip.update({'description': desc})
            print(bgp_as_ip)


    #BGP route-map
    bgp_route_map = confparse.find_all_children(r"^router bgp")
    for routemap in bgp_route_map:
        if 'route-map' in routemap:
            bgp_routemap_slice1 = routemap.strip().split(' ')[0:2]
            bgp_routemap_slice2 = routemap.strip().split(' ')[-2:]
            bgp_routemap_combine = bgp_routemap_slice1 + bgp_routemap_slice2
            bgp_route_map = bgp_routemap_combine[1:4]
            print(bgp_route_map)
            #bgp_as_ip.update({'route-map': bgp_route_map})
            #print(bgp_as_ip)
RESULT
{'remote_ip': '10.29.0.65', 'as_num': '1111', 'description': 'to ZZZ'}
{'remote_ip': '10.29.0.73', 'as_num': '2222', 'description': 'to AAA'}
{'remote_ip': '10.29.0.81', 'as_num': '3333', 'description': 'to BBB'}
{'remote_ip': '10.29.0.90', 'as_num': '4201', 'description': 'to ABC'}
{'remote_ip': '10.232.122.170', 'as_num': '64700', 'description': 'ABD'}
{'remote_ip': '10.237.34.2', 'as_num': '4209', 'description': 'to CCC'}

> The missing information is neighbor SERVER

1

There are 1 answers

0
Mike Pennington On

ciscoconfparse has a method called re_match_typed() for pretty much this exact case...


from pprint import pprint

from ciscoconfparse import CiscoConfParse

config_list = """router bgp 42098001
 neighbor SERVER peer-group
 neighbor SERVER remote-as 64700
 neighbor 10.29.0.65 remote-as 1111
 neighbor 10.29.0.65 description to ZZZ
 neighbor 10.29.0.73 remote-as 2222
 neighbor 10.29.0.73 description to AAA
 neighbor 10.29.0.81 remote-as 3333
 neighbor 10.29.0.81 description to BBB
 neighbor 10.29.0.90 remote-as 4209800190
 neighbor 10.29.0.90 description to ABC
 neighbor 10.232.122.170 remote-as 64700
 neighbor 10.232.122.170 description ABD
 neighbor 10.237.34.2 remote-as 4209800192
 neighbor 10.237.34.2 description to CCC
""".splitlines()

parse = CiscoConfParse(config_list)


nested_dict = dict()
for obj_cmd in parse.find_objects(r"^\s+neighbor"):
    nei_ipv4 = obj_cmd.re_match_typed(r"^\s+neighbor\s+(\S+)", result_type=str)

    nei_new_addr = nested_dict.get(nei_ipv4, False)
    if nei_new_addr is False:
        nested_dict[nei_ipv4] = dict()

    if nested_dict[nei_ipv4].get("remote-as", None) is None:
        nested_dict[nei_ipv4]["remote-as"] = obj_cmd.re_match_typed(
            r"^\s*neighbor\s+{0}\s+remote-as\s+(\d+)\s*$".format(nei_ipv4),
            untyped_default=True,
            default=None,
        )

    if nested_dict[nei_ipv4].get("description", None) is None:
        nested_dict[nei_ipv4]["description"] = obj_cmd.re_match_typed(
            r"^\s*neighbor\s+{0}\s+description\s+(\S.*)\s*$".format(nei_ipv4),
            untyped_default=True,
            default=None,
        )

pprint(nested_dict)

Running this, the output is...

{'10.232.122.170': {'description': 'ABD', 'remote-as': '64700'},
 '10.237.34.2': {'description': 'to CCC', 'remote-as': '4209800192'},
 '10.29.0.65': {'description': 'to ZZZ', 'remote-as': '1111'},
 '10.29.0.73': {'description': 'to AAA', 'remote-as': '2222'},
 '10.29.0.81': {'description': 'to BBB', 'remote-as': '3333'},
 '10.29.0.90': {'description': 'to ABC ', 'remote-as': '4209800190'},
 'SERVER': {'description': None, 'remote-as': '64700'}}

I reformatted the output, but it's trivial to change the example to use your format...