Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change order of ipv4_to_ipv6 arguments #228

Draft
wants to merge 2 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 20 additions & 12 deletions src/cnaas_nms/tools/jinja_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,31 +86,39 @@ def isofy_ipv4(ip_string, prefix=''):

@template_filter()
def ipv4_to_ipv6(
v6_network: Union[str, ipaddress.IPv6Network], v4_address: Union[str, ipaddress.IPv4Interface]
v4_address: Union[str, ipaddress.IPv4Interface],
v6_network: Union[str, ipaddress.IPv6Network],
keep_octets: int = 1,
):
"""Transforms an IPv4 address to an IPv6 interface address. This will combine an arbitrary
IPv6 network address with the 32 address bytes of an IPv4 address into a valid IPv6 address
+ prefix length notation - the equivalent of dotted quad compatible notation.
"""Transforms an IPv4 address intoto an IPv6 interface address that should be more-or-less
identifiable as the same device on a different protocol family.

E.g.:
>>> ipv6 = ipv4_to_ipv6("2001:700:dead:babe::/64", "127.0.0.1")
>>> ipv6
IPv6Interface('2001:700:dead:babe::7f00:1/64')
>>> ipv6 == ipaddress.IPv6Interface('2001:700:dead:babe::127.0.0.1/64')
True
A selected number of octets, right-to-left, of the IPv4 address will be converted to
hexadecimal notation that can be read as the decimal IPv4 address. This will then be used as
a host address on the provided IPv6 network.

Examples:
>>> ipv4_to_ipv6("10.1.0.42", "2001:700:dead:babe::/64")
IPv6Interface('2001:700:dead:babe::42/64')
>>> ipv4_to_ipv6("10.1.0.42", "2001:700:dead:babe::/64", keep_octets=4)
IPv6Interface('2001:700:dead:babe:10:1:0:42/64')

Args:
v6_network: IPv6 network in prefix notation
v4_address: IPv4 address
v6_network: IPv6 network in prefix notation
keep_octets: The number of octets to keep from the IPv4 address (from right-to-left)
Returns:
An IPv6Address object on the given network
"""
if isinstance(v6_network, str):
v6_network = ipaddress.IPv6Network(v6_network)
if isinstance(v4_address, str):
v4_address = ipaddress.IPv4Address(v4_address)
assert keep_octets > 0 <= 4

v6_address = v6_network[int(v4_address)]
octets = str(v4_address).split('.')[-keep_octets:]
v6ified = ipaddress.IPv6Address("::" + ":".join(octets))
v6_address = v6_network[int(v6ified)]
return ipaddress.IPv6Interface(f"{v6_address}/{v6_network.prefixlen}")


Expand Down
12 changes: 6 additions & 6 deletions src/cnaas_nms/tools/tests/test_jinja_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,23 +68,23 @@ class IPv6ToIPv4Tests(unittest.TestCase):

def test_should_convert_short_network_properly(self):
self.assertEqual(
ipv4_to_ipv6('2001:700::/64', '10.0.0.1'),
ipaddress.IPv6Interface('2001:700::10.0.0.1/64'),
ipv4_to_ipv6('10.0.0.1', '2001:700::/64'),
ipaddress.IPv6Interface('2001:700::1/64'),
)

def test_should_convert_long_network_properly(self):
self.assertEqual(
ipv4_to_ipv6('2001:700:dead:c0de:babe::/80', '10.0.0.1'),
ipaddress.IPv6Interface('2001:700:dead:c0de:babe::10.0.0.1/80'),
ipv4_to_ipv6('10.0.0.1', '2001:700:dead:c0de::/64', keep_octets=4),
ipaddress.IPv6Interface('2001:700:dead:c0de:10:0:0:1/64'),
)

def test_should_raise_on_invalid_network(self):
with self.assertRaises(ValueError):
invalid_network = '2001:700:0:::/64'
ipv4_to_ipv6(invalid_network, '10.0.0.1')
ipv4_to_ipv6('10.0.0.1', invalid_network)

def test_should_return_an_ipv6interface(self):
result = ipv4_to_ipv6('2001:700::/64', '10.0.0.1')
result = ipv4_to_ipv6('10.0.0.1', '2001:700::/64')
self.assertIsInstance(result, ipaddress.IPv6Interface)


Expand Down