Merge "Improving IPV4 validation for configs"

This commit is contained in:
Zuul 2022-01-10 18:21:15 +00:00 committed by Gerrit Code Review
commit a37c216b8f
2 changed files with 62 additions and 2 deletions

View File

@ -1951,16 +1951,25 @@ def is_valid_domain_or_ip(url_str):
if url_str:
url_without_path = url_str.split('/')[0]
url_with_port = url_without_path.split(':')
# check ipv4 or ipv4 with port
if len(url_with_port) <= 2:
try:
if len(url_with_port) == 2 and not int(url_with_port[1]) in range(1, 65535):
return False
except ValueError:
return False
if is_possible_ipv4_address(url_with_port[0]):
return is_valid_ipv4(url_with_port[0])
if is_valid_domain(url_with_port[0]):
return True
# check ipv4 or ipv4 with port
return is_valid_ipv4(url_with_port[0])
else:
# check ipv6
if '[' in url_without_path:
try:
bkt_idx = url_without_path.index(']')
port = url_without_path[bkt_idx:].replace(']:', '')
if not int(port) in range(1, 65535):
return False
return is_valid_ipv6(url_without_path[1:bkt_idx])
except Exception:
return False
@ -1969,6 +1978,20 @@ def is_valid_domain_or_ip(url_str):
return is_valid_ipv6(url_without_path)
def is_possible_ipv4_address(str_ip):
"""
This method does not validate if the string is a valid IPV4,
it only verifies if the string matches a IPV4 basic format of
four numbers separated by dots.
"""
r = re.compile(r'^(?:[0-9](?:[0-9-]{0,61}[0-9])?\.)+([0-9-]+\.?)')
url = r.match(str_ip)
if url:
return True
else:
return False
def is_valid_domain_name(value):
""" Validate domain name based on RFC specs including IDN """
p = re.compile(

View File

@ -229,6 +229,43 @@ class GenericUtilsTestCase(base.TestCase):
self.assertFalse(utils.is_valid_boolstr('maybe'))
self.assertFalse(utils.is_valid_boolstr('only on tuesdays'))
def test_is_valid_domain_or_ip(self):
# IPV6
# Valid IPV6 without port
self.assertTrue(utils.is_valid_domain_or_ip("1fff:0:a88:85a3::ac1f/index.html"))
self.assertTrue(utils.is_valid_domain_or_ip("::"))
# Valid IPV6 with port
self.assertTrue(utils.is_valid_domain_or_ip("[::]:8000"))
self.assertTrue(utils.is_valid_domain_or_ip("[1fff:0:a88:85a3::ac1f]:22"))
# Invalid IPV6 without port
self.assertFalse(utils.is_valid_domain_or_ip("2002:1d:"))
self.assertFalse(utils.is_valid_domain_or_ip(":1d::"))
# IPV6 with invalid port
self.assertFalse(utils.is_valid_domain_or_ip("[::]:75535"))
self.assertFalse(utils.is_valid_domain_or_ip("[1fff:0:a88:85a3::ac1f]:99999"))
self.assertFalse(utils.is_valid_domain_or_ip("[1fff:0:a88:85a3::ac1f]:90a90"))
# IPV4
# Valid IPV4 without port
self.assertTrue(utils.is_valid_domain_or_ip("192.2.3.4"))
self.assertTrue(utils.is_valid_domain_or_ip("255.90.33.87"))
# Valid IPV4 with port
self.assertTrue(utils.is_valid_domain_or_ip("100.168.0.98:12345"))
self.assertTrue(utils.is_valid_domain_or_ip("192.168.0.98:8080"))
# Invalid IPV4 without port
self.assertFalse(utils.is_valid_domain_or_ip("192.168.0.999999"))
self.assertFalse(utils.is_valid_domain_or_ip("500.168.0.10"))
# IPV4 with invalid port
self.assertFalse(utils.is_valid_domain_or_ip("100.168.0.10:99999"))
self.assertFalse(utils.is_valid_domain_or_ip("100.168.0.10:80000"))
self.assertFalse(utils.is_valid_domain_or_ip("100.168.0.10:8cc00"))
def test_is_possible_ipv4_address(self):
self.assertTrue(utils.is_possible_ipv4_address('127.0.0.1'))
self.assertTrue(utils.is_possible_ipv4_address('9999.9999.9999.9999'))
self.assertFalse(utils.is_possible_ipv4_address('::1'))
self.assertFalse(utils.is_possible_ipv4_address('bacon'))
self.assertFalse(utils.is_possible_ipv4_address(""))
def test_is_valid_ipv4(self):
self.assertTrue(utils.is_valid_ipv4('127.0.0.1'))
self.assertFalse(utils.is_valid_ipv4('::1'))