Skip to content

Commit

Permalink
Update adva parser to deplicate parent lines i.e. configure snmp
Browse files Browse the repository at this point in the history
  • Loading branch information
johanek committed Nov 24, 2023
1 parent 22c9c58 commit 20037cb
Show file tree
Hide file tree
Showing 4 changed files with 219 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/dev/include_parser_list.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
| OS Name | Parser Class |
| ---------- | ------ |
| adva_embedded_os | netutils.config.parser.AdvaConfigParser |
| arista_eos | netutils.config.parser.EOSConfigParser |
| aruba_aoscx | netutils.config.parser.ArubaConfigParser |
| bigip_f5 | netutils.config.parser.F5ConfigParser |
Expand Down
123 changes: 123 additions & 0 deletions netutils/config/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -1583,7 +1583,130 @@ class AdvaConfigParser(BaseSpaceConfigParser):
comment_chars: t.List[str] = ["#", "home", "back"]
banner_start: t.List[str] = []


def __init__(self, config: str):
"""Create ConfigParser Object.
Args:
config: The config text to parse.
"""
self.config = config
self._config: t.Optional[str] = None
self._current_parents: t.Tuple[str, ...] = ()
self.generator_config = (line for line in self.config_lines_only.splitlines())
self.config_lines: t.List[ConfigLine] = []
self.all_config_lines: t.List[ConfigLine] = []
self.build_config_relationship()

@property
def banner_end(self) -> str:
"""Demarcate End of Banner char(s)."""
raise NotImplementedError("Adva Embedded OS platform doesn't have a banner.")

def _update_config_lines(self, config_line: str) -> None:
"""Add a ``ConfigLine`` object to ``self.config_lines``.
Args:
config_line: The current config line being evaluated.
Returns:
None
"""
entry = ConfigLine(config_line, self._current_parents)
self.all_config_lines.append(entry)

# Deduplicate lines - parent sections i.e. "configure snmp" should be recorded only once
if entry not in self.config_lines:
self.config_lines.append(entry)

def _build_nested_config(self, line: str) -> t.Optional[str]:
"""Handle building child config sections.
Args:
line: A configuration line from the configuration text.
Returns:
The next top-level configuration line in the configuration text or None when the last line of configuration
text is a nested configuration line.
Raises:
IndexError: When the number of parents does not match the expected deindent level.
"""
self._update_config_lines(line)
for line in self.generator_config:
if not line[0].isspace():
self._current_parents = ()
self.indent_level = 0
return line

spaces = self.get_leading_space_count(line)
if spaces == self.indent_level:
pass
elif spaces > self.indent_level:
previous_config = self.all_config_lines[-1]
self._current_parents += (previous_config.config_line,)
else:
self._current_parents = self._remove_parents(line, spaces)

if spaces != self.indent_level:
self.indent_level = spaces

if self.is_banner_start(line):
banner_line = self._build_banner(line)
if banner_line is None or not banner_line[0].isspace():
self._current_parents = ()
self.indent_level = 0
return banner_line
line = banner_line

self._update_config_lines(line)
return None


def build_config_relationship(self) -> t.List[ConfigLine]:
r"""Parse text tree of config lines and their parents.
Examples:
>>> config = (
... "interface Ethernet1/1\n"
... " vlan 10\n"
... " no shutdown\n"
... "interface Ethernet1/2\n"
... " shutdown\n"
... )
>>> config_tree = BaseSpaceConfigParser(config)
>>> config_tree.build_config_relationship() == \
... [
... ConfigLine(config_line='interface Ethernet1/1', parents=()),
... ConfigLine(config_line=' vlan 10', parents=('interface Ethernet1/1',)),
... ConfigLine(config_line=' no shutdown', parents=('interface Ethernet1/1',)),
... ConfigLine(config_line='interface Ethernet1/2', parents=(),),
... ConfigLine(config_line=' shutdown', parents=('interface Ethernet1/2',))
... ]
True
"""
for line in self.generator_config:
if not line[0].isspace():
self._current_parents = ()
if self.is_banner_start(line):
line = self._build_banner(line) # type: ignore
else:
previous_config = self.all_config_lines[-1]
self._current_parents = (previous_config.config_line,)
self.indent_level = self.get_leading_space_count(line)
if not self.is_banner_start(line):
line = self._build_nested_config(line) # type: ignore
else:
line = self._build_banner(line) # type: ignore
if line is not None and line[0].isspace():
line = self._build_nested_config(line) # type: ignore
else:
self._current_parents = ()

