Add a `strict
` flag allowing users to restrict validation of IPv4 format
Add a ``strict`` flag allowing users to restrict validation to IP addresses in presentation format (``a.b.c.d``) as opposed to address format (``a.b.c.d``, ``a.b.c``, ``a.b``, ``a``). https://github.com/netaddr/netaddr/issues/186 https://man7.org/linux/man-pages/man3/inet_pton.3.html https://bugzilla.redhat.com/show_bug.cgi?id=1924436 Change-Id: I10fed16dad77ac17691a5d175c42b25916dc8bc4 Closes-Bug: #1914386
This commit is contained in:
parent
870ab370c5
commit
3288539a0b
@ -24,6 +24,7 @@ import socket
|
|||||||
from urllib import parse
|
from urllib import parse
|
||||||
|
|
||||||
import netaddr
|
import netaddr
|
||||||
|
from netaddr.core import INET_PTON
|
||||||
import netifaces
|
import netifaces
|
||||||
|
|
||||||
from oslo_utils._i18n import _
|
from oslo_utils._i18n import _
|
||||||
@ -81,17 +82,43 @@ def parse_host_port(address, default_port=None):
|
|||||||
return (host, None if port is None else int(port))
|
return (host, None if port is None else int(port))
|
||||||
|
|
||||||
|
|
||||||
def is_valid_ipv4(address):
|
def is_valid_ipv4(address, strict=None):
|
||||||
"""Verify that address represents a valid IPv4 address.
|
"""Verify that address represents a valid IPv4 address.
|
||||||
|
|
||||||
:param address: Value to verify
|
:param address: Value to verify
|
||||||
:type address: string
|
:type address: string
|
||||||
|
:param strict: flag allowing users to restrict validation
|
||||||
|
to IP addresses in presentation format (``a.b.c.d``) as opposed to
|
||||||
|
address format (``a.b.c.d``, ``a.b.c``, ``a.b``, ``a``).
|
||||||
|
:type flags: bool
|
||||||
:returns: bool
|
:returns: bool
|
||||||
|
|
||||||
.. versionadded:: 1.1
|
.. versionadded:: 1.1
|
||||||
|
.. versionchanged:: 4.8.0
|
||||||
|
Allow to restrict validation to IP addresses in presentation format
|
||||||
|
(``a.b.c.d``) as opposed to address format
|
||||||
|
(``a.b.c.d``, ``a.b.c``, ``a.b``, ``a``).
|
||||||
"""
|
"""
|
||||||
|
if strict is not None:
|
||||||
|
flag = INET_PTON if strict else 0
|
||||||
|
try:
|
||||||
|
return netaddr.valid_ipv4(address, flags=flag)
|
||||||
|
except netaddr.AddrFormatError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# non strict mode
|
||||||
try:
|
try:
|
||||||
return netaddr.valid_ipv4(address)
|
if netaddr.valid_ipv4(address, flags=INET_PTON):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
if netaddr.valid_ipv4(address):
|
||||||
|
LOG.warn(
|
||||||
|
'Converting in non strict mode is deprecated. '
|
||||||
|
'You should pass strict=False if you want to '
|
||||||
|
'preserve legacy behavior')
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
except netaddr.AddrFormatError:
|
except netaddr.AddrFormatError:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -154,13 +154,52 @@ class NetworkUtilsTest(test_base.BaseTestCase):
|
|||||||
netutils.set_tcp_keepalive(mock_sock, False)
|
netutils.set_tcp_keepalive(mock_sock, False)
|
||||||
self.assertEqual(1, len(mock_sock.mock_calls))
|
self.assertEqual(1, len(mock_sock.mock_calls))
|
||||||
|
|
||||||
def test_is_valid_ipv4(self):
|
@mock.patch.object(netutils, 'LOG', autospec=True)
|
||||||
|
def test_is_valid_ipv4(self, mock_log):
|
||||||
|
expected_log = 'Converting in non strict mode is deprecated. ' \
|
||||||
|
'You should pass strict=False if you want to preserve ' \
|
||||||
|
'legacy behavior'
|
||||||
self.assertTrue(netutils.is_valid_ipv4('42.42.42.42'))
|
self.assertTrue(netutils.is_valid_ipv4('42.42.42.42'))
|
||||||
|
|
||||||
self.assertFalse(netutils.is_valid_ipv4('-1.11.11.11'))
|
self.assertFalse(netutils.is_valid_ipv4('-1.11.11.11'))
|
||||||
|
|
||||||
self.assertFalse(netutils.is_valid_ipv4(''))
|
self.assertFalse(netutils.is_valid_ipv4(''))
|
||||||
|
|
||||||
|
self.assertTrue(netutils.is_valid_ipv4('10'))
|
||||||
|
mock_log.warn.assert_called_with(expected_log)
|
||||||
|
mock_log.reset_mock()
|
||||||
|
self.assertTrue(netutils.is_valid_ipv4('10.10'))
|
||||||
|
mock_log.warn.assert_called_with(expected_log)
|
||||||
|
mock_log.reset_mock()
|
||||||
|
self.assertTrue(netutils.is_valid_ipv4('10.10.10'))
|
||||||
|
mock_log.warn.assert_called_with(expected_log)
|
||||||
|
mock_log.reset_mock()
|
||||||
|
self.assertTrue(netutils.is_valid_ipv4('10.10.10.10'))
|
||||||
|
mock_log.warn.assert_not_called()
|
||||||
|
mock_log.reset_mock()
|
||||||
|
self.assertFalse(
|
||||||
|
netutils.is_valid_ipv4('10', strict=True)
|
||||||
|
)
|
||||||
|
self.assertFalse(
|
||||||
|
netutils.is_valid_ipv4('10.10', strict=True)
|
||||||
|
)
|
||||||
|
self.assertFalse(
|
||||||
|
netutils.is_valid_ipv4('10.10.10', strict=True)
|
||||||
|
)
|
||||||
|
mock_log.warn.assert_not_called()
|
||||||
|
mock_log.reset_mock()
|
||||||
|
self.assertTrue(
|
||||||
|
netutils.is_valid_ipv4('10', strict=False)
|
||||||
|
)
|
||||||
|
self.assertTrue(
|
||||||
|
netutils.is_valid_ipv4('10.10', strict=False)
|
||||||
|
)
|
||||||
|
self.assertTrue(
|
||||||
|
netutils.is_valid_ipv4('10.10.10', strict=False)
|
||||||
|
)
|
||||||
|
mock_log.warn.assert_not_called()
|
||||||
|
mock_log.reset_mock()
|
||||||
|
|
||||||
def test_is_valid_ipv6(self):
|
def test_is_valid_ipv6(self):
|
||||||
self.assertTrue(netutils.is_valid_ipv6('::1'))
|
self.assertTrue(netutils.is_valid_ipv6('::1'))
|
||||||
|
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Add a ``strict`` flag to ``netutils.is_valid_ipv4`` to allowing users to
|
||||||
|
restrict validation to IP addresses in presentation format (``a.b.c.d``)
|
||||||
|
as opposed to address format (``a.b.c.d``, ``a.b.c``, ``a.b``, ``a``).
|
Loading…
x
Reference in New Issue
Block a user