Page MenuHomeDevCentral

No OneTemporary

diff --git a/_modules/network_utils.py b/_modules/network_utils.py
index 1ffb73e..253d972 100644
--- a/_modules/network_utils.py
+++ b/_modules/network_utils.py
@@ -1,46 +1,64 @@
# -*- coding: utf-8 -*-
# -------------------------------------------------------------
# Salt — Network execution module
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Project: Nasqueron
# License: BSD-2-Clause
# -------------------------------------------------------------
+import ipaddress
import re
# -------------------------------------------------------------
# CIDR netmask and prefixes
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
def is_valid_netmask(netmask):
# "255.255.255.240" → "11111111111111111111111111110000"
bits = "".join([format(int(octet), "b") for octet in netmask.split(".")])
# A netmask is valid if the suite of bits:
# - starts by contiguous 1, e.g. here 1111111111111111111111111111
# - ends by contiguous 0, e.g. here 0000
#
# Also, as 0.0.0.0 is invalid, netmask must starts by 1.
return re.compile("^1+0*$").match(bits) is not None
def netmask_to_cidr_prefix(netmask):
"""
Convert a netmask like 255.255.255.240 into a CIDR prefix like 24.
This can be useful for RHEL network scripts requiring PREFIX information.
"""
if not is_valid_netmask(netmask):
raise ValueError("Netmask is invalid.")
# The CIDR prefix is the count of 1 bits in each octet.
# e.g. 255.255.255.240 can be split in octets [255, 255, 255, 240],
# then becomes ['0b11111111', '0b11111111', '0b11111111', '0b11110000'].
#
# There is 24 "1" in this expression, that's 24 is our CIDR prefix.
return sum([bin(int(octet)).count("1") for octet in netmask.split(".")])
+
+
+# -------------------------------------------------------------
+# IPv6 prefixes
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+def _ipv6_address_to_prefix(address, prefixlen):
+ return ipaddress.IPv6Network((address, prefixlen), strict=False)
+
+
+def can_directly_be_discovered(gateway, address, prefixlen):
+ """Determines if the gateway belong to the same prefix than the address,
+ and so can be directly be discovered in NDP."""
+ return _ipv6_address_to_prefix(gateway, prefixlen) == _ipv6_address_to_prefix(
+ address, prefixlen
+ )
diff --git a/_tests/modules/test_network.py b/_tests/modules/test_network.py
index b05ed6e..8ea6ce1 100755
--- a/_tests/modules/test_network.py
+++ b/_tests/modules/test_network.py
@@ -1,53 +1,75 @@
#!/usr/bin/env python3
from importlib.machinery import SourceFileLoader
from unittest_data_provider import data_provider
import unittest
salt_test_case = SourceFileLoader("salt_test_case", "salt_test_case.py").load_module()
network = SourceFileLoader("network", "../_modules/network_utils.py").load_module()
class Testinstance(unittest.TestCase, salt_test_case.SaltTestCase):
cidr_prefixes = lambda: (
("255.255.255.255", 32),
("255.255.255.254", 31),
("255.255.255.252", 30),
("255.255.255.240", 28),
("255.255.255.224", 27),
("255.255.255.0", 24),
("255.252.0.0", 14),
)
valid_netmasks = lambda: (
("255.255.255.255",),
("255.255.255.254",),
("255.255.255.252",),
("255.255.255.240",),
)
invalid_netmasks = lambda: (
# In binary, it's not a suite of 1 then a suite of 0
("255.255.255.209",),
# By definition, netmask MUST be strictly greater than 0
("0.0.0.0",),
)
@data_provider(cidr_prefixes)
def test_netmask_to_cidr_prefix(self, netmask, expected_prefix):
actual_prefix = network.netmask_to_cidr_prefix(netmask)
self.assertTrue(actual_prefix == expected_prefix)
@data_provider(valid_netmasks)
def test_is_valid_netmask(self, netmask):
self.assertTrue(network.is_valid_netmask(netmask))
@data_provider(invalid_netmasks)
def test_is_valid_netmask_when_it_is_not(self, netmask):
self.assertFalse(network.is_valid_netmask(netmask))
+ def test_ipv6_address_to_prefix(self):
+ prefix = network._ipv6_address_to_prefix(
+ "2001:41d0:0303:d9ff:00ff:00ff:00ff:00ff", 64
+ )
+ self.assertEqual("2001:41d0:303:d9ff::", prefix.network_address.compressed)
+
+ def test_can_directly_be_discovered(self):
+ self.assertFalse(
+ network.can_directly_be_discovered(
+ "2001:41d0:0303:d9ff:00ff:00ff:00ff:00ff",
+ "2001:41d0:303:d971::517e:c0de",
+ 64,
+ )
+ )
+ self.assertTrue(
+ network.can_directly_be_discovered(
+ "2001:41d0:0303:d971:00ff:00ff:00ff:00ff",
+ "2001:41d0:303:d971::517e:c0de",
+ 64,
+ )
+ )
+
if __name__ == "__main__":
unittest.main()

File Metadata

Mime Type
text/x-diff
Expires
Fri, Nov 28, 17:38 (1 d, 20 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3209040
Default Alt Text
(4 KB)

Event Timeline