if line is None:
break
elif self.is_banner_start(line):
line = self._build_banner(line) # type: ignore

self._update_config_lines(line)
return self.config_lines
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from netutils.config.parser import ConfigLine

data = [
ConfigLine(config_line='configure snmp', parents=()),
ConfigLine(config_line=' delete community "private"', parents=('configure snmp',)),
ConfigLine(config_line=' delete community "public"', parents=('configure snmp',)),
ConfigLine(config_line=' add community "secret" readwrite', parents=('configure snmp',)),
ConfigLine(config_line=' add target-params "Params" snmpv2c snmpv2c "secret" no-auth', parents=('configure snmp',)),
ConfigLine(config_line=' add target-address "target1" "10.0.0.2:161" ipv4 60 3 "info" "Params" enabled', parents=('configure snmp',)),
ConfigLine(config_line=' configure target-address "target1" bulk-traps-control disabled', parents=('configure snmp',)),
ConfigLine(config_line=' add target-address "target2" "10.0.0.5:161" ipv4 60 3 "info" "Params" enabled', parents=('configure snmp',)),
ConfigLine(config_line=' configure target-address "target2" bulk-traps-control disabled', parents=('configure snmp',)),
ConfigLine(config_line='network-element ne-1', parents=()),
ConfigLine(config_line=' configure nte ntexg108-1-1-1', parents=('network-element ne-1',)),
ConfigLine(config_line=' configure access-port access-1-1-1-3', parents=('network-element ne-1', ' configure nte ntexg108-1-1-1')),
ConfigLine(config_line=' admin-state unassigned', parents=('network-element ne-1', ' configure nte ntexg108-1-1-1', ' configure access-port access-1-1-1-3')),
ConfigLine(config_line=' service-type evpl', parents=('network-element ne-1', ' configure nte ntexg108-1-1-1', ' configure access-port access-1-1-1-3')),
ConfigLine(config_line=' alias "CUST-HANDOFF"', parents=('network-element ne-1', ' configure nte ntexg108-1-1-1', ' configure access-port access-1-1-1-3')),
ConfigLine(config_line=' port-vlan-id 1-0', parents=('network-element ne-1', ' configure nte ntexg108-1-1-1', ' configure access-port access-1-1-1-3')),
ConfigLine(config_line=' a2n-push-port-vid disabled', parents=('network-element ne-1', ' configure nte ntexg108-1-1-1', ' configure access-port access-1-1-1-3')),
ConfigLine(config_line=' priority-mapping-profile prio_map_profile-1', parents=('network-element ne-1', ' configure nte ntexg108-1-1-1', ' configure access-port access-1-1-1-3')),
ConfigLine(config_line=' cpd-filter 01-80-c2-00-00-00 pass-thru', parents=('network-element ne-1', ' configure nte ntexg108-1-1-1', ' configure access-port access-1-1-1-3')),
ConfigLine(config_line=' cpd-filter 01-80-c2-00-00-01 pass-thru', parents=('network-element ne-1', ' configure nte ntexg108-1-1-1', ' configure access-port access-1-1-1-3')),
ConfigLine(config_line=' cpd-filter 01-80-c2-00-00-02 pass-thru', parents=('network-element ne-1', ' configure nte ntexg108-1-1-1', ' configure access-port access-1-1-1-3')),
ConfigLine(config_line=' cpd-filter 01-80-c2-00-00-03 pass-thru', parents=('network-element ne-1', ' configure nte ntexg108-1-1-1', ' configure access-port access-1-1-1-3')),
ConfigLine(config_line=' cpd-filter 01-80-c2-00-00-04 pass-thru', parents=('network-element ne-1', ' configure nte ntexg108-1-1-1', ' configure access-port access-1-1-1-3')),
ConfigLine(config_line=' cpd-filter 01-80-c2-00-00-05 pass-thru', parents=('network-element ne-1', ' configure nte ntexg108-1-1-1', ' configure access-port access-1-1-1-3')),
ConfigLine(config_line=' cpd-filter 01-80-c2-00-00-06 pass-thru', parents=('network-element ne-1', ' configure nte ntexg108-1-1-1', ' configure access-port access-1-1-1-3')),
ConfigLine(config_line=' cpd-filter 01-80-c2-00-00-07 pass-thru', parents=('network-element ne-1', ' configure nte ntexg108-1-1-1', ' configure access-port access-1-1-1-3')),
ConfigLine(config_line=' cpd-filter 01-80-c2-00-00-08 pass-thru', parents=('network-element ne-1', ' configure nte ntexg108-1-1-1', ' configure access-port access-1-1-1-3')),
ConfigLine(config_line=' cpd-filter 01-80-c2-00-00-09 pass-thru', parents=('network-element ne-1', ' configure nte ntexg108-1-1-1', ' configure access-port access-1-1-1-3')),
ConfigLine(config_line=' cpd-filter 01-80-c2-00-00-0a pass-thru', parents=('network-element ne-1', ' configure nte ntexg108-1-1-1', ' configure access-port access-1-1-1-3')),
ConfigLine(config_line=' cpd-filter 01-80-c2-00-00-0b pass-thru', parents=('network-element ne-1', ' configure nte ntexg108-1-1-1', ' configure access-port access-1-1-1-3')),
ConfigLine(config_line=' cpd-filter 01-80-c2-00-00-0c pass-thru', parents=('network-element ne-1', ' configure nte ntexg108-1-1-1', ' configure access-port access-1-1-1-3')),
ConfigLine(config_line=' cpd-filter 01-80-c2-00-00-0d pass-thru', parents=('network-element ne-1', ' configure nte ntexg108-1-1-1', ' configure access-port access-1-1-1-3')),
ConfigLine(config_line=' cpd-filter 01-80-c2-00-00-0e pass-thru', parents=('network-element ne-1', ' configure nte ntexg108-1-1-1', ' configure access-port access-1-1-1-3')),
ConfigLine(config_line=' cpd-filter 01-80-c2-00-00-0f pass-thru', parents=('network-element ne-1', ' configure nte ntexg108-1-1-1', ' configure access-port access-1-1-1-3')),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
home
configure snmp
delete community "private"

home
configure snmp
delete community "public"

home
configure snmp
add community "secret" readwrite

home
configure snmp
add target-params "Params" snmpv2c snmpv2c "secret" no-auth

home
configure snmp
add target-address "target1" "10.0.0.2:161" ipv4 60 3 "info" "Params" enabled
configure target-address "target1" bulk-traps-control disabled

home
configure snmp
add target-address "target2" "10.0.0.5:161" ipv4 60 3 "info" "Params" enabled
configure target-address "target2" bulk-traps-control disabled

home
network-element ne-1
configure nte ntexg108-1-1-1
configure access-port access-1-1-1-3
admin-state unassigned
service-type evpl
alias "CUST-HANDOFF"
port-vlan-id 1-0
a2n-push-port-vid disabled
priority-mapping-profile prio_map_profile-1

home
network-element ne-1
configure nte ntexg108-1-1-1
configure access-port access-1-1-1-3
cpd-filter 01-80-c2-00-00-00 pass-thru
cpd-filter 01-80-c2-00-00-01 pass-thru
cpd-filter 01-80-c2-00-00-02 pass-thru
cpd-filter 01-80-c2-00-00-03 pass-thru
cpd-filter 01-80-c2-00-00-04 pass-thru
cpd-filter 01-80-c2-00-00-05 pass-thru
cpd-filter 01-80-c2-00-00-06 pass-thru
cpd-filter 01-80-c2-00-00-07 pass-thru
cpd-filter 01-80-c2-00-00-08 pass-thru
cpd-filter 01-80-c2-00-00-09 pass-thru
cpd-filter 01-80-c2-00-00-0a pass-thru
cpd-filter 01-80-c2-00-00-0b pass-thru
cpd-filter 01-80-c2-00-00-0c pass-thru
cpd-filter 01-80-c2-00-00-0d pass-thru
cpd-filter 01-80-c2-00-00-0e pass-thru
cpd-filter 01-80-c2-00-00-0f pass-thru

0 comments on commit 20037cb

Please sign in to comment.