Source code for nettoolkit.yaml_facts.cisco.parsers.protocol_isis_run

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

# ------------------------------------------------------------------------------
from .common import *
from .protocols import ProtocolsConfig, get_protocol_instance_dict
# ------------------------------------------------------------------------------


# ------------------------------------------------------------------------------
#  ISIS ATTR FUNCS
# ------------------------------------------------------------------------------

def _get_isis_default_info_originate(attr_dict, l, spl):
	if not l.startswith("default-information originate"): return
	if "route-map" in spl:
		dic = add_blankdict_key(attr_dict, 'default-information')
		dic = add_blankdict_key(dic, 'originate')
		append_attribute(dic, "route-map", spl[-1])
	else:
		append_attribute(attr_dict, 'default-information', spl[-1])


def _get_isis_psasive_intf(attr_dict, l, spl):
	if "passive-interface" not in spl: return
	pi_idx = spl.index("passive-interface")
	if len(spl) > 1 and "no" == spl[pi_idx-1] and pi_idx == 1:
		if "passive-interface" == spl[-1]: 
			append_attribute(attr_dict, "passive-interface", False)
		else:
			append_attribute(attr_dict, "no passive-interface", next_index_item(spl, "passive-interface"))
	elif "passive-interface" == spl[-1]:
		append_attribute(attr_dict, "passive-interface", True)
	else:
		append_attribute(attr_dict, "passive-interface", next_index_item(spl, "passive-interface"))


def _get_isis_spf_interval(attr_dict, l, spl):
	if 'spf-interval' != spl[0]: return
	dic = add_blankdict_key(attr_dict, 'spf-interval')
	d = {1: 'level', 2: 'seconds', 3: 'initial-wait', 4: 'secondary-wait'}
	diff = 1 if spl[1].isnumeric() else 0
	for idx in range(1, len(spl)):
		append_attribute(dic, d[idx+diff], spl[idx])

def _get_isis_prc_interval(attr_dict, l, spl):
	interval_candidates = ("lsp-gen-interval", 'prc-interval')
	if spl[0] not in interval_candidates: return
	dic = add_blankdict_key(attr_dict, spl[0])
	d = {1: 'seconds', 2: 'initial-wait' ,3: 'secondary-wait'}
	for idx in range(1, len(spl)):
		append_attribute(dic, d[idx], spl[idx])


def _get_isis_metric(attr_dict, l, spl):
	if 'metric' != spl[0]: return
	if len(spl) > 2:
		dic = add_blankdict_key(attr_dict, 'metric')
		append_attribute(dic, spl[2], spl[1])
	elif len(spl) == 2:
		append_attribute(attr_dict, 'metric', spl[1])

def _get_isis_metric_style(attr_dict, l, spl):
	if 'metric-style' != spl[0]: return
	dic = add_blankdict_key(attr_dict, 'metric')
	dic = add_blankdict_key(dic, 'style')
	for idx in range(1, len(spl)):
		dic = add_blankdict_key(dic, spl[idx])

def _get_isis_redistribution(attr_dict, l, spl):
	if 'redistribute' != spl[0]: return
	dic = add_blankdict_key(attr_dict, 'redistribute')
	if spl[1] == 'maximum-prefix':
		dic = add_blankdict_key(dic, 'maximum-prefix' )
		append_attribute(dic, 'maximum', spl[2])
		if spl[3].isnumeric: append_attribute(dic, 'percentage', spl[3])
		if spl[-1] in ('withdraw', 'warning-only'):
			append_attribute(dic, spl[-1], True)
		return
	# --- #
	attrs = ('metric', 'metric-type', 'match', 'tag', 'route-map', 'distribute-list')
	protocol = spl[1]
	dic = add_blankdict_key(dic, protocol)
	attr_idx = {attr:spl.index(attr) for attr in attrs if attr in spl}
	min_idx = min(attr_idx.values())
	for idx in range(2, min_idx):
		dic = add_blankdict_key(dic, spl[idx])
	for item, idx in attr_idx.items():
		append_attribute(dic, item, spl[idx+1])

def _get_isis_summary_address(attr_dict, l, spl):
	summary_candidates = ("summary-address", "summary-prefix")
	if spl[0] not in summary_candidates: return
	dic = add_blankdict_key(attr_dict, 'summaries')
	mask = None if "/" in spl[1] else spl[2]
	diff = 1 if "/" in spl[1] else 0
	network = addressing(spl[1], mask).NetworkIP()
	level = spl[3-diff]
	dic = add_blankdict_key(dic, str(network))
	append_attribute(dic, 'level', level)
	attrs = ('tag', 'metric')
	for item in attrs:
		if item not in spl: continue
		append_attribute(dic, item, next_index_item(spl, item))

