Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds utility functions ios #140

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 94 additions & 0 deletions netutils/config/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,100 @@ def build_config_relationship(self) -> t.List[ConfigLine]:
self._update_config_lines(line)
return self.config_lines

@staticmethod
def _match_type_check(line: str, pattern: str, match_type: str) -> bool:
"""Checks pattern for exact match or regex."""
if match_type == "exact" and line == pattern:
return True
if match_type == "startswith" and line.startswith(pattern):
return True
if match_type == "endswith" and line.endswith(pattern):
return True
if match_type == "regex" and re.match(pattern, line):
return True
return False

def find_all_children(self, pattern: str, match_type: str = "exact") -> t.List[str]:
"""Returns configuration part for a specific pattern not including parents.

Args:
pattern: pattern that describes parent.
match_type (optional): Exact or regex. Defaults to "exact".

Returns:
configuration under that parent pattern.
Example:
>>> config = '''
... router bgp 45000
... address-family ipv4 unicast
... neighbor 192.168.1.2 activate
... network 172.17.1.0 mas'''
mundruid marked this conversation as resolved.
Show resolved Hide resolved
>>> bgp_conf = BaseSpaceConfigParser(str(config)).find_all_children(pattern="router bgp", match_type="regex")
mundruid marked this conversation as resolved.
Show resolved Hide resolved
>>> print(bgp_conf)
['router bgp 45000', ' address-family ipv4 unicast', ' neighbor 192.168.1.2 activate', ' network 172.17.1.0 mas']
"""
config = []
for cfg_line in self.build_config_relationship():
parents = cfg_line.parents[0] if cfg_line.parents else None
if (
parents
and self._match_type_check(parents, pattern, match_type)
or self._match_type_check(cfg_line.config_line, pattern, match_type)
):
config.append(cfg_line.config_line)
return config

def find_children_w_parents(
self, parent_pattern: str, child_pattern: str, match_type: str = "exact"
) -> t.List[str]:
"""Returns configuration part for a specific pattern including parents and children.

Args:
parent_pattern: pattern that describes parent.
child_pattern: pattern that describes child.
match_type (optional): Exact or regex. Defaults to "exact".

Returns:
configuration under that parent pattern.
Example:
>>> config = '''
... router bgp 45000
... address-family ipv4 unicast
... neighbor 192.168.1.2 activate
... network 172.17.1.0 mas'''
mundruid marked this conversation as resolved.
Show resolved Hide resolved
>>> bgp_conf = BaseSpaceConfigParser(str(config)).find_children_w_parents(parent_pattern="router bgp", child_pattern=" address-family", match_type="regex")
>>> print(bgp_conf)
[' address-family ipv4 unicast', ' neighbor 192.168.1.2 activate', ' network 172.17.1.0 mas']
mundruid marked this conversation as resolved.
Show resolved Hide resolved
"""
config = []
potential_parents = [
elem.parents[0]
for elem in self.build_config_relationship()
if self._match_type_check(elem.config_line, child_pattern, match_type)
]
for cfg_line in self.build_config_relationship():
parents = cfg_line.parents[0] if cfg_line.parents else None
if parents in potential_parents and self._match_type_check(parents, parent_pattern, match_type):
config.append(cfg_line.config_line)
return config

# def find_blocks():
# def find_children():
# def find_children_w_parents():
# def find_interface_objects():
# def find_lineage():
# def find_lines():
# def find_object_branches():
# def find_objects():
# def find_objects_dna():
# def find_objects_w_all_children():
# def find_objects_w_child():
# def find_objects_w_missing_children():
# def find_objects_w_parents():
# def find_objects_wo_child():
# def find_parents_w_child():
# def find_parents_wo_child():
mundruid marked this conversation as resolved.
Show resolved Hide resolved


class BaseBraceConfigParser(BaseConfigParser):
"""Base parser class for config syntax that demarcates using braces."""
Expand Down
14 changes: 14 additions & 0 deletions tests/unit/mock/config/parser/get_path/certificate.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
crypto pki trustpoint TP-self-signed-1088426642
enrollment selfsigned
subject-name cn=IOS-Self-Signed-Certificate-1088426642
revocation-check none
rsakeypair TP-self-signed-1088426642
crypto pki trustpoint SLA-TrustPoint
enrollment pkcs12
revocation-check crl
crypto pki certificate chain TP-self-signed-1088426642
certificate self-signed 01
quit
crypto pki certificate chain SLA-TrustPoint
certificate ca 01
quit
24 changes: 24 additions & 0 deletions tests/unit/mock/config/parser/get_path/interface.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
no ip address
negotiation auto
no mop enabled
no mop sysid
no ip address
shutdown
negotiation auto
no mop enabled
no mop sysid
no ip address
shutdown
negotiation auto
no mop enabled
no mop sysid
no ip address
shutdown
negotiation auto
no mop enabled
no mop sysid
no ip address
shutdown
negotiation auto
no mop enabled
no mop sysid
Loading