[![logo][66]][66]
# ciscoconfparse2
[![git commits][41]][42] [![Version][2]][3] [![Downloads][6]][7] [![License][8]][9] [![Hatch project][68]][69]
[![SonarCloud][51]][52] [![SonarCloud Maintainability Rating][53]][54] [![SonarCloud Lines of Code][55]][56] [![SonarCloud Bugs][59]][60] [![SonarCloud Code Smells][57]][58] [![SonarCloud Tech Debt][61]][62]
## Introduction: What is ciscoconfparse2?
### Summary
[ciscoconfparse2][17] is similar to an advanced grep and diff that
specializes in network configuration files (such as those from Cisco,
Juniper, Palo Alto, etc); it is the next generation of
[ciscoconfparse][64], which was the primary development package
from 2007 until 2023.
### CLI Tool
[ciscoconfparse2][17] distributes a [CLI tool][67] that will diff and grep various
network configuration or text files.
### Simple Python API Usage
In addition to the CLI tool, [ciscoconfparse2][17] also offers a Python API.
This example code parses a configuration stored in
`tests/fixtures/configs/sample_02.ios` and select interfaces that are shutdown.
In this case, the parent is a line containing `interface` and the child is a
line containing the word `shutdown`.
```python
# filename: example.py
from ciscoconfparse2 import CiscoConfParse
##############################################################################
# Find all Cisco IOS interface names that are shutdown
##############################################################################
#
# Search for:
# !
# interface Foo
# description ignore-this-line
# shutdown
# !
# Search a configuration in the test fixutres directory
parse = CiscoConfParse('tests/fixtures/configs/sample_02.ios', syntax='ios')
# Find a parent line containing 'interface' and child line with 'shutdown'
for intf_obj in parse.find_parent_objects(['interface', 'shutdown']):
intf_name = " ".join(intf_obj.split()[1:])
print(f"Shutdown: {intf_name}")
```
That will print:
```none
$ python example.py
Shutdown: FastEthernet0/7
Shutdown: FastEthernet0/8
Shutdown: FastEthernet0/9
Shutdown: FastEthernet0/11
Shutdown: FastEthernet0/13
Shutdown: FastEthernet0/15
Shutdown: FastEthernet0/17
Shutdown: FastEthernet0/19
Shutdown: FastEthernet0/20
Shutdown: FastEthernet0/22
Shutdown: VLAN1
```
### Complex Python API Example
The following code will parse a configuration stored in
`tests/fixtures/configs/sample_08.ios` and will find the
IP address / switchport parameters assigned to interfaces.
```python
from ciscoconfparse2 import CiscoConfParse
from ciscoconfparse2 import IPv4Obj
def intf_csv(intf_obj: str) -> str:
"""
:return: CSV for each interface object.
:rtype: str
"""
intf_name = " ".join(intf_obj.split()[1:]) # Use a string split() method from the BaseCfgLine()
admin_status = intf_obj.re_match_iter_typed("^\s+(shutdown)", default="not_shutdown", result_type=str)
# Search children of all interfaces for a regex match and return
# the value matched in regex match group 1. If there is no match,
# return a default value: 0.0.0.1/32
addr_netmask = intf_obj.re_match_iter_typed(
r"^\s+ip\saddress\s(\d+\.\d+\.\d+\.\d+\s\S+)", result_type=IPv4Obj,
group=1, default=IPv4Obj("0.0.0.1/32"))
# Find the description and replace all commas in it
description = intf_obj.re_match_iter_typed("description\s+(\S.*)").replace(",", "_")
switchport_status = intf_obj.re_match_iter_typed("(switchport)", default="not_switched")
# Return a csv based on whether this is a switchport
if switchport_status == "not_switched":
return f"{intf_name},{admin_status},{addr_netmask.as_cidr_addr},{switchport_status},,,{description}"
else:
# Only calculate switchport values if this is a switchport
trunk_access = intf_obj.re_match_iter_typed("switchport mode (trunk)", default="access", result_type=str)
access_vlan = intf_obj.re_match_iter_typed("switchport access vlan (\d+)", default=1, result_type=int)
return f"{intf_name},{admin_status},,{switchport_status},{trunk_access},{access_vlan},{description}"
parse = CiscoConfParse('tests/fixtures/configs/sample_08.ios', syntax='ios')
# Find interface BaseCfgLine() instances...
for intf_obj in parse.find_objects('^interface'):
print(intf_csv(intf_obj))
```
That will print:
```none
$ python example.py
Loopback0,not_shutdown,172.16.0.1/32,not_switched,,,SEE http://www.cymru.com/Documents/secure-ios-template.html
Null0,not_shutdown,0.0.0.1/32,not_switched,,,
ATM0/0,not_shutdown,0.0.0.1/32,not_switched,,,
ATM0/0.32 point-to-point,not_shutdown,0.0.0.1/32,not_switched,,,
FastEthernet0/0,not_shutdown,172.16.2.1/24,not_switched,,,[IPv4 and IPv6 desktop / laptop hosts on 2nd-floor North LAN]
FastEthernet0/1,not_shutdown,172.16.3.1/30,not_switched,,,[IPv4 and IPv6 OSPF Transit via West side of building]
FastEthernet1/0,not_shutdown,172.16.4.1/30,not_switched,,,[IPv4 and IPv6 OSPF Transit via North side of building]
FastEtheret1/1,not_shutdown,,switchport,access,12,[switchport to the comptroller cube]
FastEtheret1/2,not_shutdown,,switchport,access,12,[switchport to the IDF media converter]
Virtual-Template1,not_shutdown,0.0.0.1/32,not_switched,,,
Dialer1,not_shutdown,0.0.0.1/32,not_switched,,,[IPv4 and IPv6 OSPF Transit via WAN Dialer: NAT_ CBWFQ interface]
```
### Cisco IOS Factory Usage
CiscoConfParse has a special feature that abstracts common IOS / NXOS / ASA / IOS XR fields; at this time, it is only useful on IOS configurations. You will see factory parsing in CiscoConfParse code as parsing the configuration with `factory=True`.
Factory parsing is still beta-quality and should be used at your own risk.
## Why
[ciscoconfparse2][17] is a [Python][10] library
that helps you quickly answer questions like these about your
Cisco configurations:
- What interfaces are shutdown?
- Which interfaces are in trunk mode?
- What address and subnet mask is assigned to each interface?
- Which interfaces are missing a critical command?
- Is this configuration missing a standard config line?
It can help you:
- Audit existing router / switch / firewall / wlc configurations
- Modify existing configurations
- Build new configurations
Speaking generally, the library examines an IOS-style config and breaks
it into a set of linked parent / child relationships. You can perform
complex queries about these relationships.
[![Cisco IOS config: Parent / child][11]][11]
### What changed in ciscoconfparse2?
In late 2023, I started a rewrite because [ciscoconfparse][64] is too large
and has some defaults that I wish it didn't have. I froze
[ciscoconfparse][64] PYPI releases at [version 1.9.41][65]; there will be no
more [ciscoconfparse][64] PYPI releases.
What do you do? Upgrade to [ciscoconfparse2][17]!
Here's why, it:
- Includes a handy [CLI command][67] (including greps for mac addresses and IPv4 / IPv6 subnets)
- Streamlines the API towards a simpler user interface.
- Removes legacy and flawed methods from the original (this could be a breaking change for old scripts).
- Adds string methods to `BaseCfgLine()` objects
- Defaults `ignore_blank_lines=False` (this could be a breaking change for old scripts).
- Is better at handling multiple-child-level configurations (such as IOS XR and JunOS)
- Can search for parents and children using an *arbitrary list of ancestors*
- Adds the concept of change commits; this is a config-modification safety feature that [ciscoconfparse][64] lacks
- Adds an `auto_commit` keyword, which defaults True
- Documents much more of the API
- Intentionally requires a different import statement to minimize confusion between the original and [ciscoconfparse2][17]
- Vasly improves Cisco IOS diffs
## What if we don\'t use Cisco IOS?
In many cases, you can parse [brace-delimited configurations][13] into a Cisco IOS style (see [original ciscoconfparse Github Issue \#17][14]), which means that CiscoConfParse may be able to parse these configurations:
- Juniper Networks Junos OS
- Palo Alto Networks Firewall configurations
- F5 Networks configurations (known caveats)
CiscoConfParse also handles anything that has a Cisco IOS style of configuration, which includes:
- Cisco IOS, Cisco Nexus, Cisco IOS-XR, Cisco IOS-XE, Aironet OS, Cisco ASA, Cisco CatOS
- Arista EOS
- Brocade
- HP Switches
- Force 10 Switches
- Dell PowerConnect Switches
- Extreme Networks
- Enterasys
- Screenos
## Docs
- The latest copy of the docs are [archived on the web][15]
## Installation and Downloads
- Use `pip` for Python3.x\... :
python -m pip install ciscoconfparse2
## What is the pythonic way of handling script credentials?
1. Never hard-code credentials
2. Use [python-dotenv](https://github.com/theskumar/python-dotenv)
## Is this a tool, or is it artwork?
That depends on who you ask. Many companies use CiscoConfParse as part of their
network engineering toolbox; others regard it as a form of artwork.
## Pre-requisites
[The ciscoconfparse2 python package][3] requires Python versions 3.7+.
Type-hinting (work-in-progress) targets Python3.9+ due to the need for `tuple[str, ...]` hints.
## Other Resources
- [Dive into Python3](http://www.diveintopython3.net/) is a good way to learn Python
- [Team CYMRU][30] has a [Secure IOS Template][29], which is especially useful for external-facing routers / switches
- [Cisco\'s Guide to hardening IOS devices][31]
- [Center for Internet Security Benchmarks][32] (An email address, cookies, and javascript are required)
## Are you releasing licensing besides GPLv3?
I will not. however, if it's truly a problem for your company, there are commercial solutions available (to include purchasing the project, or hiring me).
## Bug Tracker and Support
- Please report any suggestions, bug reports, or annoyances with a [github bug report][24].
- If you\'re having problems with general python issues, consider searching for a solution on [Stack Overflow][33]. If you can\'t find a solution for your problem or need more help, you can [ask on Stack Overflow][34] or [reddit/r/Python][39].
- If you\'re having problems with your Cisco devices, you can contact:
- [Cisco TAC][28]
- [reddit/r/Cisco][35]
- [reddit/r/networking][36]
- [NetworkEngineering.se][23]
## Dependencies
- [Python 3](https://python.org/)
- [attrs](https://github.com/python-attrs/attrs)
- [passlib](https://github.com/glic3rinu/passlib)
- [tomlkit](https://github.com/sdispater/tomlkit)
- [dnspython](https://github.com/rthalley/dnspython)
- [`hier_config`](https://github.com/netdevops/hier_config)
- [`PyYAML`](https://github.com/yaml/pyyaml)
- [`pyparsing`](https://github.com/pyparsing/pyparsing)
- [typeguard](https://github.com/agronholm/typeguard)
- [loguru](https://github.com/Delgan/loguru)
## Build and Development
I recommend that you use [`hatch`][69] to build and manage the package versions.
Typical development workflow looks like this:
- git clone this repo
- make changes
- git commit your code changes
- `hatch run pytest`
- Edit `CHANGES.md` with your changes
- Bump the `ciscoconfparse2` version number in `ciscoconfparse2/__about__.py` with `hatch version micro` or `hatch version minor`
- Publish to github with `make cicd`
- `cd sphinx-doc` and `make html`
- publish documentation changes
## Unit-Tests and SonarCloud
- We are manually disabling some [SonarCloud](https://sonarcloud.io/) alerts with:
- `#pragma warning disable S1313`
- `#pragma warning restore S1313`
- Where `S1313` is a False-positive that [SonarCloud](https://sonarcloud.io) flags
- Those `#pragma warning` lines should be carefully-fenced to ensure that we don't disable a [SonarCloud](https://sonarcloud.io/) alert that is useful.
### Semantic Versioning and Conventional Commits
- At this point, [ciscoconfparse2][3] does NOT adhere to [Semantic Versioning][49]
- Although we added [commitizen][48] as a dev dependency, we are NOT enforcing commit rules (such as [Conventional Commits][50]) yet.
### Execute Unit tests
The project\'s [test workflow][1] checks ciscoconfparse2 on Python versions 3.7 and higher, as well as a [pypy JIT][22] executable.
If you already git cloned the repo and want to manually run tests either run with `make test` from the base directory, or manually run with [`pytest`][63] in a unix-like system...
```shell
$ cd tests
$ pytest ./test*py
...
```
### Execute Test Coverage Line-Miss Report
If you already have have `pytest` and `pytest-cov` installed, run a test line miss report as shown below.
```shell
$ # Install the latest ciscoconfparse2
$ # (assuming the latest code is on pypi)
$ pip install -U ciscoconfparse2
$ pip install -U pytest-cov
$ cd tests
$ pytest --cov-report=term-missing --cov=ciscoconfparse2 ./
...
```
### Editing the Package
This uses the example of editing the package on a git branch called `develop`...
- `git clone https://github.com/mpenning/ciscoconfparse2`
- `cd ciscoconfparse2`
- `git branch develop`
- `git checkout develop`
- Add / modify / delete on the `develop` branch
- `make test`
- If tests run clean, `git commit` all the pending changes on the `develop` branch
- If you plan to publish this as an official version rev, edit the version number in [pyproject.toml][12]. In the future, we want to integrate `commitizen` to manage versioning.
- `git checkout main`
- `git merge develop`
- `make test`
- `git push origin main`
- `make pypi`
### Sphinx Documentation
Building the ciscoconfparse2 documentation tarball comes down to this one wierd trick:
- `cd sphinx-doc/`
- `pip install ciscoconfparse`
- `make html`
## License and Copyright
[ciscoconfparse2][3] is licensed [GPLv3][21]
- Copyright (C) 2023-2024 David Michael Pennington
The word \"Cisco\" is a registered trademark of [Cisco Systems][27].
## Author
[ciscoconfparse2][3] was written by [David Michael Pennington][25].
[1]: https://github.com/mpenning/ciscoconfparse2/blob/main/.github/workflows/tests.yml
[2]: https://img.shields.io/pypi/v/ciscoconfparse2.svg
[3]: https://pypi.python.org/pypi/ciscoconfparse2/
[4]: https://github.com/mpenning/ciscoconfparse2/actions/workflows/tests.yml/badge.svg
[5]: https://github.com/mpenning/ciscoconfparse2/actions/workflows/tests.yml
[6]: https://pepy.tech/badge/ciscoconfparse2
[7]: https://pepy.tech/project/ciscoconfparse2
[8]: http://img.shields.io/badge/license-GPLv3-blue.svg
[9]: https://www.gnu.org/copyleft/gpl.html
[10]: https://www.python.org
[11]: https://raw.githubusercontent.com/mpenning/ciscoconfparse/master/sphinx-doc/_static/ciscoconfparse_overview_75pct.png
[12]: https://github.com/mpenning/ciscoconfparse2/blob/main/pyproject.toml
[13]: https://github.com/mpenning/ciscoconfparse2/blob/master/configs/sample_01.junos
[14]: https://github.com/mpenning/ciscoconfparse/issues/17
[15]: http://www.pennington.net/py/ciscoconfparse2/
[16]: http://pennington.net/tutorial/ciscoconfparse2/ccp_tutorial.html
[17]: https://github.com/mpenning/ciscoconfparse2
[18]: https://github.com/mpenning/ciscoconfparse/issues/117
[19]: https://github.com/mpenning/ciscoconfparse/issues/13
[20]: https://github.com/CrackerJackMack/
[21]: http://www.gnu.org/licenses/gpl-3.0.html
[22]: https://pypy.org
[23]: https://networkengineering.stackexchange.com/
[24]: https://github.com/mpenning/ciscoconfparse2/issues/new/choose
[25]: https://github.com/mpenning
[26]: https://github.com/muir
[27]: https://www.cisco.com/
[28]: https://www.cisco.com/go/support
[29]: https://www.cymru.com/Documents/secure-ios-template.html
[30]: https://team-cymru.com/company/
[31]: http://www.cisco.com/c/en/us/support/docs/ip/access-lists/13608-21.html
[32]: https://learn.cisecurity.org/benchmarks
[33]: https://stackoverflow.com
[34]: http://stackoverflow.com/questions/ask
[35]: https://www.reddit.com/r/Cisco/
[36]: https://www.reddit.com/r/networking
[37]: https://snyk.io/advisor/python/ciscoconfparse2/badge.svg
[38]: https://snyk.io/advisor/python/ciscoconfparse2
[39]: https://www.reddit.com/r/Python/
[41]: https://img.shields.io/github/commit-activity/m/mpenning/ciscoconfparse2
[42]: https://img.shields.io/github/commit-activity/m/mpenning/ciscoconfparse2
[43]: https://www.codefactor.io/Content/badges/B.svg
[44]: https://www.codefactor.io/repository/github/mpenning/ciscoconfparse2/
[45]: https://fossa.com/blog/open-source-software-licenses-101-gpl-v3/
[46]: https://app.codacy.com/project/badge/Grade/4774ebb0292d4e1d9dc30bf263d9df14
[47]: https://app.codacy.com/gh/mpenning/ciscoconfparse2/dashboard
[48]: https://commitizen-tools.github.io/commitizen/
[49]: https://semver.org/
[50]: https://www.conventionalcommits.org/en/v1.0.0/
[51]: https://sonarcloud.io/api/project_badges/measure?project=mpenning_ciscoconfparse2&metric=alert_status
[52]: https://sonarcloud.io/summary/new_code?id=mpenning_ciscoconfparse2
[53]: https://sonarcloud.io/api/project_badges/measure?project=mpenning_ciscoconfparse2&metric=sqale_rating
[54]: https://sonarcloud.io/summary/new_code?id=mpenning_ciscoconfparse2
[55]: https://sonarcloud.io/api/project_badges/measure?project=mpenning_ciscoconfparse2&metric=ncloc
[56]: https://sonarcloud.io/summary/new_code?id=mpenning_ciscoconfparse2
[57]: https://sonarcloud.io/api/project_badges/measure?project=mpenning_ciscoconfparse2&metric=code_smells
[58]: https://sonarcloud.io/summary/new_code?id=mpenning_ciscoconfparse2
[59]: https://sonarcloud.io/api/project_badges/measure?project=mpenning_ciscoconfparse2&metric=bugs
[60]: https://sonarcloud.io/summary/new_code?id=mpenning_ciscoconfparse2
[61]: https://sonarcloud.io/api/project_badges/measure?project=mpenning_ciscoconfparse2&metric=sqale_index
[62]: https://sonarcloud.io/summary/new_code?id=mpenning_ciscoconfparse2
[63]: https://docs.pytest.org/en/
[64]: https://github.com/mpenning/ciscoconfparse
[65]: https://pypi.org/project/ciscoconfparse/1.9.41/
[66]: https://raw.githubusercontent.com/mpenning/ciscoconfparse2/main/sphinx-doc/_static/ciscoconfparse_logo_bw_01.png
[67]: http://www.pennington.net/py/ciscoconfparse2/cli.html
[68]: https://img.shields.io/badge/%F0%9F%A5%9A-Hatch-4051b5.svg
[69]: https://github.com/pypa/hatch
Raw data
{
"_id": null,
"home_page": null,
"name": "ciscoconfparse2",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "ASA, Cisco, Cisco IOS, Juniper, NXOS, Parse, audit, modify, query",
"author": null,
"author_email": "Mike Pennington <mike@pennington.net>",
"download_url": "https://files.pythonhosted.org/packages/fa/8f/9225bce5d5353123dcfc34b8dadfc7fe843873c4f5825505c42edc5a4ff4/ciscoconfparse2-0.7.47.tar.gz",
"platform": null,
"description": "[![logo][66]][66]\n\n# ciscoconfparse2\n\n[![git commits][41]][42] [![Version][2]][3] [![Downloads][6]][7] [![License][8]][9] [![Hatch project][68]][69]\n\n[![SonarCloud][51]][52] [![SonarCloud Maintainability Rating][53]][54] [![SonarCloud Lines of Code][55]][56] [![SonarCloud Bugs][59]][60] [![SonarCloud Code Smells][57]][58] [![SonarCloud Tech Debt][61]][62]\n\n## Introduction: What is ciscoconfparse2?\n\n### Summary\n\n[ciscoconfparse2][17] is similar to an advanced grep and diff that\nspecializes in network configuration files (such as those from Cisco,\nJuniper, Palo Alto, etc); it is the next generation of\n[ciscoconfparse][64], which was the primary development package\nfrom 2007 until 2023.\n\n### CLI Tool\n\n[ciscoconfparse2][17] distributes a [CLI tool][67] that will diff and grep various\nnetwork configuration or text files.\n\n### Simple Python API Usage\n\nIn addition to the CLI tool, [ciscoconfparse2][17] also offers a Python API.\n\nThis example code parses a configuration stored in\n`tests/fixtures/configs/sample_02.ios` and select interfaces that are shutdown.\n\nIn this case, the parent is a line containing `interface` and the child is a\nline containing the word `shutdown`.\n\n```python\n# filename: example.py\nfrom ciscoconfparse2 import CiscoConfParse\n\n##############################################################################\n# Find all Cisco IOS interface names that are shutdown\n##############################################################################\n#\n# Search for:\n# !\n# interface Foo\n# description ignore-this-line\n# shutdown\n# !\n\n# Search a configuration in the test fixutres directory\nparse = CiscoConfParse('tests/fixtures/configs/sample_02.ios', syntax='ios')\n\n# Find a parent line containing 'interface' and child line with 'shutdown'\nfor intf_obj in parse.find_parent_objects(['interface', 'shutdown']):\n intf_name = \" \".join(intf_obj.split()[1:])\n print(f\"Shutdown: {intf_name}\")\n```\n\nThat will print:\n\n```none\n$ python example.py\nShutdown: FastEthernet0/7\nShutdown: FastEthernet0/8\nShutdown: FastEthernet0/9\nShutdown: FastEthernet0/11\nShutdown: FastEthernet0/13\nShutdown: FastEthernet0/15\nShutdown: FastEthernet0/17\nShutdown: FastEthernet0/19\nShutdown: FastEthernet0/20\nShutdown: FastEthernet0/22\nShutdown: VLAN1\n```\n\n### Complex Python API Example\n\nThe following code will parse a configuration stored in\n`tests/fixtures/configs/sample_08.ios` and will find the\nIP address / switchport parameters assigned to interfaces.\n\n```python\nfrom ciscoconfparse2 import CiscoConfParse\nfrom ciscoconfparse2 import IPv4Obj\n\ndef intf_csv(intf_obj: str) -> str:\n \"\"\"\n :return: CSV for each interface object.\n :rtype: str\n \"\"\"\n intf_name = \" \".join(intf_obj.split()[1:]) # Use a string split() method from the BaseCfgLine()\n admin_status = intf_obj.re_match_iter_typed(\"^\\s+(shutdown)\", default=\"not_shutdown\", result_type=str)\n # Search children of all interfaces for a regex match and return\n # the value matched in regex match group 1. If there is no match,\n # return a default value: 0.0.0.1/32\n addr_netmask = intf_obj.re_match_iter_typed(\n r\"^\\s+ip\\saddress\\s(\\d+\\.\\d+\\.\\d+\\.\\d+\\s\\S+)\", result_type=IPv4Obj,\n group=1, default=IPv4Obj(\"0.0.0.1/32\"))\n # Find the description and replace all commas in it\n description = intf_obj.re_match_iter_typed(\"description\\s+(\\S.*)\").replace(\",\", \"_\")\n\n switchport_status = intf_obj.re_match_iter_typed(\"(switchport)\", default=\"not_switched\")\n\n # Return a csv based on whether this is a switchport\n if switchport_status == \"not_switched\":\n return f\"{intf_name},{admin_status},{addr_netmask.as_cidr_addr},{switchport_status},,,{description}\"\n\n else:\n # Only calculate switchport values if this is a switchport\n trunk_access = intf_obj.re_match_iter_typed(\"switchport mode (trunk)\", default=\"access\", result_type=str)\n access_vlan = intf_obj.re_match_iter_typed(\"switchport access vlan (\\d+)\", default=1, result_type=int)\n\n return f\"{intf_name},{admin_status},,{switchport_status},{trunk_access},{access_vlan},{description}\"\n\nparse = CiscoConfParse('tests/fixtures/configs/sample_08.ios', syntax='ios')\n\n# Find interface BaseCfgLine() instances...\nfor intf_obj in parse.find_objects('^interface'):\n print(intf_csv(intf_obj))\n```\n\nThat will print:\n\n```none\n$ python example.py\nLoopback0,not_shutdown,172.16.0.1/32,not_switched,,,SEE http://www.cymru.com/Documents/secure-ios-template.html\nNull0,not_shutdown,0.0.0.1/32,not_switched,,,\nATM0/0,not_shutdown,0.0.0.1/32,not_switched,,,\nATM0/0.32 point-to-point,not_shutdown,0.0.0.1/32,not_switched,,,\nFastEthernet0/0,not_shutdown,172.16.2.1/24,not_switched,,,[IPv4 and IPv6 desktop / laptop hosts on 2nd-floor North LAN]\nFastEthernet0/1,not_shutdown,172.16.3.1/30,not_switched,,,[IPv4 and IPv6 OSPF Transit via West side of building]\nFastEthernet1/0,not_shutdown,172.16.4.1/30,not_switched,,,[IPv4 and IPv6 OSPF Transit via North side of building]\nFastEtheret1/1,not_shutdown,,switchport,access,12,[switchport to the comptroller cube]\nFastEtheret1/2,not_shutdown,,switchport,access,12,[switchport to the IDF media converter]\nVirtual-Template1,not_shutdown,0.0.0.1/32,not_switched,,,\nDialer1,not_shutdown,0.0.0.1/32,not_switched,,,[IPv4 and IPv6 OSPF Transit via WAN Dialer: NAT_ CBWFQ interface]\n```\n\n### Cisco IOS Factory Usage\n\nCiscoConfParse has a special feature that abstracts common IOS / NXOS / ASA / IOS XR fields; at this time, it is only useful on IOS configurations. You will see factory parsing in CiscoConfParse code as parsing the configuration with `factory=True`.\n\nFactory parsing is still beta-quality and should be used at your own risk.\n\n## Why\n\n[ciscoconfparse2][17] is a [Python][10] library\nthat helps you quickly answer questions like these about your\nCisco configurations:\n\n- What interfaces are shutdown?\n- Which interfaces are in trunk mode?\n- What address and subnet mask is assigned to each interface?\n- Which interfaces are missing a critical command?\n- Is this configuration missing a standard config line?\n\nIt can help you:\n\n- Audit existing router / switch / firewall / wlc configurations\n- Modify existing configurations\n- Build new configurations\n\nSpeaking generally, the library examines an IOS-style config and breaks\nit into a set of linked parent / child relationships. You can perform\ncomplex queries about these relationships.\n\n[![Cisco IOS config: Parent / child][11]][11]\n\n### What changed in ciscoconfparse2?\n\nIn late 2023, I started a rewrite because [ciscoconfparse][64] is too large \nand has some defaults that I wish it didn't have. I froze\n[ciscoconfparse][64] PYPI releases at [version 1.9.41][65]; there will be no\nmore [ciscoconfparse][64] PYPI releases.\n\nWhat do you do? Upgrade to [ciscoconfparse2][17]!\n\nHere's why, it:\n\n- Includes a handy [CLI command][67] (including greps for mac addresses and IPv4 / IPv6 subnets)\n- Streamlines the API towards a simpler user interface.\n- Removes legacy and flawed methods from the original (this could be a breaking change for old scripts).\n- Adds string methods to `BaseCfgLine()` objects\n- Defaults `ignore_blank_lines=False` (this could be a breaking change for old scripts).\n- Is better at handling multiple-child-level configurations (such as IOS XR and JunOS)\n- Can search for parents and children using an *arbitrary list of ancestors*\n- Adds the concept of change commits; this is a config-modification safety feature that [ciscoconfparse][64] lacks\n- Adds an `auto_commit` keyword, which defaults True\n- Documents much more of the API\n- Intentionally requires a different import statement to minimize confusion between the original and [ciscoconfparse2][17]\n- Vasly improves Cisco IOS diffs\n\n## What if we don\\'t use Cisco IOS?\n\nIn many cases, you can parse [brace-delimited configurations][13] into a Cisco IOS style (see [original ciscoconfparse Github Issue \\#17][14]), which means that CiscoConfParse may be able to parse these configurations:\n\n- Juniper Networks Junos OS\n- Palo Alto Networks Firewall configurations\n- F5 Networks configurations (known caveats)\n\nCiscoConfParse also handles anything that has a Cisco IOS style of configuration, which includes:\n\n- Cisco IOS, Cisco Nexus, Cisco IOS-XR, Cisco IOS-XE, Aironet OS, Cisco ASA, Cisco CatOS\n- Arista EOS\n- Brocade\n- HP Switches\n- Force 10 Switches\n- Dell PowerConnect Switches\n- Extreme Networks\n- Enterasys\n- Screenos\n\n## Docs\n\n- The latest copy of the docs are [archived on the web][15]\n\n## Installation and Downloads\n\n- Use `pip` for Python3.x\\... :\n\n python -m pip install ciscoconfparse2\n\n## What is the pythonic way of handling script credentials?\n\n1. Never hard-code credentials\n2. Use [python-dotenv](https://github.com/theskumar/python-dotenv)\n\n\n## Is this a tool, or is it artwork?\n\nThat depends on who you ask. Many companies use CiscoConfParse as part of their\nnetwork engineering toolbox; others regard it as a form of artwork.\n\n## Pre-requisites\n\n[The ciscoconfparse2 python package][3] requires Python versions 3.7+.\n\nType-hinting (work-in-progress) targets Python3.9+ due to the need for `tuple[str, ...]` hints.\n\n## Other Resources\n\n- [Dive into Python3](http://www.diveintopython3.net/) is a good way to learn Python\n- [Team CYMRU][30] has a [Secure IOS Template][29], which is especially useful for external-facing routers / switches\n- [Cisco\\'s Guide to hardening IOS devices][31]\n- [Center for Internet Security Benchmarks][32] (An email address, cookies, and javascript are required)\n\n## Are you releasing licensing besides GPLv3?\n\nI will not. however, if it's truly a problem for your company, there are commercial solutions available (to include purchasing the project, or hiring me).\n\n## Bug Tracker and Support\n\n- Please report any suggestions, bug reports, or annoyances with a [github bug report][24].\n- If you\\'re having problems with general python issues, consider searching for a solution on [Stack Overflow][33]. If you can\\'t find a solution for your problem or need more help, you can [ask on Stack Overflow][34] or [reddit/r/Python][39].\n- If you\\'re having problems with your Cisco devices, you can contact:\n - [Cisco TAC][28]\n - [reddit/r/Cisco][35]\n - [reddit/r/networking][36]\n - [NetworkEngineering.se][23]\n\n## Dependencies\n\n- [Python 3](https://python.org/)\n- [attrs](https://github.com/python-attrs/attrs)\n- [passlib](https://github.com/glic3rinu/passlib)\n- [tomlkit](https://github.com/sdispater/tomlkit)\n- [dnspython](https://github.com/rthalley/dnspython)\n- [`hier_config`](https://github.com/netdevops/hier_config)\n- [`PyYAML`](https://github.com/yaml/pyyaml)\n- [`pyparsing`](https://github.com/pyparsing/pyparsing)\n- [typeguard](https://github.com/agronholm/typeguard)\n- [loguru](https://github.com/Delgan/loguru)\n\n\n## Build and Development\n\nI recommend that you use [`hatch`][69] to build and manage the package versions.\n\nTypical development workflow looks like this:\n\n- git clone this repo\n- make changes\n- git commit your code changes\n- `hatch run pytest`\n- Edit `CHANGES.md` with your changes\n- Bump the `ciscoconfparse2` version number in `ciscoconfparse2/__about__.py` with `hatch version micro` or `hatch version minor`\n- Publish to github with `make cicd`\n- `cd sphinx-doc` and `make html`\n- publish documentation changes\n\n## Unit-Tests and SonarCloud\n\n- We are manually disabling some [SonarCloud](https://sonarcloud.io/) alerts with:\n - `#pragma warning disable S1313`\n - `#pragma warning restore S1313`\n - Where `S1313` is a False-positive that [SonarCloud](https://sonarcloud.io) flags\n - Those `#pragma warning` lines should be carefully-fenced to ensure that we don't disable a [SonarCloud](https://sonarcloud.io/) alert that is useful.\n\n### Semantic Versioning and Conventional Commits\n\n- At this point, [ciscoconfparse2][3] does NOT adhere to [Semantic Versioning][49]\n- Although we added [commitizen][48] as a dev dependency, we are NOT enforcing commit rules (such as [Conventional Commits][50]) yet.\n\n### Execute Unit tests\n\nThe project\\'s [test workflow][1] checks ciscoconfparse2 on Python versions 3.7 and higher, as well as a [pypy JIT][22] executable.\n\nIf you already git cloned the repo and want to manually run tests either run with `make test` from the base directory, or manually run with [`pytest`][63] in a unix-like system...\n\n```shell\n$ cd tests\n$ pytest ./test*py\n...\n```\n\n### Execute Test Coverage Line-Miss Report\n\nIf you already have have `pytest` and `pytest-cov` installed, run a test line miss report as shown below.\n\n```shell\n$ # Install the latest ciscoconfparse2\n$ # (assuming the latest code is on pypi)\n$ pip install -U ciscoconfparse2\n$ pip install -U pytest-cov\n$ cd tests\n$ pytest --cov-report=term-missing --cov=ciscoconfparse2 ./\n...\n```\n\n\n### Editing the Package\n\nThis uses the example of editing the package on a git branch called `develop`...\n\n- `git clone https://github.com/mpenning/ciscoconfparse2`\n- `cd ciscoconfparse2`\n- `git branch develop`\n- `git checkout develop`\n- Add / modify / delete on the `develop` branch\n- `make test`\n- If tests run clean, `git commit` all the pending changes on the `develop` branch\n- If you plan to publish this as an official version rev, edit the version number in [pyproject.toml][12]. In the future, we want to integrate `commitizen` to manage versioning.\n- `git checkout main`\n- `git merge develop`\n- `make test`\n- `git push origin main`\n- `make pypi`\n\n### Sphinx Documentation\n\nBuilding the ciscoconfparse2 documentation tarball comes down to this one wierd trick:\n\n- `cd sphinx-doc/`\n- `pip install ciscoconfparse`\n- `make html`\n\n## License and Copyright\n\n[ciscoconfparse2][3] is licensed [GPLv3][21]\n\n- Copyright (C) 2023-2024 David Michael Pennington\n\nThe word \\\"Cisco\\\" is a registered trademark of [Cisco Systems][27].\n\n## Author\n\n[ciscoconfparse2][3] was written by [David Michael Pennington][25].\n\n\n\n [1]: https://github.com/mpenning/ciscoconfparse2/blob/main/.github/workflows/tests.yml\n [2]: https://img.shields.io/pypi/v/ciscoconfparse2.svg\n [3]: https://pypi.python.org/pypi/ciscoconfparse2/\n [4]: https://github.com/mpenning/ciscoconfparse2/actions/workflows/tests.yml/badge.svg\n [5]: https://github.com/mpenning/ciscoconfparse2/actions/workflows/tests.yml\n [6]: https://pepy.tech/badge/ciscoconfparse2\n [7]: https://pepy.tech/project/ciscoconfparse2\n [8]: http://img.shields.io/badge/license-GPLv3-blue.svg\n [9]: https://www.gnu.org/copyleft/gpl.html\n [10]: https://www.python.org\n [11]: https://raw.githubusercontent.com/mpenning/ciscoconfparse/master/sphinx-doc/_static/ciscoconfparse_overview_75pct.png\n [12]: https://github.com/mpenning/ciscoconfparse2/blob/main/pyproject.toml\n [13]: https://github.com/mpenning/ciscoconfparse2/blob/master/configs/sample_01.junos\n [14]: https://github.com/mpenning/ciscoconfparse/issues/17\n [15]: http://www.pennington.net/py/ciscoconfparse2/\n [16]: http://pennington.net/tutorial/ciscoconfparse2/ccp_tutorial.html\n [17]: https://github.com/mpenning/ciscoconfparse2\n [18]: https://github.com/mpenning/ciscoconfparse/issues/117\n [19]: https://github.com/mpenning/ciscoconfparse/issues/13\n [20]: https://github.com/CrackerJackMack/\n [21]: http://www.gnu.org/licenses/gpl-3.0.html\n [22]: https://pypy.org\n [23]: https://networkengineering.stackexchange.com/\n [24]: https://github.com/mpenning/ciscoconfparse2/issues/new/choose\n [25]: https://github.com/mpenning\n [26]: https://github.com/muir\n [27]: https://www.cisco.com/\n [28]: https://www.cisco.com/go/support\n [29]: https://www.cymru.com/Documents/secure-ios-template.html\n [30]: https://team-cymru.com/company/\n [31]: http://www.cisco.com/c/en/us/support/docs/ip/access-lists/13608-21.html\n [32]: https://learn.cisecurity.org/benchmarks\n [33]: https://stackoverflow.com\n [34]: http://stackoverflow.com/questions/ask\n [35]: https://www.reddit.com/r/Cisco/\n [36]: https://www.reddit.com/r/networking\n [37]: https://snyk.io/advisor/python/ciscoconfparse2/badge.svg\n [38]: https://snyk.io/advisor/python/ciscoconfparse2\n [39]: https://www.reddit.com/r/Python/\n [41]: https://img.shields.io/github/commit-activity/m/mpenning/ciscoconfparse2\n [42]: https://img.shields.io/github/commit-activity/m/mpenning/ciscoconfparse2\n [43]: https://www.codefactor.io/Content/badges/B.svg\n [44]: https://www.codefactor.io/repository/github/mpenning/ciscoconfparse2/\n [45]: https://fossa.com/blog/open-source-software-licenses-101-gpl-v3/\n [46]: https://app.codacy.com/project/badge/Grade/4774ebb0292d4e1d9dc30bf263d9df14\n [47]: https://app.codacy.com/gh/mpenning/ciscoconfparse2/dashboard\n [48]: https://commitizen-tools.github.io/commitizen/\n [49]: https://semver.org/\n [50]: https://www.conventionalcommits.org/en/v1.0.0/\n [51]: https://sonarcloud.io/api/project_badges/measure?project=mpenning_ciscoconfparse2&metric=alert_status\n [52]: https://sonarcloud.io/summary/new_code?id=mpenning_ciscoconfparse2\n [53]: https://sonarcloud.io/api/project_badges/measure?project=mpenning_ciscoconfparse2&metric=sqale_rating\n [54]: https://sonarcloud.io/summary/new_code?id=mpenning_ciscoconfparse2\n [55]: https://sonarcloud.io/api/project_badges/measure?project=mpenning_ciscoconfparse2&metric=ncloc\n [56]: https://sonarcloud.io/summary/new_code?id=mpenning_ciscoconfparse2\n [57]: https://sonarcloud.io/api/project_badges/measure?project=mpenning_ciscoconfparse2&metric=code_smells\n [58]: https://sonarcloud.io/summary/new_code?id=mpenning_ciscoconfparse2\n [59]: https://sonarcloud.io/api/project_badges/measure?project=mpenning_ciscoconfparse2&metric=bugs\n [60]: https://sonarcloud.io/summary/new_code?id=mpenning_ciscoconfparse2\n [61]: https://sonarcloud.io/api/project_badges/measure?project=mpenning_ciscoconfparse2&metric=sqale_index\n [62]: https://sonarcloud.io/summary/new_code?id=mpenning_ciscoconfparse2\n [63]: https://docs.pytest.org/en/\n [64]: https://github.com/mpenning/ciscoconfparse\n [65]: https://pypi.org/project/ciscoconfparse/1.9.41/\n [66]: https://raw.githubusercontent.com/mpenning/ciscoconfparse2/main/sphinx-doc/_static/ciscoconfparse_logo_bw_01.png\n [67]: http://www.pennington.net/py/ciscoconfparse2/cli.html\n [68]: https://img.shields.io/badge/%F0%9F%A5%9A-Hatch-4051b5.svg\n [69]: https://github.com/pypa/hatch\n",
"bugtrack_url": null,
"license": null,
"summary": "Parse, Audit, Query, Build, and Modify Cisco IOS-style and JunOS-style configs",
"version": "0.7.47",
"project_urls": {
"changelog": "https://github.com/mpenning/ciscoconfparse2/blob/main/CHANGES.md",
"documentation": "http://www.pennington.net/py/ciscoconfparse2/",
"homepage": "http://github.com/mpenning/ciscoconfparse2",
"repository": "https://github.com/mpenning/ciscoconfparse2"
},
"split_keywords": [
"asa",
" cisco",
" cisco ios",
" juniper",
" nxos",
" parse",
" audit",
" modify",
" query"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "5cf9b49f50f49ad7add461bfcf580c81548fac6af38a9eea4a3620cb2658088e",
"md5": "d3caa42aeb037ef61ce6c90d0f7f55e3",
"sha256": "1908d21488620440ad3a0e00155c5f2d63a71e2716be8adbd9d89ceb7df3745c"
},
"downloads": -1,
"filename": "ciscoconfparse2-0.7.47-py3-none-any.whl",
"has_sig": false,
"md5_digest": "d3caa42aeb037ef61ce6c90d0f7f55e3",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 423276,
"upload_time": "2024-04-27T16:44:16",
"upload_time_iso_8601": "2024-04-27T16:44:16.354783Z",
"url": "https://files.pythonhosted.org/packages/5c/f9/b49f50f49ad7add461bfcf580c81548fac6af38a9eea4a3620cb2658088e/ciscoconfparse2-0.7.47-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "fa8f9225bce5d5353123dcfc34b8dadfc7fe843873c4f5825505c42edc5a4ff4",
"md5": "f1b30a40020ef1a932b021c9b80cd267",
"sha256": "69d9cf87b4a60d99561be8f34602e1937e08e355be16892d32b05fced7e62d11"
},
"downloads": -1,
"filename": "ciscoconfparse2-0.7.47.tar.gz",
"has_sig": false,
"md5_digest": "f1b30a40020ef1a932b021c9b80cd267",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 1342590,
"upload_time": "2024-04-27T16:44:18",
"upload_time_iso_8601": "2024-04-27T16:44:18.408627Z",
"url": "https://files.pythonhosted.org/packages/fa/8f/9225bce5d5353123dcfc34b8dadfc7fe843873c4f5825505c42edc5a4ff4/ciscoconfparse2-0.7.47.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-04-27 16:44:18",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "mpenning",
"github_project": "ciscoconfparse2",
"travis_ci": false,
"coveralls": true,
"github_actions": true,
"tox": true,
"lcname": "ciscoconfparse2"
}