def _get_isis_auth(attr_dict, l, spl):
	if 'authentication' not in spl or 'password' not in spl: return
	password_candidates = ('area-password', 'domain-password')
	if spl[0] in password_candidates:
		dic = add_blankdict_key(attr_dict, "password")
		update_key_value(dic, spl[0], next_index_item(spl, "password"))
		if len(spl) > 2:
			for i in range(2, len(spl)):
				dic = update_key_value(dic, spl[i], spl[i+1])
	elif 'authentication' in spl:
		dic = add_blankdict_key(attr_dict, 'authentication')
		if 'mode' in spl:
			update_key_value(dic, 'mode', next_index_item(spl, 'mode'))
		if 'key-chain' in spl:
			update_key_value(dic, 'key-chain', spl[ spl.index('key-chain') + 2 ])




def _get_isis_next_item(attr_dict, l, spl):
	attrs = (
		"net", "is-type", "vrf", "multi-topology", "maximum-paths", "protocol", "segment-routing",
		"max-lsp-lifetime", "lsp-refresh-interval", "fast-flood",
	)
	for item in attrs:
		if item != spl[0]: continue
		append_attribute(attr_dict, item, next_index_item(spl, item))



# ====================================================================================================
#  ISIS Config extractor Class
# ====================================================================================================

[docs] @dataclass class ISISConf(ProtocolsConfig): ## ISIS Supported AF types supported_af_types = ('ipv4', 'ipv6') attr_functions = [ _get_isis_spf_interval, _get_isis_prc_interval, _get_isis_metric, _get_isis_metric_style, _get_isis_redistribution, _get_isis_summary_address, _get_isis_auth, _get_isis_next_item, _get_isis_psasive_intf, _get_isis_default_info_originate, ] def __post_init__(self): self.isis_vrf_dict = {} isis_lines_dict = self.get_isis_lines_dict() self.isis_af_lines_dict = self.get_isis_af_lines_dict(isis_lines_dict, 'address-family ', "exit-address-family") self._iterate_vrfs() self.shirnk_None_vrf_dict()
[docs] def shirnk_None_vrf_dict(self): for area_id in list(self.isis_vrf_dict.keys()): vrf_dict = self.isis_vrf_dict[area_id] if None in vrf_dict: merge_dict(vrf_dict, vrf_dict[None]) del(vrf_dict[None])
[docs] def get_isis_lines_dict(self): dic, start = {}, False for line in self.run_list: if not line.strip() : continue if line.startswith(f"router isis"): spl = line.split() area_id = spl[2] if len(spl)>2 else 0 lst = [] start = True if start and line[0] == "!": dic[area_id] = lst start = False continue if not start: continue if line.strip().startswith("!"): continue lst.append(line.strip()) return dic
[docs] def get_isis_af_lines_dict(self, source_dict, starter, stopper): dic = {} ###- lines with vrf for key, lines in source_dict.items(): x_dic = add_blankdict_key(dic, key) start = False if not lines: continue for line in lines: if not line: continue if not line.strip(): continue if line.startswith(starter): spl = line.split() key, lst = line, [] start = True if start and line.startswith(stopper): x_dic[key] = lst start = False continue if not start: continue lst.append(line) ###- lines without vrf for key, lines in source_dict.items(): x_dic = add_blankdict_key(dic, key) start, NullKey, lst = False, None, [] for line in lines: if line.startswith(starter): start = True continue if start and line.startswith(stopper): start = False continue if start: continue lst.append(line) x_dic[NullKey] = lst return dic
def _iterate_vrfs(self): for area_id, vrf_dict in self.isis_af_lines_dict.items(): if not vrf_dict: continue process_dic = add_blankdict_key(self.isis_vrf_dict, area_id) for key, lines in vrf_dict.items(): if not lines: continue vrf_dic = add_blankdict_key(process_dic, key) vrf_dic.update( self._get_attributes(lines) )
# ==================================================================================================== # ISIS Config extractor function # ====================================================================================================
[docs] def get_isis_running(command_output): """parse output of : show running-config Args: command_output (list): command output Returns: dict: protocols isis and isis-instance level parsed output dictionary """ RC = ISISConf(command_output) return get_protocol_instance_dict(protocol='isis', instances_dic=RC.isis_vrf_dict)
# ====================================================================================================