Merge "Add CIDR format validation"
This commit is contained in:
commit
f81cb5dbd1
@ -11,10 +11,8 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import netaddr
|
||||
from oslo_log import log as logging
|
||||
|
||||
from heat.common import exception
|
||||
from heat.common.i18n import _
|
||||
from heat.common.i18n import _LW
|
||||
from heat.engine import attributes
|
||||
@ -79,7 +77,10 @@ class CloudNetwork(resource.Resource):
|
||||
properties.Schema.STRING,
|
||||
_("The IP block from which to allocate the network. For example, "
|
||||
"172.16.0.0/24 or 2001:DB8::/64."),
|
||||
required=True
|
||||
required=True,
|
||||
constraints=[
|
||||
constraints.CustomConstraint('net_cidr')
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
@ -154,10 +155,6 @@ class CloudNetwork(resource.Resource):
|
||||
|
||||
def validate(self):
|
||||
super(CloudNetwork, self).validate()
|
||||
try:
|
||||
netaddr.IPNetwork(self.properties[self.CIDR])
|
||||
except netaddr.core.AddrFormatError:
|
||||
raise exception.StackValidationFailed(message=_("Invalid cidr"))
|
||||
|
||||
def _resolve_attribute(self, name):
|
||||
net = self.network()
|
||||
|
@ -116,12 +116,15 @@ class CloudNetworkTest(common.HeatTestCase):
|
||||
self.assertEqual(expect_label, res.FnGetAtt('label'))
|
||||
self.assertEqual(expect_cidr, res.FnGetAtt('cidr'))
|
||||
|
||||
def test_create_bad_cider(self, mock_client):
|
||||
self._template['resources']['cnw']['properties']['cidr'] = "bad cidr"
|
||||
def test_create_bad_cidr(self, mock_client):
|
||||
prop = self._template['resources']['cnw']['properties']
|
||||
prop['cidr'] = "bad cidr"
|
||||
self._parse_stack()
|
||||
exc = self.assertRaises(exception.StackValidationFailed,
|
||||
self.stack.validate)
|
||||
self.assertIn("Invalid cidr", six.text_type(exc))
|
||||
self.assertIn("Invalid net cidr", six.text_type(exc))
|
||||
# reset property
|
||||
prop['cidr'] = "172.16.0.0/24"
|
||||
|
||||
def test_check(self, mock_client):
|
||||
self._setup_stack(mock_client)
|
||||
|
@ -12,6 +12,7 @@
|
||||
# under the License.
|
||||
|
||||
import netaddr
|
||||
import six
|
||||
|
||||
from neutronclient.common import exceptions
|
||||
from neutronclient.neutron import v2_0 as neutronV20
|
||||
@ -189,3 +190,21 @@ class MACConstraint(constraints.BaseCustomConstraint):
|
||||
def validate(self, value, context):
|
||||
self._error_message = 'Invalid MAC address.'
|
||||
return netaddr.valid_mac(value)
|
||||
|
||||
|
||||
class CIDRConstraint(constraints.BaseCustomConstraint):
|
||||
|
||||
def _validate_whitespace(self, data):
|
||||
self._error_message = ("Invalid net cidr '%s' contains "
|
||||
"whitespace" % data)
|
||||
if len(data.split()) > 1:
|
||||
return False
|
||||
return True
|
||||
|
||||
def validate(self, value, context):
|
||||
try:
|
||||
netaddr.IPNetwork(value)
|
||||
return self._validate_whitespace(value)
|
||||
except Exception as ex:
|
||||
self._error_message = 'Invalid net cidr %s ' % six.text_type(ex)
|
||||
return False
|
||||
|
@ -298,12 +298,18 @@ class FirewallRule(neutron.NeutronResource):
|
||||
SOURCE_IP_ADDRESS: properties.Schema(
|
||||
properties.Schema.STRING,
|
||||
_('Source IP address or CIDR.'),
|
||||
update_allowed=True
|
||||
update_allowed=True,
|
||||
constraints=[
|
||||
constraints.CustomConstraint('net_cidr')
|
||||
]
|
||||
),
|
||||
DESTINATION_IP_ADDRESS: properties.Schema(
|
||||
properties.Schema.STRING,
|
||||
_('Destination IP address or CIDR.'),
|
||||
update_allowed=True
|
||||
update_allowed=True,
|
||||
constraints=[
|
||||
constraints.CustomConstraint('net_cidr')
|
||||
]
|
||||
),
|
||||
SOURCE_PORT: properties.Schema(
|
||||
properties.Schema.STRING,
|
||||
|
@ -105,7 +105,10 @@ class SecurityGroup(neutron.NeutronResource):
|
||||
RULE_REMOTE_IP_PREFIX: properties.Schema(
|
||||
properties.Schema.STRING,
|
||||
_('The remote IP prefix (CIDR) to be associated with this '
|
||||
'security group rule.')
|
||||
'security group rule.'),
|
||||
constraints=[
|
||||
constraints.CustomConstraint('net_cidr')
|
||||
]
|
||||
),
|
||||
}
|
||||
|
||||
|
@ -84,7 +84,10 @@ class Subnet(neutron.NeutronResource):
|
||||
CIDR: properties.Schema(
|
||||
properties.Schema.STRING,
|
||||
_('The CIDR.'),
|
||||
required=True
|
||||
required=True,
|
||||
constraints=[
|
||||
constraints.CustomConstraint('net_cidr')
|
||||
]
|
||||
),
|
||||
VALUE_SPECS: properties.Schema(
|
||||
properties.Schema.MAP,
|
||||
|
@ -219,7 +219,13 @@ class IPsecSiteConnection(neutron.NeutronResource):
|
||||
PEER_CIDRS: properties.Schema(
|
||||
properties.Schema.LIST,
|
||||
_('Remote subnet(s) in CIDR format.'),
|
||||
required=True
|
||||
required=True,
|
||||
schema=properties.Schema(
|
||||
properties.Schema.STRING,
|
||||
constraints=[
|
||||
constraints.CustomConstraint('net_cidr')
|
||||
]
|
||||
)
|
||||
),
|
||||
MTU: properties.Schema(
|
||||
properties.Schema.INTEGER,
|
||||
|
@ -254,3 +254,30 @@ class TestMACConstraint(common.HeatTestCase):
|
||||
]
|
||||
for mac in invalidate_format:
|
||||
self.assertFalse(self.constraint.validate(mac, None))
|
||||
|
||||
|
||||
class TestCIDRConstraint(common.HeatTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestCIDRConstraint, self).setUp()
|
||||
self.constraint = neutron.CIDRConstraint()
|
||||
|
||||
def test_valid_cidr_format(self):
|
||||
validate_format = [
|
||||
'10.0.0.0/24',
|
||||
'6000::/64',
|
||||
'8.8.8.8'
|
||||
]
|
||||
for cidr in validate_format:
|
||||
self.assertTrue(self.constraint.validate(cidr, None))
|
||||
|
||||
def test_invalid_cidr_format(self):
|
||||
invalidate_format = [
|
||||
'::/129',
|
||||
'Invalid cidr',
|
||||
'300.0.0.0/24',
|
||||
'10.0.0.0/33',
|
||||
'8.8.8.0/ 24'
|
||||
]
|
||||
for cidr in invalidate_format:
|
||||
self.assertFalse(self.constraint.validate(cidr, None))
|
||||
|
@ -75,6 +75,7 @@ heat.constraints =
|
||||
trove.flavor = heat.engine.clients.os.trove:FlavorConstraint
|
||||
ip_addr = heat.engine.clients.os.neutron:IPConstraint
|
||||
mac_addr = heat.engine.clients.os.neutron:MACConstraint
|
||||
net_cidr = heat.engine.clients.os.neutron:CIDRConstraint
|
||||
|
||||
heat.stack_lifecycle_plugins =
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user