summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Stappaerts <tom.stappaerts@nuagenetworks.net>2019-06-12 13:56:30 +0200
committerTom Stappaerts <tom.stappaerts@nuagenetworks.net>2019-08-05 11:15:22 +0000
commitac3bf784ff9eabf3010ac377e5727893a583c3f9 (patch)
tree3a34abe4c1e2348d29b91d15055d9a3ce337c7eb
parent3f81939870c3b3de63a4cb98c77ded728e6d1948 (diff)
downloadheat-ac3bf784ff9eabf3010ac377e5727893a583c3f9.tar.gz
Fix allowed address pair validation
Neutron requires the allowed address pair ip address to be either an ip or a cidr. https://review.opendev.org/#/c/575265/ made heat verify for cidr only. Change-Id: I2cc2785cb32cf8d788af6262992b1b76107c8292 Story: 2005674 Task: 30985 (cherry picked from commit 5e93b3e4cf60310d33bf397fd11b4ec50e6067a0) (cherry picked from commit cec8b079c006522b2b2eaeede49a7a7229f7ae2d)
-rw-r--r--heat/engine/constraint/common_constraints.py14
-rw-r--r--heat/tests/constraints/test_common_constraints.py53
-rw-r--r--heat/tests/openstack/neutron/test_neutron_port.py4
-rw-r--r--heat/tests/openstack/neutron/test_neutron_subnet.py4
4 files changed, 54 insertions, 21 deletions
diff --git a/heat/engine/constraint/common_constraints.py b/heat/engine/constraint/common_constraints.py
index 124f09eb9..e5f08ab81 100644
--- a/heat/engine/constraint/common_constraints.py
+++ b/heat/engine/constraint/common_constraints.py
@@ -107,14 +107,18 @@ class CIDRConstraint(constraints.BaseCustomConstraint):
def validate(self, value, context, template=None):
try:
- netaddr.IPNetwork(value, implicit_prefix=True)
- msg = validators.validate_subnet(value)
+ if '/' in value:
+ msg = validators.validate_subnet(value)
+ else:
+ msg = validators.validate_ip_address(value)
if msg is not None:
self._error_message = msg
return False
- return True
- except Exception as ex:
- self._error_message = 'Invalid net cidr %s ' % six.text_type(ex)
+ else:
+ return True
+ except Exception:
+ self._error_message = '{} is not a valid IP or CIDR'.format(
+ value)
return False
diff --git a/heat/tests/constraints/test_common_constraints.py b/heat/tests/constraints/test_common_constraints.py
index 665c0b903..89f47e643 100644
--- a/heat/tests/constraints/test_common_constraints.py
+++ b/heat/tests/constraints/test_common_constraints.py
@@ -102,15 +102,22 @@ class TestCIDRConstraint(common.HeatTestCase):
super(TestCIDRConstraint, self).setUp()
self.constraint = cc.CIDRConstraint()
- def test_valid_cidr_format(self):
+ def test_valid_format(self):
validate_format = [
'10.0.0.0/24',
+ '1.1.1.1',
+ '1.0.1.1',
+ '255.255.255.255',
'6000::/64',
+ '2002:2002::20c:29ff:fe7d:811a',
+ '::1',
+ '2002::',
+ '2002::1',
]
- for cidr in validate_format:
- self.assertTrue(self.constraint.validate(cidr, None))
+ for value in validate_format:
+ self.assertTrue(self.constraint.validate(value, None))
- def test_invalid_cidr_format(self):
+ def test_invalid_format(self):
invalidate_format = [
'::/129',
'Invalid cidr',
@@ -120,25 +127,45 @@ class TestCIDRConstraint(common.HeatTestCase):
'10.0/24',
'10.0.a.10/24',
'8.8.8.0/ 24',
- '8.8.8.8'
+ None,
+ 123,
+ '1.1',
+ '1.1.',
+ '1.1.1',
+ '1.1.1.',
+ '1.1.1.256',
+ '1.a.1.1',
+ '2002::2001::1',
+ '2002::g',
+ '2001::0::',
+ '20c:29ff:fe7d:811a'
]
- for cidr in invalidate_format:
- self.assertFalse(self.constraint.validate(cidr, None))
+ for value in invalidate_format:
+ self.assertFalse(self.constraint.validate(value, None))
@mock.patch('neutron_lib.api.validators.validate_subnet')
- def test_validate(self, mock_validate_subnet):
+ @mock.patch('neutron_lib.api.validators.validate_ip_address')
+ def test_validate(self, mock_validate_ip, mock_validate_subnet):
test_formats = [
'10.0.0/24',
'10.0/24',
- ]
- self.assertFalse(self.constraint.validate('10.0.0.0/33', None))
+ '10.0.0.0/33',
+ ]
for cidr in test_formats:
self.assertFalse(self.constraint.validate(cidr, None))
+ mock_validate_subnet.assert_called_with(cidr)
+ self.assertEqual(mock_validate_subnet.call_count, 3)
- mock_validate_subnet.assert_any_call('10.0.0/24')
- mock_validate_subnet.assert_called_with('10.0/24')
- self.assertEqual(mock_validate_subnet.call_count, 2)
+ test_formats = [
+ '10.0.0',
+ '10.0',
+ '10.0.0.0',
+ ]
+ for ip in test_formats:
+ self.assertFalse(self.constraint.validate(ip, None))
+ mock_validate_ip.assert_called_with(ip)
+ self.assertEqual(mock_validate_ip.call_count, 3)
class TestISO8601Constraint(common.HeatTestCase):
diff --git a/heat/tests/openstack/neutron/test_neutron_port.py b/heat/tests/openstack/neutron/test_neutron_port.py
index b27b4eda2..149539fc8 100644
--- a/heat/tests/openstack/neutron/test_neutron_port.py
+++ b/heat/tests/openstack/neutron/test_neutron_port.py
@@ -183,6 +183,8 @@ class NeutronPortTest(common.HeatTestCase):
def test_allowed_address_pair(self):
t = template_format.parse(neutron_port_with_address_pair_template)
+ t['resources']['port']['properties'][
+ 'allowed_address_pairs'][0]['ip_address'] = '10.0.3.21'
stack = utils.parse_stack(t)
self.find_mock.return_value = 'abcd1234'
@@ -200,7 +202,7 @@ class NeutronPortTest(common.HeatTestCase):
self.create_mock.assert_called_once_with({'port': {
'network_id': u'abcd1234',
'allowed_address_pairs': [{
- 'ip_address': u'10.0.3.21/8',
+ 'ip_address': u'10.0.3.21',
'mac_address': u'00-B0-D0-86-BB-F7'
}],
'name': utils.PhysName(stack.name, 'port'),
diff --git a/heat/tests/openstack/neutron/test_neutron_subnet.py b/heat/tests/openstack/neutron/test_neutron_subnet.py
index 4804a376f..5c25e2749 100644
--- a/heat/tests/openstack/neutron/test_neutron_subnet.py
+++ b/heat/tests/openstack/neutron/test_neutron_subnet.py
@@ -551,8 +551,8 @@ class NeutronSubnetTest(common.HeatTestCase):
rsrc.validate)
msg = ("Property error: "
"resources.sub_net.properties.host_routes[0].destination: "
- "Error validating value 'invalid_cidr': Invalid net cidr "
- "invalid IPNetwork invalid_cidr ")
+ "Error validating value 'invalid_cidr': "
+ "'invalid_cidr' is not a valid IP address")
self.assertEqual(msg, six.text_type(ex))
def test_ipv6_validate_ra_mode(self):