Source code for nettoolkit.facts_finder.generators.cisco._cmd_parse_bgp

"""cisco running-config parser for bgp section output """

# ------------------------------------------------------------------------------
from collections import OrderedDict

from nettoolkit.facts_finder.generators.commons import *
from .common import *

merge_dict = DIC.merge_dict
# ------------------------------------------------------------------------------

[docs] class BGP_Papa(): """parent object for BGP level running config parser Args: cmd_op (list, str): running config output, either list of multiline string """ def __init__(self, cmd_op): """initialize the object by providing the running config output """ self.cmd_op = verifid_output(cmd_op) self.op_dict = {}
[docs] def bgp_nbr_attributes(self): """update the bgp neighbor attribute details """ func = self.get_nbr_attributes merge_dict(self.op_dict, self.bgp_read(func))
[docs] @staticmethod def get_nbr_attributes(op_dict, line, spl): """parser function to update bgp neighbor attribute details Args: port_dict (dict): dictionary with a bgp neighbour info line (str): string line to parse spl (list): splitted line to parse Returns: None: None """ if spl[2] == "remote-as": op_dict['bgp_peer_as'] = spl[-1] if spl[2] == "update-source": op_dict['update-source'] = spl[-1] if spl[2] == "ebgp-multihop": op_dict['ebgp-multihop'] = spl[-1] if spl[2] == "unsuppress-map" : op_dict["unsuppress-map"] = spl[-1] if spl[-2] == "peer-group": op_dict["bgp_peergrp"] = spl[-1] op_dict["bgp_peer_ip"] = spl[1] if spl[-1] == "peer-group": op_dict["bgp_peergrp"] = spl[1] if spl[2] == "password": op_dict["bgp_peer_password"] = decrypt_type7(spl[-1]) if spl[3] == "7" else spl[-1] if spl[2] == "route-map" and spl[-1] == "in": op_dict["route-map in"] = spl[-2] if spl[2] == "route-map" and spl[-1] == "out": op_dict["route-map out"] = spl[-2] if spl[2] == "local-as": op_dict['local-as'] = spl[3] if spl[2] == "description": op_dict['bgp_peer_description'] = " ".join(spl[3:]) ## add more as necessary ## return op_dict
[docs] class AddressFamily(BGP_Papa): """object for address-family BGP running config parser Args: cmd_op (list, str): running config output, either list of multiline string """
[docs] def bgp_read(self, func): """directive function to get the various bgp af level output Args: func (method): method to be executed on bgp af config line Returns: dict: parsed output dictionary """ toggle, af, update_dict = False, False, "" op_dict = OrderedDict() for l in self.cmd_op: spl = l.strip().split() if l.startswith(" address-family "): op_dict['type'] = spl[1] op_dict['bpg_vrf'] = spl[3] continue if spl[1] == "router-id ": op_dict['router_id'] = spl[-1] continue if spl[0] != "neighbor" : continue # continue except neighbour statements nbr = spl[1] if not op_dict.get(nbr): op_dict[nbr] = {} nbr_dict = op_dict[nbr] nbr_dict['filter'] = 'bgp' func(nbr_dict, l, spl) return op_dict
[docs] class BGP(BGP_Papa): """object for native BGP running config parser Args: cmd_op (list, str): running config output, either list of multiline string """ def __init__(self, cmd_op): """initialize the object by providing the running config output """ super().__init__(cmd_op) self.afl = {}
[docs] def bgp_read(self, func): """directive function to get the various bgp native level output Args: func (method): method to be executed on bgp native config line Returns: dict: parsed output dictionary """ toggle, af = False, False op_dict = OrderedDict() for l in self.cmd_op: if blank_line(l): continue spl = l.strip().split() if l.startswith("router bgp "): toggle = True continue if l.startswith("!"): toggle = False continue if spl[0][0].startswith("!"): continue # if spl[0] == "!": continue if l.startswith(" address-family ") and spl[-2] == "vrf": toggle = False af = True af_name = l.split(" address-family ")[-1] afl = [] continue if af and l.startswith(" exit-address-family"): af = False self.afl[af_name] = get_bgp_af_running(afl) continue if af: afl.append(l) if not toggle: continue if spl[0] == "exit-address-family": continue # if spl[1] == "router-id ": op_dict['router_id'] = spl[-1] continue if spl[0] != "neighbor" : continue # continue except neighbour statements nbr = spl[1] if not op_dict.get(nbr): op_dict[nbr] = {} nbr_dict = op_dict[nbr] nbr_dict['filter'] = 'bgp' func(nbr_dict, l, spl) update_dict = merge_vrftype_name_inkey(self.afl) self.op_dict.update(update_dict) return op_dict
[docs] def merge_vrftype_name_inkey(d): """update vrf and vrf_type in dictionary Args: d (dict): dictionary with neighbours attributes Returns: dict: updated dict with bgp_vrf and address-family attributes """ update_dict = {} for vrftype, vrfattrs in d.items(): for nbr, vrfattr in vrfattrs.items(): vrftype_spl = vrftype.split() vrf = vrftype_spl[-1] af = vrftype_spl[-3] update_dict[nbr] = vrfattr update_dict[nbr]['bgp_vrf'] = vrf update_dict[nbr]['address-family'] = af return update_dict
# ------------------------------------------------------------------------------
[docs] def get_bgp_af_running(cmd_op, *args): """defines set of methods executions. to get various bgp address-family parameters. uses AddressFamily in order to get all. Args: cmd_op (list, str): running config output, either list of multiline string Returns: dict: output dictionary with parsed with system fields """ AF = AddressFamily(cmd_op) AF.bgp_nbr_attributes() # if not AF.op_dict: # AF.op_dict['dummy_col1'] = "" return AF.op_dict
[docs] def get_bgp_running(cmd_op, *args): """defines set of methods executions. to get various bgp native parameters. uses BGP in order to get all. Args: cmd_op (list, str): running config output, either list of multiline string Returns: dict: output dictionary with parsed with system fields """ R = BGP(cmd_op) R.bgp_nbr_attributes() if not R.op_dict: R.op_dict['dummy_bgp'] = "" return {'op_dict': R.op_dict }