NetworkParse API

Parsing

Parse a network configuration file

To begin using networkparse, typically an subclass of ConfigBase will be instantiated with the text of the configuration file. Currently, networkparse has support for:

The automatic parser, automatic() may be a more effecient way to get started if a single script may work work multiple configuration types.

Automatic Parsing

networkparse.parse.automatic(config_content: str, *, include: List[str] = None, fallback: ConfigBase | None = None) ConfigBase

Based on the given configuration, guess the best parser.

Currently, this function can guess the following (ordered base on reliability)

  • ASA: reliable

  • FortiOS: probably reliable

  • JunOS: probably reliable

  • IOS: may catch non-IOS items, but is last thing checked

  • NX: untested, might work

Parameters:
  • include – Only check the given types. Types are “asa”, “ios”, “nxos”, “fortios”, “hp”, and “junos”. By default all options will be checked. The names used match with the name of each ConfigBase subclass.

  • fallabck – If not match is found, use the specified class as a parser. This should be an object, not an instance (i.e., parse.ConfigIOS vs. parse.ConfigIOS()).

Raises:

UnknownConfigError – The correct configuration type could not be determined

Returns:

Parsed configuration

Return type:

ConfigBase

Base Configuration Manager

ConfigBase will almost never be directly created, but it’s functionality is shared by all other configuration classes. To avoid duplicate documentation, refer back to this class for complete details on what a configuration type offers.

class networkparse.parse.ConfigBase(name='base', original_lines: List[str] = None, comment_marker: str = '!', full_match_default: bool = True, indent_size_default: int = 2)

Common configuration base operations

ConfigBase is really just a specialized ConfigLineList that can hold some settings and act like a ConfigLine in terms of having a parent (None) and children.

Refer to ConfigLineList for filtering and searching options after you’ve parsed a configuration file.

can_have_children(line: ConfigLine | str)

Checks if the given line is allowed to have child lines

Defaults to true, for compatibility with existing code

property children: ConfigLineList

Allow for use of “.children” for consistency with ConfigLine

Returns self, which is already a ConfigLineList. It is likely cleaner to not use this. I.E.:

config = ConfigIOS(running_config_contents)

# Prefer this
config.filter("interface .+")

# Only use this if it looks clearer in context
config.children.filter("interface .+")
comment_marker = '!'

Defaults to ! as the comment marker, following Cisco convention. If more complex comment checking is needed override is_comment()

full_match = True

Default setting for full_match in filter. Defaults to True to prevent a search from also matching the “no” version of the line.

get_line(line_number) ConfigLine

Get a line by line-number

Note that if the given line numbers falls in the middle of a multi-line string, it may not be found, depending on how the individual parser represents it.

Parameters:

line_number – Returns the line at the given line number.

Raises:

IndexError – The given line_number does not exist in the config

Returns:

Line at the given line number

Return type:

ConfigLine

property indent

The base config is never indented, at least for our purposes

indent_size = 2

How far tree_display() should indent children. Has no effect on parsing

name = 'base'

Name of configuration type, usable by scripts that support multiple configuration types.

original_lines = None

Original configuration lines, before any parsing occured. The line_number from a ConfigLine will match up with this list

parent = None

Exists to make walking up a parent tree easier–just look for parent=None to stop

Contrived example:

current_line = config.filter("no shutdown", depth=None)
while current_line.parent is not None:
    print(current_line)
    current_line = current_line.parent
property version: VersionNumber | None

Returns the version number of the configuration

This is intended to help with major version differences, i.e., IOS v12 vs. v15 differences. Generally it indentifies the version by looking for a line like “version 12.2”, although the details vary based on the parser in use. More details can be found on each of the base classes.

Returns:

Floating-point version number (i.e. 12.1 or 15.4) or None if the version cannot be found

Return type:

Optional[VersionNumber]

Cisco

class networkparse.parse.ConfigIOS(config_content: str)

Parses Cisco IOS-style configuration into common config format

Supported command output:

  • show running-config

  • show running-config all

  • show startup-config

name is set to “ios” for this parser.

