Merge "Validate properties against the schema in validate_template"
This commit is contained in:
commit
a6f228783c
@ -172,13 +172,14 @@ class Properties(collections.Mapping):
|
||||
else:
|
||||
self.error_prefix = parent_name + ': '
|
||||
|
||||
def validate(self):
|
||||
def validate(self, with_value=True):
|
||||
for (key, prop) in self.props.items():
|
||||
try:
|
||||
self[key]
|
||||
except ValueError as e:
|
||||
msg = "Property error : %s" % str(e)
|
||||
raise exception.StackValidationFailed(message=msg)
|
||||
if with_value:
|
||||
try:
|
||||
self[key]
|
||||
except ValueError as e:
|
||||
msg = "Property error : %s" % str(e)
|
||||
raise exception.StackValidationFailed(message=msg)
|
||||
|
||||
# are there unimplemented Properties
|
||||
if not prop.implemented() and key in self.data:
|
||||
|
@ -28,6 +28,7 @@ from heat.common import exception
|
||||
from heat.common import identifier
|
||||
from heat.engine import parameters
|
||||
from heat.engine import parser
|
||||
from heat.engine import properties
|
||||
from heat.engine import resource
|
||||
from heat.engine import watchrule
|
||||
|
||||
@ -285,6 +286,13 @@ class EngineService(service.Service):
|
||||
if not res.get('Type'):
|
||||
return {'Error':
|
||||
'Every Resources object must contain a Type member.'}
|
||||
ResourceClass = resource.get_class(res['Type'])
|
||||
props = properties.Properties(ResourceClass.properties_schema,
|
||||
res.get('Properties', {}))
|
||||
try:
|
||||
props.validate(with_value=False)
|
||||
except Exception as ex:
|
||||
return {'Error': str(ex)}
|
||||
|
||||
tmpl_params = parser.Parameters(None, tmpl)
|
||||
format_validate_parameter = lambda p: dict(p.schema)
|
||||
|
@ -207,6 +207,64 @@ test_template_findinmap_invalid = '''
|
||||
}
|
||||
'''
|
||||
|
||||
test_template_invalid_property = '''
|
||||
{
|
||||
"AWSTemplateFormatVersion" : "2010-09-09",
|
||||
"Description" : "test.",
|
||||
"Parameters" : {
|
||||
|
||||
"KeyName" : {
|
||||
''' + \
|
||||
'"Description" : "Name of an existing EC2' + \
|
||||
'KeyPair to enable SSH access to the instances",' + \
|
||||
'''
|
||||
"Type" : "String"
|
||||
}
|
||||
},
|
||||
|
||||
"Resources" : {
|
||||
"WikiDatabase": {
|
||||
"Type": "AWS::EC2::Instance",
|
||||
"Properties": {
|
||||
"ImageId": "image_name",
|
||||
"InstanceType": "m1.large",
|
||||
"KeyName": { "Ref" : "KeyName" },
|
||||
"UnknownProperty": "unknown"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
'''
|
||||
|
||||
test_template_unimplemented_property = '''
|
||||
{
|
||||
"AWSTemplateFormatVersion" : "2010-09-09",
|
||||
"Description" : "test.",
|
||||
"Parameters" : {
|
||||
|
||||
"KeyName" : {
|
||||
''' + \
|
||||
'"Description" : "Name of an existing EC2' + \
|
||||
'KeyPair to enable SSH access to the instances",' + \
|
||||
'''
|
||||
"Type" : "String"
|
||||
}
|
||||
},
|
||||
|
||||
"Resources" : {
|
||||
"WikiDatabase": {
|
||||
"Type": "AWS::EC2::Instance",
|
||||
"Properties": {
|
||||
"ImageId": "image_name",
|
||||
"InstanceType": "m1.large",
|
||||
"KeyName": { "Ref" : "KeyName" },
|
||||
"SourceDestCheck": "false"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
'''
|
||||
|
||||
|
||||
@attr(tag=['unit', 'validate'])
|
||||
@attr(speed='fast')
|
||||
@ -302,3 +360,25 @@ class validateTest(unittest.TestCase):
|
||||
'Type': 'String',
|
||||
'Description': 'Name of an existing EC2KeyPair to enable SSH '
|
||||
'access to the instances'}})
|
||||
|
||||
def test_validate_properties(self):
|
||||
t = template_format.parse(test_template_invalid_property)
|
||||
self.m.StubOutWithMock(instances.Instance, 'nova')
|
||||
instances.Instance.nova().AndReturn(self.fc)
|
||||
self.m.ReplayAll()
|
||||
|
||||
engine = service.EngineService('a', 't')
|
||||
res = dict(engine.validate_template(None, t))
|
||||
self.assertEqual(res, {'Error': 'Unknown Property UnknownProperty'})
|
||||
|
||||
def test_unimplemented_property(self):
|
||||
t = template_format.parse(test_template_unimplemented_property)
|
||||
self.m.StubOutWithMock(instances.Instance, 'nova')
|
||||
instances.Instance.nova().AndReturn(self.fc)
|
||||
self.m.ReplayAll()
|
||||
|
||||
engine = service.EngineService('a', 't')
|
||||
res = dict(engine.validate_template(None, t))
|
||||
self.assertEqual(
|
||||
res,
|
||||
{'Error': 'Property SourceDestCheck not implemented yet'})
|
||||
|
Loading…
Reference in New Issue
Block a user