attributes: Additional IP address validation
Introduce an additional IP address validation instead of assuming that netaddr provides it. Namely, it ensures that an address either has ':' (IPv6) or 3 periods like 'xx.xx.xx.xx'. (IPv4) The "'1' * 59" test case recently introduced by commit1681f62ec9
fails on some platforms because it's considered a valid address by their inet_aton. Examples of such platforms: NetBSD, OS X While one might argue it's a fault of the platforms, this is a historical behavior which is probably too late to change there. (The breakage has been hidden by later UT changes in commit35662d0762
. This commit includes a UT change to uncover the problem again.) (cherry-picked from2794bb89d6
) Closes-Bug: #1394867 Related-Bug: #1378450 Change-Id: Ibe02f8b7c4d437bf7abbe7304ca138bdcf4bfdb9
This commit is contained in:
parent
91a4593346
commit
d329c221c3
|
@ -175,6 +175,21 @@ def _validate_mac_address_or_none(data, valid_values=None):
|
|||
def _validate_ip_address(data, valid_values=None):
|
||||
try:
|
||||
netaddr.IPAddress(_validate_no_whitespace(data))
|
||||
# The followings are quick checks for IPv6 (has ':') and
|
||||
# IPv4. (has 3 periods like 'xx.xx.xx.xx')
|
||||
# NOTE(yamamoto): netaddr uses libraries provided by the underlying
|
||||
# platform to convert addresses. For example, inet_aton(3).
|
||||
# Some platforms, including NetBSD and OS X, have inet_aton
|
||||
# implementation which accepts more varying forms of addresses than
|
||||
# we want to accept here. The following check is to reject such
|
||||
# addresses. For Example:
|
||||
# >>> netaddr.IPAddress('1' * 59)
|
||||
# IPAddress('199.28.113.199')
|
||||
# >>> netaddr.IPAddress(str(int('1' * 59) & 0xffffffff))
|
||||
# IPAddress('199.28.113.199')
|
||||
# >>>
|
||||
if ':' not in data and data.count('.') != 3:
|
||||
raise ValueError()
|
||||
except Exception:
|
||||
msg = _("'%s' is not a valid IP address") % data
|
||||
LOG.debug(msg)
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
|
||||
import testtools
|
||||
|
||||
import mock
|
||||
|
||||
from neutron.api.v2 import attributes
|
||||
from neutron.common import exceptions as n_exc
|
||||
from neutron.tests import base
|
||||
|
@ -204,6 +206,12 @@ class TestAttributes(base.BaseTestCase):
|
|||
msg = attributes._validate_ip_address(ip_addr)
|
||||
self.assertEqual(msg, "'%s' is not a valid IP address" % ip_addr)
|
||||
|
||||
# Depending on platform to run UTs, this case might or might not be
|
||||
# an equivalent to test_validate_ip_address_bsd.
|
||||
ip_addr = '1' * 59
|
||||
msg = attributes._validate_ip_address(ip_addr)
|
||||
self.assertEqual("'%s' is not a valid IP address" % ip_addr, msg)
|
||||
|
||||
ip_addr = '1.1.1.1 has whitespace'
|
||||
msg = attributes._validate_ip_address(ip_addr)
|
||||
self.assertEqual(msg, "'%s' is not a valid IP address" % ip_addr)
|
||||
|
@ -216,6 +224,18 @@ class TestAttributes(base.BaseTestCase):
|
|||
msg = attributes._validate_ip_address(ip_addr)
|
||||
self.assertEqual(msg, "'%s' is not a valid IP address" % ip_addr)
|
||||
|
||||
def test_validate_ip_address_bsd(self):
|
||||
# NOTE(yamamoto): On NetBSD and OS X, netaddr.IPAddress() accepts
|
||||
# '1' * 59 as a valid address. The behaviour is inherited from
|
||||
# libc behaviour there. This test ensures that our validator reject
|
||||
# such addresses on such platforms by mocking netaddr to emulate
|
||||
# the behaviour.
|
||||
ip_addr = '1' * 59
|
||||
with mock.patch('netaddr.IPAddress') as ip_address_cls:
|
||||
msg = attributes._validate_ip_address(ip_addr)
|
||||
ip_address_cls.assert_called_once_with(ip_addr)
|
||||
self.assertEqual("'%s' is not a valid IP address" % ip_addr, msg)
|
||||
|
||||
def test_validate_ip_pools(self):
|
||||
pools = [[{'end': '10.0.0.254'}],
|
||||
[{'start': '10.0.0.254'}],
|
||||
|
|
Loading…
Reference in New Issue