See ConfigBase for more information.

can_have_children(line: ConfigLine | str)

Checks if the given line is allowed to have child lines

property version: VersionNumber | None

Returns the version number of the configuration

This is intended to help with v12 vs. v15 differences. It identifies the version by looking for a line like “version 12.2”.

Returns:

Version number (i.e. 12 or 15) or None if the version cannot be found

Return type:

Optional[VersionNumber]

class networkparse.parse.ConfigNXOS(config_content: str)

Parses Cisco NX-OS-style configuration into common config format

Currently this parser completely defers to ConfigIOS.

See ConfigIOS for more information.

class networkparse.parse.ConfigASA(config_content: str)

Parses Cisco ASA-style configuration into common config format

Supported command output:

  • show running-config

  • show running-config all

  • show startup-config

name is set to “asa” for this parser.

See ConfigBase for more information.

property version: VersionNumber | None

Returns the major version number of the configuration

This is intended to help difference between major versions. It indentifies the version by looking for a line like “ASA Version 9.0(3)”.

Returns:

Version number (i.e. 12.1 or 15.4) or None if the version cannot be found

Return type:

Optional[VersionNumber]

Fortinet

class networkparse.parse.ConfigFortigate(config_content: str)

Parses Fortinet-style configuration into common config format

Supported command output:

  • show full-configuration

name is set to “fortios” for this parser.

See ConfigBase for more information.

property version: VersionNumber | None

Returns the version number of the configuration

This is intended to help with v12 vs. v15 types of differences. It indentifies the version by looking for a line like “#config-version=FGVM64-6.2.0-FW-build0866-190328:opmode=0:vdom=0:user=admin”.

Returns:

Float version number (i.e. 6.2) or None if the version cannot be found

Return type:

Optional[VersionNumber]

HP

class networkparse.parse.ConfigHPCommware(config_content: str)

Parses HP Commware-style configuration into common config format

name is set to “hp” for this parser.

See ConfigBase for more information.

property version: VersionNumber | None

Returns the major version number of the configuration

This is intended to help with v12 vs. v15 differences. It indentifies the version by looking for a line like “version 5.20, Release 1513P81”.

Returns:

Version number (i.e. 5.20) or None if the version cannot be found

Juniper

class networkparse.parse.ConfigJunos(config_content: str)

Parses a Juniper OS (Junos)-style configuration into common config format

Supported command outputs are:

  • show configuration

  • save

name is set to “junos” for this parser.

See ConfigBase for more information.

Parsing Utils

class networkparse.parse.VersionNumber(major: int, minor: int = 0, revision: int = 0)

Firmware version number

classmethod from_string(string) VersionNumber

Given a string containing a release number, returns a VersionNumber

Supported formats:

  • 1.2.3

  • 1.2

  • 1.2(3)

Version string may appear anywhere in the given string.

Parameters:

string – String to attempt to parse

Returns:

VersionNumber with major, minor, and (if available) revision number set

Return type:

VersionNumber

Searching

Once a ConfigBase has been created, searching is typically done using ConfigLineList and ConfigLine.

class networkparse.core.ConfigLineList(lines: List[ConfigLine] = None)

A searchable list of ConfigLine s

This class acts like a standard Python list, so indexed access via [], len(), etc. all work. See the Python 3 documentation on list for more methods.

This class may not hold only ConfigLine items from the same parent–it can store any ConfigLine, so be aware that iterating through a ConfigLineList does not necessarily mean all items have the same parent. In particular, after running filter() or flatten() the returned list will be a mixture of parents.

copy() List

Create a copy of this list

Returns:

Copy of list. ConfigLine s are not duplicated.

Return type:

ConfigLineList

exclude(regex: str, **kwargs) List

Calls filter() with invert = True

kwargs are passed through to filter(), see that for for argument descriptions.

Returns:

List with matching lines removed

Return type:

ConfigLineList

filter(regex: str, *, full_match: bool = None, ignore_case: bool = False, invert: bool = False, depth: int = 0, skip_comments: bool = True) List

Find all lines that match a regular expression

