diff --git a/pyproject.toml b/pyproject.toml index 86eb712..42eaa94 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -69,3 +69,7 @@ ctl = ">=1" [build-system] requires = ["poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api" + +[tool.ruff.lint] +# Enable the isort rules. +extend-select = ["I"] diff --git a/src/netom/__init__.py b/src/netom/__init__.py index a564f70..5cec982 100644 --- a/src/netom/__init__.py +++ b/src/netom/__init__.py @@ -1,8 +1,6 @@ import io -import ipaddress import os -import confu import tmpl from confu import schema from pkg_resources import get_distribution @@ -63,7 +61,9 @@ class Render: Renders data to defined type. """ - def __init__(self, model_version, model_type, search_path=None, engine="jinja2", filters=None): + def __init__( + self, model_version, model_type, search_path=None, engine="jinja2", filters=None + ): """ Create a render object. @@ -98,7 +98,7 @@ def set_search_path(self, search_path): else: self.engine = tmpl.get_engine(self._engine_type)(search_path=search_path) self.engine.engine.filters.update(self.filters) - self.engine.engine.add_extension('jinja2.ext.loopcontrols') + self.engine.engine.add_extension("jinja2.ext.loopcontrols") def _render(self, filename, data, fobj): # engine.engine.undefined = IgnoreUndefined @@ -133,13 +133,12 @@ def bgp_neighbors(self, data, fobj, validate=True): class TemplarRender(Render): - def __init__(self, *args, **kwargs): kwargs["engine"] = "templar" super().__init__(*args, **kwargs) def render_string(self, filename, data): - with open(os.path.join(self._search_path, filename), 'r') as file: + with open(os.path.join(self._search_path, filename)) as file: template_string = file.read() return self.render_from_string(template_string, data) @@ -147,7 +146,6 @@ def render_from_string(self, instr, data): return self.engine._render_str_to_str(instr, data) - def validate(model, data, strict=True): schema.apply_defaults(model, data) success, errors, warnings = schema.validate(model, data, log=print) diff --git a/src/netom/filters.py b/src/netom/filters.py index 4a8e406..b922479 100644 --- a/src/netom/filters.py +++ b/src/netom/filters.py @@ -1,10 +1,10 @@ import ipaddress import re from ipaddress import IPv4Address -from jinja2 import pass_context +from jinja2 import pass_context -r_ip_nn = re.compile("[\d.]{7,15}/\d{1,2}") +r_ip_nn = re.compile(r"[\d.]{7,15}/\d{1,2}") __all__ = [ "address_to_mask", @@ -115,7 +115,7 @@ def address_to_wildcard(addr): https://medium.com/opsops/wildcard-masks-operations-in-python-16acf1c35683 """ ipnet4 = ipaddress.ip_network(addr) - wildcard = str(IPv4Address(int(IPv4Address(ipnet4.netmask))^(2**32-1))) + wildcard = str(IPv4Address(int(IPv4Address(ipnet4.netmask)) ^ (2**32 - 1))) return f"{ipnet4.network_address} {wildcard}" @@ -125,7 +125,9 @@ def line_to_mask(line): E.g. `permit ip 10.0.0.0/8` any -> `permit ip 10.0.0.0 255.0.0.0 any` """ tokens = line.split() - return " ".join([address_to_mask(token) if r_ip_nn.match(token) else token for token in tokens]) + return " ".join( + [address_to_mask(token) if r_ip_nn.match(token) else token for token in tokens] + ) def line_to_wildcard(line): @@ -134,7 +136,13 @@ def line_to_wildcard(line): E.g. `permit ip 10.0.0.0/8` any -> `permit ip 10.0.0.0 0.255.255.255 any` """ tokens = line.split() - return " ".join([address_to_wildcard(token) if r_ip_nn.match(token) else token for token in tokens]) + return " ".join( + [ + address_to_wildcard(token) if r_ip_nn.match(token) else token + for token in tokens + ] + ) + def ip_to_ipv4(line): """ @@ -142,4 +150,3 @@ def ip_to_ipv4(line): """ tokens = line.split() return " ".join(["ipv4" if token == "ip" else token for token in tokens]) - diff --git a/tests/conftest.py b/tests/conftest.py index c14563c..4d95a61 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -7,6 +7,7 @@ def this_dir(): return os.path.dirname(__file__) + @pytest.fixture def data_dir(this_dir): return os.path.join(this_dir, "data") diff --git a/tests/test_bgp_neighbor.py b/tests/test_bgp_neighbor.py index 45c66f1..ccb02f0 100644 --- a/tests/test_bgp_neighbor.py +++ b/tests/test_bgp_neighbor.py @@ -1,6 +1,5 @@ -import pytest - import netom +import pytest from netom import exception from netom.models import BgpNeighbor diff --git a/tests/test_filters.py b/tests/test_filters.py index 9bb820f..a43f5ef 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -1,5 +1,9 @@ - -from netom.filters import address_to_mask, address_to_wildcard, line_to_mask, line_to_wildcard +from netom.filters import ( + address_to_mask, + address_to_wildcard, + line_to_mask, + line_to_wildcard, +) def test_address_to_mask(): @@ -13,6 +17,7 @@ def test_address_to_mask(): assert address_to_mask("192.168.0.1/31") == "192.168.0.1 255.255.255.254" assert address_to_mask("192.168.0.1/32") == "192.168.0.1 255.255.255.255" + def test_address_to_wildcard(): assert address_to_wildcard("192.0.0.0/4") == "192.0.0.0 15.255.255.255" assert address_to_wildcard("192.0.0.0/8") == "192.0.0.0 0.255.255.255" @@ -24,24 +29,80 @@ def test_address_to_wildcard(): assert address_to_wildcard("192.168.0.0/31") == "192.168.0.0 0.0.0.1" assert address_to_wildcard("192.168.0.0/32") == "192.168.0.0 0.0.0.0" + def test_line_to_mask(): - assert line_to_mask("ip route 192.168.0.0/4 198.51.100.1") == "ip route 192.168.0.0 240.0.0.0 198.51.100.1" - assert line_to_mask("ip route 192.168.0.0/8 198.51.100.1") == "ip route 192.168.0.0 255.0.0.0 198.51.100.1" - assert line_to_mask("ip route 192.168.0.0/9 198.51.100.1") == "ip route 192.168.0.0 255.128.0.0 198.51.100.1" - assert line_to_mask("ip route 192.168.0.0/16 198.51.100.1") == "ip route 192.168.0.0 255.255.0.0 198.51.100.1" - assert line_to_mask("ip route 192.168.0.0/24 198.51.100.1") == "ip route 192.168.0.0 255.255.255.0 198.51.100.1" - assert line_to_mask("ip route 192.168.0.0/25 198.51.100.1") == "ip route 192.168.0.0 255.255.255.128 198.51.100.1" - assert line_to_mask("ip route 192.168.0.0/30 198.51.100.1") == "ip route 192.168.0.0 255.255.255.252 198.51.100.1" - assert line_to_mask("ip route 192.168.0.0/31 198.51.100.1") == "ip route 192.168.0.0 255.255.255.254 198.51.100.1" - assert line_to_mask("ip route 192.168.0.0/32 198.51.100.1") == "ip route 192.168.0.0 255.255.255.255 198.51.100.1" + assert ( + line_to_mask("ip route 192.168.0.0/4 198.51.100.1") + == "ip route 192.168.0.0 240.0.0.0 198.51.100.1" + ) + assert ( + line_to_mask("ip route 192.168.0.0/8 198.51.100.1") + == "ip route 192.168.0.0 255.0.0.0 198.51.100.1" + ) + assert ( + line_to_mask("ip route 192.168.0.0/9 198.51.100.1") + == "ip route 192.168.0.0 255.128.0.0 198.51.100.1" + ) + assert ( + line_to_mask("ip route 192.168.0.0/16 198.51.100.1") + == "ip route 192.168.0.0 255.255.0.0 198.51.100.1" + ) + assert ( + line_to_mask("ip route 192.168.0.0/24 198.51.100.1") + == "ip route 192.168.0.0 255.255.255.0 198.51.100.1" + ) + assert ( + line_to_mask("ip route 192.168.0.0/25 198.51.100.1") + == "ip route 192.168.0.0 255.255.255.128 198.51.100.1" + ) + assert ( + line_to_mask("ip route 192.168.0.0/30 198.51.100.1") + == "ip route 192.168.0.0 255.255.255.252 198.51.100.1" + ) + assert ( + line_to_mask("ip route 192.168.0.0/31 198.51.100.1") + == "ip route 192.168.0.0 255.255.255.254 198.51.100.1" + ) + assert ( + line_to_mask("ip route 192.168.0.0/32 198.51.100.1") + == "ip route 192.168.0.0 255.255.255.255 198.51.100.1" + ) + def test_line_to_wildcard(): - assert line_to_wildcard("permit tcp 192.0.0.0/4 any eq 22") == "permit tcp 192.0.0.0 15.255.255.255 any eq 22" - assert line_to_wildcard("permit tcp 192.0.0.0/8 any eq 22") == "permit tcp 192.0.0.0 0.255.255.255 any eq 22" - assert line_to_wildcard("permit tcp 192.0.0.0/9 any eq 22") == "permit tcp 192.0.0.0 0.127.255.255 any eq 22" - assert line_to_wildcard("permit tcp 192.168.0.0/16 any eq 22") == "permit tcp 192.168.0.0 0.0.255.255 any eq 22" - assert line_to_wildcard("permit tcp 192.168.0.0/24 any eq 22") == "permit tcp 192.168.0.0 0.0.0.255 any eq 22" - assert line_to_wildcard("permit tcp 192.168.0.0/25 any eq 22") == "permit tcp 192.168.0.0 0.0.0.127 any eq 22" - assert line_to_wildcard("permit tcp 192.168.0.0/30 any eq 22") == "permit tcp 192.168.0.0 0.0.0.3 any eq 22" - assert line_to_wildcard("permit tcp 192.168.0.0/31 any eq 22") == "permit tcp 192.168.0.0 0.0.0.1 any eq 22" - assert line_to_wildcard("permit tcp 192.168.0.0/32 any eq 22") == "permit tcp 192.168.0.0 0.0.0.0 any eq 22" + assert ( + line_to_wildcard("permit tcp 192.0.0.0/4 any eq 22") + == "permit tcp 192.0.0.0 15.255.255.255 any eq 22" + ) + assert ( + line_to_wildcard("permit tcp 192.0.0.0/8 any eq 22") + == "permit tcp 192.0.0.0 0.255.255.255 any eq 22" + ) + assert ( + line_to_wildcard("permit tcp 192.0.0.0/9 any eq 22") + == "permit tcp 192.0.0.0 0.127.255.255 any eq 22" + ) + assert ( + line_to_wildcard("permit tcp 192.168.0.0/16 any eq 22") + == "permit tcp 192.168.0.0 0.0.255.255 any eq 22" + ) + assert ( + line_to_wildcard("permit tcp 192.168.0.0/24 any eq 22") + == "permit tcp 192.168.0.0 0.0.0.255 any eq 22" + ) + assert ( + line_to_wildcard("permit tcp 192.168.0.0/25 any eq 22") + == "permit tcp 192.168.0.0 0.0.0.127 any eq 22" + ) + assert ( + line_to_wildcard("permit tcp 192.168.0.0/30 any eq 22") + == "permit tcp 192.168.0.0 0.0.0.3 any eq 22" + ) + assert ( + line_to_wildcard("permit tcp 192.168.0.0/31 any eq 22") + == "permit tcp 192.168.0.0 0.0.0.1 any eq 22" + ) + assert ( + line_to_wildcard("permit tcp 192.168.0.0/32 any eq 22") + == "permit tcp 192.168.0.0 0.0.0.0 any eq 22" + ) diff --git a/tests/test_render.py b/tests/test_render.py index 15290c6..b8aef81 100644 --- a/tests/test_render.py +++ b/tests/test_render.py @@ -1,26 +1,17 @@ -import os - import netom - from ansible.parsing.dataloader import DataLoader from ansible.template import Templar - +from jinja2 import Environment from netom.filters import ( address_to_mask, - address_to_wildcard, - line_to_mask, - line_to_wildcard, ) -from jinja2 import Environment - - j2env = Environment() -j2env.filters['address_to_mask'] = address_to_mask +j2env.filters["address_to_mask"] = address_to_mask class NetomTemplar(Templar): - '''A custom Templar class which includes additional jinja2 filters.''' + """A custom Templar class which includes additional jinja2 filters.""" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs)