Skip to content

Commit

Permalink
Merge pull request #1 from Tes3awy/change-ciscoconfparse
Browse files Browse the repository at this point in the history
Change to ciscoconfparse2
  • Loading branch information
Tes3awy authored Jul 12, 2024
2 parents 3b56257 + 7f6e75e commit 221f44d
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 39 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# Changelog

> NOTE: ciscoconfaudit follows the ([semver](https://semver.org/)) Semantic Versioning 2.0.0 specification meaning it has three numerical version parts with distinct rules `MAJOR.MINOR.PATCH`
> **NOTE:** ciscoconfaudit follows the ([semver](https://semver.org/)) Semantic Versioning 2.0.0 specification meaning it has three numerical version parts with distinct rules `MAJOR.MINOR.PATCH`
## 0.2.1

- Change ciscoconfaudit to use [ciscoconfparse2](https://github.com/mpenning/ciscoconfparse2) instead of [ciscoconfparse](https://github.com/mpenning/ciscoconfparse)
- Update README.md

## 0.2.0

Expand Down
13 changes: 6 additions & 7 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[project]
name = "ciscoconfaudit"
version = "0.2.0"
description = "A Cisco IOS & IOS-XE configuration audit tool"
version = "0.2.1"
description = "A Cisco IOS, IOS-XE, & NX-OS configuration audit tool"
readme = { file = "README.md", content-type = "text/markdown" }
requires-python = ">=3.8, <4"
requires-python = ">=3.9, <4"
license = { file = "LICENSE" }
keywords = ["cisco", "audit", "configuration audit"]
authors = [{ name = "Osama Abbas", email = "[email protected]" }]
Expand All @@ -21,17 +21,16 @@ classifiers = [
"Natural Language :: English",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Typing :: Typed",
]
dependencies = ["ciscoconfparse", "rich"]
dependencies = ["ciscoconfparse2", "rich"]

[project.optional-dependencies]
dev = ["pre-commit", "bumpver", "black", "isort"]
dev = ["pre-commit", "bumpver", "black", "isort", "python-dotenv"]

[project.urls]
Homepage = "https://github.com/Tes3awy/cisco-config-auditor/"
Expand All @@ -49,7 +48,7 @@ build-backend = "setuptools.build_meta"
profile = "black"

[tool.bumpver]
current_version = "0.2.0"
current_version = "0.2.1"
version_pattern = "MAJOR.MINOR.PATCH"
commit_message = "Bump version {old_version} -> {new_version}"
commit = true
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
rich==13.7.1
ciscoconfparse==1.9.41
ciscoconfparse2==0.7.74
60 changes: 30 additions & 30 deletions src/ciscoconfaudit/__init__.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# -*- coding: utf-8 -*-
from ciscoconfparse import CiscoConfParse
from ciscoconfparse2 import CiscoConfParse
from rich.console import Console
from rich.table import Table

__version__ = "0.2.0"
__version__ = "0.2.1"
__all__ = ["ciscoconfaudit"]
PY_MAJ_VER = 3
PY_MIN_VER = 8
MIN_PYTHON_VER = "3.8"
PY_MIN_VER = 9
MIN_PYTHON_VER = "3.9"

FAIL = "[bold red]:heavy_multiplication_x: FAIL[/bold red]"
PASS = "[bold green]:heavy_check_mark: PASS[/bold green]"
Expand Down Expand Up @@ -43,27 +43,27 @@ def create_table(self, title: str) -> Table:

# Configuration Checks
def check_service(self, pattern: str, cmd: str):
if self.parse.find_lines(pattern):
if self.parse.find_objects(pattern):
self.global_table.add_row(cmd, FAIL)
else:
self.global_table.add_row(cmd, PASS)

def check_config(self, pattern: str, cmd: str):
if self.parse.find_lines(pattern):
if self.parse.find_objects(pattern):
self.global_table.add_row(cmd, PASS)
else:
self.global_table.add_row(cmd, FAIL)

def check_vuln_config(self, pattern: str, cmd: str):
if not self.parse.find_lines(pattern):
if not self.parse.find_objects(pattern):
self.global_table.add_row(cmd, NOT_IN_USE)
elif self.parse.find_lines(pattern):
elif self.parse.find_objects(pattern):
self.global_table.add_row(cmd, WARN)
else:
self.global_table.add_row(cmd, PASS)

def check_optional_config(self, pattern: str, cmd: str):
if self.parse.find_lines(pattern):
if self.parse.find_objects(pattern):
self.global_table.add_row(cmd, PASS)
else:
self.global_table.add_row(cmd, RECOMMENDED)
Expand All @@ -72,7 +72,7 @@ def check_optional_config(self, pattern: str, cmd: str):
def global_config(self, running_config: str):
# Parse configuration
self.parse = CiscoConfParse(
running_config.splitlines(), syntax="ios", factory=True, read_only=True
running_config.splitlines(), syntax="ios", factory=True
)
hostname = self.parse.re_match_iter_typed(
r"^hostname\s+(\S+)", default="Device"
Expand Down Expand Up @@ -103,7 +103,7 @@ def global_config(self, running_config: str):
self.check_service(r"^no\sservice\sconfig$", "no service config")
self.check_config(
r"^no\sservice\spassword-recovery$",
"no service password-recovery (Use with caution)",
"no service password-recovery ([yellow]Use with caution[/yellow])",
)
self.check_service(r"^service\scall-home$", "no service call-home")
self.check_service(
Expand Down Expand Up @@ -219,7 +219,7 @@ def global_config(self, running_config: str):
"enable algorithm-type scrypt secret <password>",
)
# Check for AAA settings
if self.parse.find_lines(r"^no\saaa\snew-model$"):
if self.parse.find_objects(r"^no\saaa\snew-model$"):
self.global_table.add_row("aaa new-model", FAIL)
else:
self.global_table.add_row("aaa new-model", PASS)
Expand Down Expand Up @@ -317,7 +317,7 @@ def check_vlan1(self, parse: CiscoConfParse):

def check_mop(self, parse: CiscoConfParse):
mop_intfs_total, mop_intfs_success = 0, 0
cdp_intfs = parse.find_objects_w_child(
cdp_intfs = parse.find_child_objects(
parentspec=r"^interface\s", childspec=IS_ACCESS_PORT
)
for cdp_obj in cdp_intfs:
Expand All @@ -338,7 +338,7 @@ def check_mop(self, parse: CiscoConfParse):

def check_port_security(self, parse: CiscoConfParse):
ps_intfs_total, ps_intfs_pass = 0, 0
ps_intfs = parse.find_objects_w_child(
ps_intfs = parse.find_child_objects(
parentspec=r"^interface\s", childspec=IS_ACCESS_PORT
)
for ps_obj in ps_intfs:
Expand Down Expand Up @@ -370,7 +370,7 @@ def check_port_security(self, parse: CiscoConfParse):
def check_stp_portfast(self, parse: CiscoConfParse):
if not bool(parse.find_objects(r"^spanning-tree\sportfast\sdefault$")):
stp_intfs_total, stp_intfs_pass = 0, 0
stp_intfs = parse.find_objects_w_child(
stp_intfs = parse.find_child_objects(
parentspec=r"^interface\s", childspec=IS_ACCESS_PORT
)
for stp_obj in stp_intfs:
Expand Down Expand Up @@ -403,7 +403,7 @@ def check_stp_bpdu(self, parse: CiscoConfParse):
parse.find_objects(r"^spanning-tree\sportfast\sbpduguard\sdefault$")
):
bpdu_intfs_total, bpdu_intfs_pass = 0, 0
bpdu_intfs = parse.find_objects_w_child(
bpdu_intfs = parse.find_child_objects(
parentspec=r"^interf", childspec=IS_ACCESS_PORT
)
for bpdu_obj in bpdu_intfs:
Expand Down Expand Up @@ -433,7 +433,7 @@ def check_stp_bpdu(self, parse: CiscoConfParse):

def check_stp_root(self, parse: CiscoConfParse):
root_intfs_total, root_intfs_pass = 0, 0
root_intfs = parse.find_objects_w_child(
root_intfs = parse.find_child_objects(
parentspec=r"^interface\s", childspec=IS_ACCESS_PORT
)
for root_obj in root_intfs:
Expand All @@ -459,7 +459,7 @@ def check_stp_root(self, parse: CiscoConfParse):
def check_cdp(self, parse: CiscoConfParse):
if not bool(parse.find_objects(r"^no\scdp\srun$")):
cdp_intfs_total, cdp_intfs_pass = 0, 0
cdp_intfs = parse.find_objects_w_child(
cdp_intfs = parse.find_child_objects(
parentspec=r"^interface\s", childspec=IS_ACCESS_PORT
)
for cdp_obj in cdp_intfs:
Expand All @@ -483,7 +483,7 @@ def check_cdp(self, parse: CiscoConfParse):
def check_lldp(self, parse: CiscoConfParse):
if not bool(parse.find_objects(r"^no\slldp\srun$")):
lldp_intfs_total, lldp_intfs_pass = 0, 0
lldp_intfs = parse.find_objects_w_child(
lldp_intfs = parse.find_child_objects(
parentspec=r"^interface\s", childspec=IS_ACCESS_PORT
)
for lldp_obj in lldp_intfs:
Expand Down Expand Up @@ -512,7 +512,7 @@ def check_lldp(self, parse: CiscoConfParse):

def check_ip_src_verify(self, parse: CiscoConfParse):
src_verify_total, src_verify_pass = 0, 0
src_verify_intfs = parse.find_objects_w_child(
src_verify_intfs = parse.find_child_objects(
parentspec=r"^interface\s", childspec=IS_ACCESS_PORT
)
for src_verify_obj in src_verify_intfs:
Expand All @@ -535,7 +535,7 @@ def check_ip_src_verify(self, parse: CiscoConfParse):

def check_sticky_mac(self, parse: CiscoConfParse):
mac_sticky_total, mac_stick_pass = 0, 0
mac_sticky_intfs = parse.find_objects_w_child(
mac_sticky_intfs = parse.find_child_objects(
parentspec=r"^interface\s", childspec=IS_ACCESS_PORT
)
for mac_sticky_obj in mac_sticky_intfs:
Expand Down Expand Up @@ -567,7 +567,7 @@ def check_sticky_mac(self, parse: CiscoConfParse):
def check_arp_proxy(self, parse: CiscoConfParse):
if not bool(parse.find_objects(r"^ip\sarp\sproxy\sdisable$")):
arp_intfs_total, arp_intfs_pass = 0, 0
arp_intfs = parse.find_objects_w_child(
arp_intfs = parse.find_child_objects(
parentspec=r"^interface\s", childspec=r"^\sip\saddress\s"
)
for arp_obj in arp_intfs:
Expand All @@ -594,15 +594,15 @@ def check_arp_proxy(self, parse: CiscoConfParse):

def check_ip_redirects(self, parse: CiscoConfParse):
redirect_intfs_total, redirect_intfs_pass = 0, 0
redirect_intfs = parse.find_objects_w_child(
redirect_intfs = parse.find_child_objects(
parentspec=r"^interface\s", childspec=r"^\sip\saddress\s"
)
for redirect_obj in redirect_intfs:
if not redirect_obj.has_child_with(
r"^\sno\sip\sredirects$"
) and not redirect_obj.has_child_with(r"^\sshutdown$"):
self.interface_table.add_row(
f"'{redirect_obj.text}' no ip redirects", FAIL
f"'{redirect_obj.parent}' no ip redirects", FAIL
)
else:
redirect_intfs_pass += 1
Expand All @@ -615,15 +615,15 @@ def check_ip_redirects(self, parse: CiscoConfParse):

def check_route_cache(self, parse: CiscoConfParse):
rcache_intfs_total, rcache_intfs_pass = 0, 0
rcache_intfs = parse.find_objects_w_child(
rcache_intfs = parse.find_child_objects(
parentspec=r"^interface\s", childspec=r"^\sip\saddress\s"
)
for rcache_obj in rcache_intfs:
if not rcache_obj.has_child_with(
r"^\sno\sip\sroute-cache$"
) and not rcache_obj.has_child_with(r"^\sshutdown$"):
self.interface_table.add_row(
f"'{rcache_obj.text}' no ip route-cache", FAIL
f"'{rcache_obj.parent}' no ip route-cache", FAIL
)
else:
rcache_intfs_pass += 1
Expand All @@ -636,15 +636,15 @@ def check_route_cache(self, parse: CiscoConfParse):

def check_directed_broadcast(self, parse: CiscoConfParse):
redirect_intfs_total, redirect_intfs_pass = 0, 0
redirect_intfs = parse.find_objects_w_child(
redirect_intfs = parse.find_child_objects(
parentspec=r"^interface\s", childspec=r"^\sip\saddress\s"
)
for redirect_obj in redirect_intfs:
if not redirect_obj.re_search_children(
r"^\sno\sip\sdirected-broadcast$"
) and not redirect_obj.re_search_children(r"^\sshutdown$"):
self.interface_table.add_row(
f"'{redirect_obj.text}' no ip directed-broadcast", FAIL
f"'{redirect_obj.parent}' no ip directed-broadcast", FAIL
)
else:
redirect_intfs_pass += 1
Expand All @@ -661,15 +661,15 @@ def check_directed_broadcast(self, parse: CiscoConfParse):

def check_ip_unreachables(self, parse: CiscoConfParse):
unreachable_intfs_total, unreachable_intfs_pass = 0, 0
unreachable_intfs = parse.find_objects_w_child(
unreachable_intfs = parse.find_child_objects(
parentspec=r"^interface\s", childspec=r"^\sip\saddress\s"
)
for unreachable_obj in unreachable_intfs:
if unreachable_obj.re_search_children(
r"^\sip\sunreachables$"
) and not unreachable_obj.re_search_children(r"^\sshutdown$"):
self.interface_table.add_row(
f"'{unreachable_obj.text}' no ip unreachables", FAIL
f"'{unreachable_obj.parent}' no ip unreachables", FAIL
)
else:
unreachable_intfs_pass += 1
Expand Down

0 comments on commit 221f44d

Please sign in to comment.