Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
7 changes: 7 additions & 0 deletions netutils/config/compliance.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ def _is_feature_ordered_compliant(feature_intended_cfg: str, feature_actual_cfg:
bool

Examples:
>>> from netutils.config.compliance import _is_feature_ordered_compliant
>>> feature_intended_cfg = '''router bgp 100
... bgp router-id 10.6.6.5'''
>>>
Expand Down Expand Up @@ -134,6 +135,7 @@ def compliance(
dict: Compliance information per feature.

Examples:
>>> from netutils.config.compliance import compliance
>>> features = [
... {
... "name": "hostname",
Expand Down Expand Up @@ -206,6 +208,7 @@ def config_section_not_parsed(
Config that was not parsed or section not found.

Examples:
>>> from netutils.config.compliance import config_section_not_parsed
>>> features = [{
... "name": "BGP",
... "ordered": True,
Expand Down Expand Up @@ -247,6 +250,7 @@ def diff_network_config(compare_config: str, base_config: str, network_os: str)
base_config: The string of additional commands in compare_config separated by a newline.

Examples:
>>> from netutils.config.compliance import diff_network_config
>>> compare_config = '''router bgp 100
... bgp router-id 10.6.6.5
... !
Expand Down Expand Up @@ -300,6 +304,7 @@ def feature_compliance(
dict: Compliance information of a single feature.

Examples:
>>> from netutils.config.compliance import feature_compliance
>>> feature = {
... "name": "ntp",
... "ordered": True,
Expand Down Expand Up @@ -359,6 +364,7 @@ def find_unordered_cfg_lines(intended_cfg: str, actual_cfg: str) -> t.Tuple[bool
list: List of tuples with unordered_compliant cfg lines.

Examples:
>>> from netutils.config.compliance import find_unordered_cfg_lines
>>> intended_cfg = '''
... ntp server 10.10.10.10
... ntp server 10.10.10.11
Expand Down Expand Up @@ -399,6 +405,7 @@ def section_config(feature: t.Dict[str, t.Union[str, bool, t.List[str]]], device
The hash report data mapping file hashes to report data.

Examples:
>>> from netutils.config.compliance import section_config
>>> feature = {
... "name": "BGP",
... "ordered": False,
Expand Down
63 changes: 32 additions & 31 deletions netutils/config/conversion.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,37 +20,38 @@ def paloalto_panos_brace_to_set(cfg: str, cfg_type: str = "file") -> str:
str: Converted configuration as a string.

Examples:
>>> config = '''
... config {
... mgt-config {
... users {
... admin {
... phash *;
... permissions {
... role-based {
... superuser yes;
... }
... }
... public-key thisisasuperduperlongbase64encodedstring;
... }
... panadmin {
... permissions {
... role-based {
... superuser yes;
... }
... }
... phash passwordhash;
... }
... }
... }
... }'''
>>> paloalto_panos_brace_to_set(cfg=config, cfg_type='string') == \
... '''set mgt-config users admin phash *
... set mgt-config users admin permissions role-based superuser yes
... set mgt-config users admin public-key thisisasuperduperlongbase64encodedstring
... set mgt-config users panadmin permissions role-based superuser yes
... set mgt-config users panadmin phash passwordhash'''
True
>>> from netutils.config.conversion import paloalto_panos_brace_to_set
>>> config = '''
... config {
... mgt-config {
... users {
... admin {
... phash *;
... permissions {
... role-based {
... superuser yes;
... }
... }
... public-key thisisasuperduperlongbase64encodedstring;
... }
... panadmin {
... permissions {
... role-based {
... superuser yes;
... }
... }
... phash passwordhash;
... }
... }
... }
... }'''
>>> paloalto_panos_brace_to_set(cfg=config, cfg_type='string') == \
... '''set mgt-config users admin phash *
... set mgt-config users admin permissions role-based superuser yes
... set mgt-config users admin public-key thisisasuperduperlongbase64encodedstring
... set mgt-config users panadmin permissions role-based superuser yes
... set mgt-config users panadmin phash passwordhash'''
True
"""
stack: t.List[str] = []
cfg_value: t.List[str] = []
Expand Down
22 changes: 15 additions & 7 deletions netutils/config/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ def is_comment(self, line: str) -> bool:
True if line is a comment, else False.

Examples:
>>> from netutils.config.parser import BaseSpaceConfigParser
>>> BaseSpaceConfigParser("interface Ethernet1/1").is_comment("interface Ethernet1/1")
False
>>> BaseSpaceConfigParser("!").is_comment("!")
Expand All @@ -128,6 +129,7 @@ def config_lines_only(self) -> str:
The non-space and non-comment lines from ``config``.

Examples:
>>> from netutils.config.parser import BaseSpaceConfigParser
>>> config = '''!
... aaa group server tacacs+ auth
... server 10.1.1.1
Expand Down Expand Up @@ -162,6 +164,7 @@ def get_leading_space_count(config_line: str) -> int:
The number of leading spaces.

Examples:
>>> from netutils.config.parser import BaseSpaceConfigParser
>>> config = '''interface GigabitEthernet1\n description link to ISP'''
>>> config_line = " description link to ISP"
>>> indent_level = BaseSpaceConfigParser(config).get_leading_space_count(config_line)
Expand Down Expand Up @@ -286,6 +289,7 @@ def build_config_relationship(self) -> t.List[ConfigLine]:
r"""Parse text tree of config lines and their parents.

Examples:
>>> from netutils.config.parser import BaseSpaceConfigParser, ConfigLine
>>> config = (
... "interface Ethernet1/1\n"
... " vlan 10\n"
Expand Down Expand Up @@ -354,6 +358,7 @@ def find_all_children(self, pattern: str, match_type: str = "exact") -> t.List[s
configuration under that parent pattern.

Examples:
>>> from netutils.config.parser import BaseSpaceConfigParser
>>> config = '''
... router bgp 45000
... address-family ipv4 unicast
Expand Down Expand Up @@ -388,6 +393,7 @@ def find_children_w_parents(
configuration under that parent pattern.

Examples:
>>> from netutils.config.parser import BaseSpaceConfigParser
>>> config = '''
... router bgp 45000
... address-family ipv4 unicast
Expand Down Expand Up @@ -429,6 +435,7 @@ def build_config_relationship(self) -> t.List[ConfigLine]:
r"""Parse text tree of config lines and their parents.

Examples:
>>> from netutils.config.parser import BaseSpaceConfigParser, ConfigLine
>>> config = '''auth ldap system-auth {
... port ldaps
... servers { ams-lda01.ntc.com }
Expand Down Expand Up @@ -473,6 +480,7 @@ def _build_multiline_config(self, delimiter: str) -> t.Optional[ConfigLine]:
The multiline string text that was added to ``self.config_lines``.

Examples:
>>> from netutils.config.parser import BaseSpaceConfigParser, ConfigLine
>>> config = (
... 'sys syslog {\n'
... ' include "\n'
Expand Down Expand Up @@ -634,6 +642,7 @@ def build_config_relationship(self) -> t.List[ConfigLine]:
r"""Parse text tree of config lines and their parents.

Examples:
>>> from netutils.config.parser import IOSConfigParser, ConfigLine
>>> config = '''
... interface Ethernet1/1
... vlan 10
Expand Down Expand Up @@ -786,6 +795,7 @@ def build_config_relationship(self) -> t.List[ConfigLine]:
r"""Parse text tree of config lines and their parents.

Examples:
>>> from netutils.config.parser import F5ConfigParser, ConfigLine
>>> config = '''apm resource webtop-link aShare {
... application-uri http://funshare.example.com
... customization-group a_customization_group
Expand Down Expand Up @@ -838,13 +848,7 @@ def _build_multiline_single_configuration_line(self, delimiter: str, prev_line:
The multiline string text that was added to ``self.config_lines``.

Examples:
config = '''apm resource webtop-link aShare {
application-uri http://funshare.example.com
customization-group a_customization_group
}
apm sso form-based portal_ext_sso_form_based {
form-action /Citrix/Example/ExplicitAuth/LoginAttempt
>>>
>>> from netutils.config.parser import F5ConfigParser, ConfigLine
>>> config = '''apm resource webtop-link aShare {
... application-uri http://funshare.example.com
... customization-group a_customization_group
Expand Down Expand Up @@ -928,6 +932,7 @@ def build_config_relationship(self) -> t.List[ConfigLine]:
r"""Parse text tree of config lines and their parents.

Examples:
>>> from netutils.config.parser import ASAConfigParser, ConfigLine
>>> config = '''
... interface Management0/0
... management-only
Expand Down Expand Up @@ -995,6 +1000,7 @@ def is_end_next(self, line: str) -> bool:
True if line has 'end' or 'next', else False.

Examples:
>>> from netutils.config.parser import FortinetConfigParser
>>> FortinetConfigParser("config system virtual-switch").is_end_next("config system virtual-switch")
False
>>> FortinetConfigParser("end").is_end_next("end")
Expand Down Expand Up @@ -1310,6 +1316,7 @@ def build_config_relationship(self) -> t.List[ConfigLine]:
r"""Parse text tree of config lines and their parents.

Examples:
>>> from netutils.config.parser import IOSXRConfigParser, ConfigLine
>>> config = (
... "interface Ethernet1/1\n"
... " vlan 10\n"
Expand Down Expand Up @@ -1472,6 +1479,7 @@ def build_config_relationship(self) -> t.List[ConfigLine]: # pylint: disable=to
r"""Parse text of config lines and find their parents.

Examples:
>>> from netutils.config.parser import PaloAltoNetworksConfigParser, ConfigLine
>>> config = (
... "set deviceconfig system hostname firewall1\n"
... "set deviceconfig system panorama local-panorama panorama-server 10.0.0.1\n"
Expand Down
4 changes: 4 additions & 0 deletions netutils/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ def abbreviated_interface_name(
The name of the interface in the abbreviated form.

Examples:
>>> from netutils.interface import abbreviated_interface_name
>>> abbreviated_interface_name("GigabitEthernet1/0/1")
'Gi1/0/1'
>>> abbreviated_interface_name("Eth1")
Expand Down Expand Up @@ -444,6 +445,7 @@ def sort_interface_list(interfaces: t.List[str]) -> t.List[str]:
A **new** sorted, unique list elements from the input.

Examples:
>>> from netutils.interface import sort_interface_list
>>> sort_interface_list(["Gi1/0/1", "Gi1/0/3", "Gi1/0/3.100", "Gi1/0/2", "Gi1/0/2.50", "Gi2/0/2", "Po40", "Po160", "Lo10"])
['Gi1/0/1', 'Gi1/0/2', 'Gi1/0/2.50', 'Gi1/0/3', 'Gi1/0/3.100', 'Gi2/0/2', 'Lo10', 'Po40', 'Po160']
>>> sort_interface_list(['GigabitEthernet1/0/1', 'GigabitEthernet1/0/3', 'GigabitEthernet1/0/2', "GigabitEthernet3/0/5", 'GigabitEthernet3/0/7', 'GigabitEthernet2/0/8.5', 'Port-channel40', 'Vlan20', 'Loopback10'])
Expand Down Expand Up @@ -557,6 +559,7 @@ def _ranges_in_list(numbers: t.List[int]) -> t.List[t.List[int]]:
"""Find contiguous ranges in a list of numbers.

Examples:
>>> from netutils.interface import _ranges_in_list
>>> _ranges_in_list([1, 2, 3, 5, 6, 8])
[[1, 2, 3], [5, 6], [8]]

Expand All @@ -577,6 +580,7 @@ def interface_range_compress(interface_list: t.List[str]) -> t.List[str]:
E.g. Gi =! GigabitEthernet

Examples:
>>> from netutils.interface import interface_range_compress
>>> interface_range_compress(["Gi1/0/1", "Gi1/0/2", "Gi1/0/3", "Gi1/0/5"])
['Gi1/0/1-3', 'Gi1/0/5']
>>> interface_range_compress(["Gi0/1", "Gi0/2", "Gi0/4", "Gi1/0", "Gi1/1"])
Expand Down