Parameters:
  • regex – A string in Python’s regex format that will be checked against each line

  • full_match – If True, the regex must match the entire line (using Python’s re.fullmatch). If False, the regex can match any where in the line (using re.search). If None, uses the default for contained lines’ config_manager (typically True).

  • ignore_case – If True, the regex will be compiled with the flag re.IGNORECASE.

  • invert – If True, excludes matched items from the list. Default is False, matching lines are returned in the new list

  • depth

    Controls whether searches look at direct descendents

    • depth = 0: Line must be in this list, not a child

    • depth > 0: Also search the children of each line, up to the given depth

    • depth = None: Search through entire tree

  • skip_comments – Controls whether search never returns comments. Default is True, meaning comment lines are never matched. Note that enabling this still means regex must match the line, including any comment characters.

Returns:

New ConfigLineList with the filtered items. Returns an empty list if none are found.

Return type:

ConfigLineList

filter_with_child(child_regex: str, *, full_match: bool = None, ignore_case: bool = False, depth: int = 0) List

Find all lines that have a child that matches the given regex.

Parameters:
  • child_regex – Regular expression that child line must match

  • full_match – Whether the regex must match the entire child line. See filter() for more details.

  • ignore_case – If True, the regex will be compiled with the flag re.IGNORECASE. See filter() for more details.

  • depth – If is not 0, the child does not need to be a direct descendent. See filter()’s depth argument for more details.

Returns:

New filtered list

Return type:

ConfigLineList

For example, if this list has these items (children shown as well):

child
child 1
child 2
child 3
    child 4
    child 5
child 6
    child 7
        child 8
        child 9

Then filter_with_child("child 4") will return the list:

child 3
    child 4
    child 5

