Fix for bad content inside Resources element

In validate_template check if we have a dict before we try to
get 'Type'. We also need to check the response back from
validate_template to see if there are any 'Error'(s) and present
that back to the user.

Fixes LP# 1204157

Change-Id: I0f636a6a84f6afc9a0aff3089e2bd13a8f88a470
This commit is contained in:
Davanum Srinivas 2013-07-23 23:14:16 -04:00 committed by Gerrit Code Review
parent 2ffb44e0aa
commit 11c6c3b7d7
4 changed files with 87 additions and 2 deletions

View File

@ -438,6 +438,10 @@ class StackController(object):
try:
res = self.engine_rpcapi.validate_template(con, template)
if 'Error' in res:
return api_utils.format_response('ValidateTemplate',
res['Error'])
res['Parameters'] = [format_validate_parameter(k, v)
for k, v in res['Parameters'].items()]
return api_utils.format_response('ValidateTemplate', res)

View File

@ -312,9 +312,19 @@ class EngineService(service.Service):
return {'Error': 'At least one Resources member must be defined.'}
for res in tmpl_resources.values():
if not res.get('Type'):
try:
if not res.get('Type'):
return {'Error':
'Every Resource object must '
'contain a Type member.'}
except AttributeError:
type_res = type(res)
if isinstance(res, unicode):
type_res = "string"
return {'Error':
'Every Resources object must contain a Type member.'}
'Resources must contain Resource. '
'Found a [%s] instead' % type_res}
ResourceClass = resource.get_class(res['Type'])
props = properties.Properties(ResourceClass.properties_schema,
res.get('Properties', {}))

View File

@ -1076,6 +1076,40 @@ class CfnStackControllerTest(HeatTestCase):
self.assertEqual(type(result),
exception.HeatInvalidParameterValueError)
def test_bad_resources_in_template(self):
# Format a dummy request
json_template = {
'template': {
'AWSTemplateFormatVersion': '2010-09-09',
'Resources': {
'Type': 'AWS: : EC2: : Instance',
},
}
}
params = {'Action': 'ValidateTemplate',
'TemplateBody': '%s' % json.dumps(json_template)}
response = {'Error': 'Resources must contain Resource. '
'Found a [string] instead'}
dummy_req = self._dummy_GET_request(params)
# Stub out the RPC call to the engine with a pre-canned response
self.m.StubOutWithMock(rpc, 'call')
rpc.call(dummy_req.context, self.topic,
{'namespace': None,
'method': 'validate_template',
'args': {'template': json_template},
'version': self.api_version}, None).AndReturn(response)
self.m.ReplayAll()
response = self.controller.validate_template(dummy_req)
expected = {'ValidateTemplateResponse':
{'ValidateTemplateResult':
'Resources must contain Resource. '
'Found a [string] instead'}}
self.assertEqual(expected, response)
self.m.VerifyAll()
def test_delete(self):
# Format a dummy request
stack_name = "wordpress"

View File

@ -211,6 +211,31 @@ test_template_findinmap_invalid = '''
}
'''
test_template_invalid_resources = '''
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Description" : "AWS CloudFormation Sample Template for xyz.",
"Parameters" : {
"InstanceType" : {
"Description" : "Defined instance type",
"Type" : "String",
"Default" : "node.ee",
"AllowedValues" : ["node.ee", "node.apache", "node.api"],
"ConstraintDescription" : "must be a valid instance type."
}
},
"Resources" : {
"Type" : "AWS::EC2::Instance",
"Metadata" : {
},
"Properties" : {
"ImageId" : { "Ref" : "centos-6.4-20130701-0" },
"InstanceType" : { "Ref" : "InstanceType" }
}
}
}
'''
test_template_invalid_property = '''
{
"AWSTemplateFormatVersion" : "2010-09-09",
@ -605,6 +630,18 @@ class validateTest(HeatTestCase):
res = dict(engine.validate_template(None, t))
self.assertEqual(res, {'Error': 'Unknown Property UnknownProperty'})
def test_invalid_resources(self):
t = template_format.parse(test_template_invalid_resources)
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({'Error': 'Resources must contain Resource. '
'Found a [string] instead'},
res)
def test_unimplemented_property(self):
t = template_format.parse(test_template_unimplemented_property)
self.m.StubOutWithMock(instances.Instance, 'nova')