Skip to content

Commit

Permalink
isofy: Add prefix parameter (revision 3)
Browse files Browse the repository at this point in the history
  • Loading branch information
katsel committed May 18, 2021
1 parent ecf4457 commit 58989d7
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 29 deletions.
45 changes: 24 additions & 21 deletions src/cnaas_nms/tools/jinja_filters.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import ipaddress
import re


def increment_ip(ip_string, increment=1):
Expand Down Expand Up @@ -29,40 +30,42 @@ def increment_ip(ip_string, increment=1):
return format(ip + increment)


def isofy_ipv4(ip_string, octets=7):
def isofy_ipv4(ip_string, prefix=''):
"""Transform IPv4 address so it can be used as an ISO/NET address.
All four blocks of the IP address are padded with zeros and split up into double octets.
Example: 10.255.255.1 -> 0102.5525.5001.00
Args:
ip_string: a valid IPv4 address
octets: number of octets to return (default: 7)
prefix: optional prefix to be used
Returns:
Last n octets of an ISO address
ISO address
"""
ipaddress.IPv4Address(ip_string) # fails for invalid IP
# split + pad IP

if prefix != '':
prefix_valid = bool(re.match('^.{2}(\..{4})*?$', prefix))
if not prefix_valid:
raise ValueError(f"{prefix} cannot be used as ISO prefix, please check formatting")
prefix += '.'

ip_parts = ip_string.split('.')
padded = [p.zfill(3) for p in ip_parts]
joined = ''.join(padded)
# make octets

chunksize = 2
chunks = [joined[i : i + chunksize] for i in range(0, len(joined), chunksize)]
chunks += ['00']
ip_octets = [joined[i : i + chunksize] for i in range(0, len(joined), chunksize)]
ip_octets += ['00']

missing_octets = octets - len(chunks)
if missing_octets < 0:
raise ValueError(f"IP Address {ip_string} cannot be represented in {octets} octets")
else:
# pad with missing octets
chunks = missing_octets * ['00'] + chunks
# result array with dots and octets, used for formatting
chunks.reverse()
resultsize = 2 * len(chunks) - 1
result = resultsize * ['']
result[1::4] = len(result[1::4]) * '.'
result[0::2] = chunks
result.reverse()
return ''.join(result)
# format: add . after every other octet, starting at the end
ip_octets.reverse()
resultsize = 2 * len(ip_octets) - 1
result = resultsize * ['']
result[1::4] = len(result[1::4]) * '.'
result[0::2] = ip_octets
result.reverse()

iso_address = prefix + ''.join(result)
return iso_address


def ipv4_to_ipv6(v6network_string, v4address):
Expand Down
27 changes: 19 additions & 8 deletions src/cnaas_nms/tools/tests/test_jinja_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,25 @@ def test_isofy_ipv4(self):
with self.assertRaises(ValueError):
isofy_ipv4('10.256.255.1')

def test_isofy_ipv4_octetcount(self):
with self.assertRaises(ValueError):
isofy_ipv4('10.255.255.1', 6)
self.assertEqual(isofy_ipv4('10.255.255.1', 7), '0102.5525.5001.00')
self.assertEqual(isofy_ipv4('10.255.255.1', 8), '00.0102.5525.5001.00')
self.assertEqual(isofy_ipv4('10.255.255.1', 9), '0000.0102.5525.5001.00')
self.assertEqual(isofy_ipv4('10.255.255.1', 10), '00.0000.0102.5525.5001.00')
self.assertEqual(isofy_ipv4('10.255.255.1', 20), '00.0000.0000.0000.0000.0000.0000.0102.5525.5001.00')
def test_isofy_ipv4_prefix(self):
self.assertEqual(
isofy_ipv4('130.242.1.28', prefix='47.0023.0000.0001.0000'),
'47.0023.0000.0001.0000.1302.4200.1028.00',
)
self.assertEqual(
isofy_ipv4('130.242.1.28', prefix='47.0023.0000.0001'),
'47.0023.0000.0001.1302.4200.1028.00',
)
self.assertEqual(isofy_ipv4('130.242.1.28', '47'), '47.1302.4200.1028.00')
invalid_prefixes = [
'47.0023.0000.0001.00',
'47.0023.0000.0001.000',
'47.0023.0000.0001.0000.',
'0047.0023.0000.0001.0000',
]
for prefix in invalid_prefixes:
with self.assertRaises(ValueError):
isofy_ipv4('10.0.0.1', prefix=prefix)

def test_ipv4_to_ipv6(self):
self.assertEqual(ipv4_to_ipv6('2001:700::/64', '10.0.0.1'), '2001:700::10:0:0:1/64')
Expand Down

0 comments on commit 58989d7

Please sign in to comment.