If depth is not 0, the child does not need to be a direct descendent. See filter()’s depth argument for more details. Given the example above, _with_child(“child 8”, depth=None)` will return the list:

child 6
    child 7
        child 8
        child 9
filter_without_child(child_regex: str, *, full_match: bool = None, ignore_case: bool = False, depth: int = 0, skip_childless: bool = False) List

Find all lines that do not have a child that matches the given regex.

Follows the symmatics of filter_with_child(), see that function for more details.

Parameters:

skip_childless – If False (the default), a line that has no children will always be matched by this function.

Returns:

New filtered list

Return type:

ConfigLineList

flatten(depth: int = None) List

Return a ConfigLineList of all of this list and the children

Parameters:

depth – If None, returns all children, recursing as deeply as needed into the hierarchy (technically, limited to 500). Otherwise, flattens only the top depth levels.

Returns:

New ConfigLineList

For example, say you have the structure:

level 1
    level 2
        level 3

flatten(depth=None) returns:

level 1
level 2
level 3

flatten(depth=1) returns:

level 1
level 2
    level 3
is_comment() bool

A list of lines is never comment

This exists to allow is_comment() to be called on a Config parser during setup, avoiding special cases.

Returns:

False

one() ConfigLine

Returns the single ConfigLine in list

Raises:
Returns:

First and only ConfigLine

one_or_none() ConfigLine

Returns the single ConfigLine in list

Raises:

MultipleLinesError – There is more than one item in list. Use one() to raise an exception if there are no items

Returns:

First and only ConfigLine if there is one, otherwise None

tree_display(initial_indent: int = 0, line_number: bool = False, child_count: bool = False) str

Print all lines in list with indents to show hierachy

Parameters:
  • initial_indent – How many spaces to put before the first text on the line. If None, uses the “original” indent. See tree_display() for more details.

  • line_number – Display original line numbers of each line

  • child_count – Display the number of children each line has

Returns:

String of this and all child line items in an indented, human-readable format.

Also refer to ConfigLine’s tree_display().

Note

Top-level items may not all have the same parent, as a ConfigLineList can hold any combination of lines (even duplicates).

class networkparse.core.ConfigLine(config_manager, parent, text: str, *, line_number: int = None, children: List = None, indent: str = None)

A line of a configuration file, which may or may not have children

Generally supports the same functions as Python strings.

property can_have_children

Checks if this line is allowed to have children, according to the config manager

children: ConfigLineList = None

Lines “under” this one–for example, lines 2 and 3 below would be children to line 1.

1. interface Ethernet0/1
2.   no shutdown
3.   switchport mode access
config_manager: parse.ConfigBase = None

The ConfigBase-subclass which created the line and will be used for checking style-specific questions

count(sub, start=None, end=None)

See str.count

property depth: int

Returns how logically nested in the config this line is

For example, the config below has the .depth displayed next to each item:

child                0
child 1              0
child 2              0
child 3              0
    child 4          1
    child 5          1
child 6              0
    child 7          1
        child 8      2
        child 9      2
Returns:

0 for top-level items, 1 or more for child items.

endswith(sub, start=None, end=None)

See str.endswith

find(sub, start=None, end=None)

See str.find

get_next()

Returns next line in the configuration after this one

Returns None if this is the last line in the config.

Returns:

ConfigLine that is next in the configuration file based on line number

Return type:

ConfigLine

get_next_sibling()

Returns next sibling line in the configuration after this one

Returns None if there is no sibling item after this one. I.E., we would need to go up to the parent’s siblings to get the next line.

Returns:

ConfigLine that is next in the configuration file that is logically a sibling of this one

Return type:

ConfigLine

get_prev()

Returns previous line in the configuration after this one

Returns None if this is the first line in the config.

Returns:

ConfigLine that is previous in the configuration file based on line number

Return type:

ConfigLine

get_prev_sibling()

Returns previous sibling line in the configuration after this one

Returns None if there is no sibling item after this one. I.E., we would need to go up to the parent’s siblings to get the previous line.

Returns:

ConfigLine that is previous in the configuration file that is logically a sibling of this one

Return type:

ConfigLine

get_top() ConfigLine

Returns the top-level line that this child is a line of

May return the same line if it is a top-level item

Returns:

Top-level ConfigLine with no parents (other than the full config itself)

Return type:

ConfigLine

indent: str | None = None

Original raw indentation for line This is used internally by some parsers. If not used, it may be left as None

index(sub, start=None, end=None)

See str.index

is_comment() bool

Check if this line is a comment

Returns:

True if line is a commment, False otherwise

is_top() bool

Tests if this line is at the top-level of the configuration

Returns:

True if the parent is the config itself, False otherwise

Return type:

bool

line_number: int | None = None

The line number in the original configuration file

lower()

See str.lower

parent: parse.ConfigBase | ConfigLine = None

Parent block line (ie, might point to a line that’s interface Eth1/1) Could be a ConfigBase or another ConfigLine

partition(sep)

See str.partition

rfind(sub, start=None, end=None)

See str.rfind

rindex(sub, start=None, end=None)

See str.rindex

rpartition(sep)

See str.rpartition

rsplit(sep=None, maxsplit=-1)

See str.rsplit

property siblings

Returns a ConfigLineList of all sibling lines

Does not include this line in the list. If you do want this line in the list, try line.parent.children.

split(sep=None, maxsplit=-1)

See str.split

startswith(sub, start=None, end=None)

See str.startswith

text: str = ''

Text of configuration line, not including any leading or trailing whitespace Generally, treat the ConfigLine itself as a string, rather than using .text. For example:

# Prefer these:
parts = line.split()
print(line)

# To these:
parts = line.text.split()
print(line.text)
tree_display(initial_indent: int = 0, line_number: bool = False, child_count: bool = False, internal_indent: int = 0) str

Print this line and child lines indented to show hierachy

Parameters:
  • initial_indent – How many spaces to put before the first text on the line. If None, will use the “original” indent level–i.e., if this was a second-level item in the original config, it will be displayed with one indent before it.

  • line_number – Display original line numbers of each line

  • child_count – Display the number of children each line has

  • internal_indent – How many spaces to place after the line number

Returns:

String of this and all child line items in an indented, human-readable format.

upper()

See str.upper

Exceptions

class networkparse.core.MultipleLinesError

More than one line was found

class networkparse.core.NoLinesError

No lines were found and at least one was expected