From b0b9ae7ddb71d44212aaa2cde980c26f229f6ced Mon Sep 17 00:00:00 2001 From: Martin Komon Date: Tue, 25 Jul 2023 23:09:28 +0200 Subject: [PATCH] add line transformation filters --- src/netom/__init__.py | 4 +++- src/netom/j2_filters.py | 24 ++++++++++++++++++++++++ tests/test_j2_filters.py | 24 +++++++++++++++++++++++- 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/netom/__init__.py b/src/netom/__init__.py index 23fa9ea..9b86995 100644 --- a/src/netom/__init__.py +++ b/src/netom/__init__.py @@ -9,7 +9,7 @@ from . import filters from .exception import NetomValidationError -from .j2_filters import address_to_mask, address_to_wildcard +from .j2_filters import address_to_mask, address_to_wildcard, line_to_mask, line_to_wildcard # TODO move out of this namespace from .models import BgpNeighbor @@ -47,6 +47,8 @@ def set_search_path(self, search_path): self.engine.engine.filters["ip_version"] = ip_version self.engine.engine.filters["address_to_mask"] = address_to_mask self.engine.engine.filters["address_to_wildcard"] = address_to_wildcard + self.engine.engine.filters["line_to_mask"] = line_to_mask + self.engine.engine.filters["line_to_wildcard"] = line_to_wildcard # self.engine.search_path = os.path.dirname(search_path) for name in filters.__all__: diff --git a/src/netom/j2_filters.py b/src/netom/j2_filters.py index b5c495b..65cbef3 100644 --- a/src/netom/j2_filters.py +++ b/src/netom/j2_filters.py @@ -1,6 +1,11 @@ import ipaddress +import re from ipaddress import IPv4Address + +r_ip_nn = re.compile("[\d.]{7,15}/\d{1,2}") + + def address_to_mask(addr): """ Transform A.B.C.D/nn into A.B.C.D M.M.M.M subnet mask format. @@ -19,3 +24,22 @@ def address_to_wildcard(addr): ipnet4 = ipaddress.ip_network(addr) wildcard = str(IPv4Address(int(IPv4Address(ipnet4.netmask))^(2**32-1))) return f"{ipnet4.network_address} {wildcard}" + + +def line_to_mask(line): + """ + Search for any IPv4/nn tokens in the `line` argument and transform them into mask format. + 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]) + + +def line_to_wildcard(line): + """ + Search for any IPv4/nn tokens in the `line` argument and transform them into wildcard format. + 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]) + diff --git a/tests/test_j2_filters.py b/tests/test_j2_filters.py index d4c0f63..9e9034d 100644 --- a/tests/test_j2_filters.py +++ b/tests/test_j2_filters.py @@ -1,5 +1,5 @@ -from netom.j2_filters import address_to_mask, address_to_wildcard +from netom.j2_filters import address_to_mask, address_to_wildcard, line_to_mask, line_to_wildcard import pytest @@ -24,3 +24,25 @@ def test_address_to_wildcard(): assert address_to_wildcard("192.168.0.0/30") == "192.168.0.0 0.0.0.3" 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" + +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"