Merge "Pass and use the environment in validate_template"
This commit is contained in:
commit
a264a16102
@ -346,7 +346,8 @@ class StackController(object):
|
||||
data = InstantiationData(body)
|
||||
|
||||
result = self.rpc_client.validate_template(req.context,
|
||||
data.template())
|
||||
data.template(),
|
||||
data.environment())
|
||||
|
||||
if 'Error' in result:
|
||||
raise exc.HTTPBadRequest(result['Error'])
|
||||
|
@ -583,13 +583,14 @@ class EngineService(service.Service):
|
||||
return dict(current_stack.identifier())
|
||||
|
||||
@request_context
|
||||
def validate_template(self, cnxt, template):
|
||||
def validate_template(self, cnxt, template, params=None):
|
||||
"""
|
||||
The validate_template method uses the stack parser to check
|
||||
the validity of a template.
|
||||
|
||||
:param cnxt: RPC context.
|
||||
:param template: Template of stack you want to create.
|
||||
:param params: Stack Input Params
|
||||
"""
|
||||
logger.info(_('validate_template'))
|
||||
if template is None:
|
||||
@ -608,6 +609,8 @@ class EngineService(service.Service):
|
||||
if not tmpl_resources:
|
||||
return {'Error': 'At least one Resources member must be defined.'}
|
||||
|
||||
env = environment.Environment(params)
|
||||
|
||||
for res in tmpl_resources.values():
|
||||
try:
|
||||
if not res.get('Type'):
|
||||
@ -622,7 +625,7 @@ class EngineService(service.Service):
|
||||
'Resources must contain Resource. '
|
||||
'Found a [%s] instead' % type_res}
|
||||
|
||||
ResourceClass = resource.get_class(res['Type'])
|
||||
ResourceClass = env.get_class(res['Type'])
|
||||
if ResourceClass == resources.template_resource.TemplateResource:
|
||||
# we can't validate a TemplateResource unless we instantiate
|
||||
# it as we need to download the template and convert the
|
||||
|
@ -153,16 +153,18 @@ class EngineClient(heat.openstack.common.rpc.proxy.RpcProxy):
|
||||
files=files,
|
||||
args=args))
|
||||
|
||||
def validate_template(self, ctxt, template):
|
||||
def validate_template(self, ctxt, template, params=None):
|
||||
"""
|
||||
The validate_template method uses the stack parser to check
|
||||
the validity of a template.
|
||||
|
||||
:param ctxt: RPC context.
|
||||
:param template: Template of stack you want to create.
|
||||
:param params: Stack Input Params/Environment
|
||||
"""
|
||||
return self.call(ctxt, self.make_msg('validate_template',
|
||||
template=template))
|
||||
template=template,
|
||||
params=params))
|
||||
|
||||
def authenticated_to_backend(self, ctxt):
|
||||
"""
|
||||
|
@ -1146,7 +1146,7 @@ class CfnStackControllerTest(HeatTestCase):
|
||||
rpc.call(dummy_req.context, self.topic,
|
||||
{'namespace': None,
|
||||
'method': 'validate_template',
|
||||
'args': {'template': json_template},
|
||||
'args': {'template': json_template, 'params': None},
|
||||
'version': self.api_version}, None).AndReturn(response)
|
||||
self.m.ReplayAll()
|
||||
|
||||
|
@ -1442,7 +1442,9 @@ class StackControllerTest(ControllerTest, HeatTestCase):
|
||||
rpc.call(req.context, self.topic,
|
||||
{'namespace': None,
|
||||
'method': 'validate_template',
|
||||
'args': {'template': template},
|
||||
'args': {'template': template,
|
||||
'params': {'parameters': {},
|
||||
'resource_registry': {}}},
|
||||
'version': self.api_version},
|
||||
None).AndReturn(engine_response)
|
||||
self.m.ReplayAll()
|
||||
@ -1464,7 +1466,9 @@ class StackControllerTest(ControllerTest, HeatTestCase):
|
||||
rpc.call(req.context, self.topic,
|
||||
{'namespace': None,
|
||||
'method': 'validate_template',
|
||||
'args': {'template': template},
|
||||
'args': {'template': template,
|
||||
'params': {'parameters': {},
|
||||
'resource_registry': {}}},
|
||||
'version': self.api_version},
|
||||
None).AndReturn({'Error': 'fubar'})
|
||||
self.m.ReplayAll()
|
||||
|
@ -142,7 +142,8 @@ class EngineRpcAPITestCase(testtools.TestCase):
|
||||
|
||||
def test_validate_template(self):
|
||||
self._test_engine_api('validate_template', 'call',
|
||||
template={u'Foo': u'bar'})
|
||||
template={u'Foo': u'bar'},
|
||||
params={u'Egg': u'spam'})
|
||||
|
||||
def test_list_resource_types(self):
|
||||
self._test_engine_api('list_resource_types', 'call',
|
||||
|
@ -804,7 +804,24 @@ class validateTest(HeatTestCase):
|
||||
self.m.ReplayAll()
|
||||
|
||||
engine = service.EngineService('a', 't')
|
||||
res = dict(engine.validate_template(None, t))
|
||||
res = dict(engine.validate_template(None, t, {}))
|
||||
self.assertEqual('test.', res['Description'])
|
||||
|
||||
def test_validate_with_environment(self):
|
||||
test_template = test_template_ref % 'WikiDatabase'
|
||||
test_template = test_template.replace('AWS::EC2::Instance',
|
||||
'My::Instance')
|
||||
t = template_format.parse(test_template)
|
||||
|
||||
self.m.StubOutWithMock(instances.Instance, 'nova')
|
||||
instances.Instance.nova().AndReturn(self.fc)
|
||||
self.m.StubOutWithMock(service.EngineListener, 'start')
|
||||
service.EngineListener.start().AndReturn(None)
|
||||
self.m.ReplayAll()
|
||||
|
||||
engine = service.EngineService('a', 't')
|
||||
params = {'resource_registry': {'My::Instance': 'AWS::EC2::Instance'}}
|
||||
res = dict(engine.validate_template(None, t, params))
|
||||
self.assertEqual('test.', res['Description'])
|
||||
|
||||
def test_validate_hot_valid(self):
|
||||
@ -821,7 +838,7 @@ class validateTest(HeatTestCase):
|
||||
self.m.ReplayAll()
|
||||
|
||||
engine = service.EngineService('a', 't')
|
||||
res = dict(engine.validate_template(None, t))
|
||||
res = dict(engine.validate_template(None, t, {}))
|
||||
self.assertEqual('test.', res['Description'])
|
||||
|
||||
def test_validate_ref_invalid(self):
|
||||
@ -832,7 +849,7 @@ class validateTest(HeatTestCase):
|
||||
self.m.ReplayAll()
|
||||
|
||||
engine = service.EngineService('a', 't')
|
||||
res = dict(engine.validate_template(None, t))
|
||||
res = dict(engine.validate_template(None, t, {}))
|
||||
self.assertNotEqual(res['Description'], 'Successfully validated')
|
||||
|
||||
def test_validate_findinmap_valid(self):
|
||||
@ -843,7 +860,7 @@ class validateTest(HeatTestCase):
|
||||
self.m.ReplayAll()
|
||||
|
||||
engine = service.EngineService('a', 't')
|
||||
res = dict(engine.validate_template(None, t))
|
||||
res = dict(engine.validate_template(None, t, {}))
|
||||
self.assertEqual('test.', res['Description'])
|
||||
|
||||
def test_validate_findinmap_invalid(self):
|
||||
@ -854,7 +871,7 @@ class validateTest(HeatTestCase):
|
||||
self.m.ReplayAll()
|
||||
|
||||
engine = service.EngineService('a', 't')
|
||||
res = dict(engine.validate_template(None, t))
|
||||
res = dict(engine.validate_template(None, t, {}))
|
||||
self.assertNotEqual(res['Description'], 'Successfully validated')
|
||||
|
||||
def test_validate_parameters(self):
|
||||
@ -865,7 +882,7 @@ class validateTest(HeatTestCase):
|
||||
self.m.ReplayAll()
|
||||
|
||||
engine = service.EngineService('a', 't')
|
||||
res = dict(engine.validate_template(None, t))
|
||||
res = dict(engine.validate_template(None, t, {}))
|
||||
# Note: the assertion below does not expect a CFN dict of the parameter
|
||||
# but a dict of the parameters.Schema object.
|
||||
# For API CFN backward compatibility, formating to CFN is done in the
|
||||
@ -885,7 +902,7 @@ class validateTest(HeatTestCase):
|
||||
self.m.ReplayAll()
|
||||
|
||||
engine = service.EngineService('a', 't')
|
||||
res = dict(engine.validate_template(None, t))
|
||||
res = dict(engine.validate_template(None, t, {}))
|
||||
parameters = res['Parameters']
|
||||
|
||||
expected = {'KeyName': {
|
||||
@ -903,7 +920,7 @@ class validateTest(HeatTestCase):
|
||||
self.m.ReplayAll()
|
||||
|
||||
engine = service.EngineService('a', 't')
|
||||
res = dict(engine.validate_template(None, t))
|
||||
res = dict(engine.validate_template(None, t, {}))
|
||||
parameters = res['Parameters']
|
||||
|
||||
expected = {'KeyName': {
|
||||
@ -921,7 +938,7 @@ class validateTest(HeatTestCase):
|
||||
self.m.ReplayAll()
|
||||
|
||||
engine = service.EngineService('a', 't')
|
||||
res = dict(engine.validate_template(None, t))
|
||||
res = dict(engine.validate_template(None, t, {}))
|
||||
parameters = res['Parameters']
|
||||
|
||||
expected = {'KeyName': {
|
||||
@ -939,7 +956,7 @@ class validateTest(HeatTestCase):
|
||||
self.m.ReplayAll()
|
||||
|
||||
engine = service.EngineService('a', 't')
|
||||
res = dict(engine.validate_template(None, t))
|
||||
res = dict(engine.validate_template(None, t, {}))
|
||||
self.assertEqual({'Error': 'Unknown Property UnknownProperty'}, res)
|
||||
|
||||
def test_invalid_resources(self):
|
||||
@ -949,7 +966,7 @@ class validateTest(HeatTestCase):
|
||||
self.m.ReplayAll()
|
||||
|
||||
engine = service.EngineService('a', 't')
|
||||
res = dict(engine.validate_template(None, t))
|
||||
res = dict(engine.validate_template(None, t, {}))
|
||||
self.assertEqual({'Error': 'Resources must contain Resource. '
|
||||
'Found a [string] instead'},
|
||||
res)
|
||||
@ -1011,7 +1028,7 @@ class validateTest(HeatTestCase):
|
||||
self.m.ReplayAll()
|
||||
|
||||
engine = service.EngineService('a', 't')
|
||||
res = dict(engine.validate_template(None, t))
|
||||
res = dict(engine.validate_template(None, t, {}))
|
||||
self.assertEqual(
|
||||
{'Error': 'Property SourceDestCheck not implemented yet'},
|
||||
res)
|
||||
@ -1023,7 +1040,7 @@ class validateTest(HeatTestCase):
|
||||
self.m.ReplayAll()
|
||||
|
||||
engine = service.EngineService('a', 't')
|
||||
res = dict(engine.validate_template(None, t))
|
||||
res = dict(engine.validate_template(None, t, {}))
|
||||
self.assertEqual({'Error': 'Invalid DeletionPolicy Destroy'}, res)
|
||||
|
||||
def test_snapshot_deletion_policy(self):
|
||||
@ -1033,7 +1050,7 @@ class validateTest(HeatTestCase):
|
||||
self.m.ReplayAll()
|
||||
|
||||
engine = service.EngineService('a', 't')
|
||||
res = dict(engine.validate_template(None, t))
|
||||
res = dict(engine.validate_template(None, t, {}))
|
||||
self.assertEqual(
|
||||
{'Error': 'Snapshot DeletionPolicy not supported'}, res)
|
||||
|
||||
@ -1046,7 +1063,7 @@ class validateTest(HeatTestCase):
|
||||
self.m.ReplayAll()
|
||||
|
||||
engine = service.EngineService('a', 't')
|
||||
res = dict(engine.validate_template(None, t))
|
||||
res = dict(engine.validate_template(None, t, {}))
|
||||
self.assertEqual({'Description': u'test.', 'Parameters': {}}, res)
|
||||
|
||||
def test_validate_template_without_resources(self):
|
||||
@ -1059,7 +1076,7 @@ class validateTest(HeatTestCase):
|
||||
self.m.ReplayAll()
|
||||
|
||||
engine = service.EngineService('a', 't')
|
||||
res = dict(engine.validate_template(None, hot_tpl))
|
||||
res = dict(engine.validate_template(None, hot_tpl, {}))
|
||||
self.assertEqual({'Error': 'At least one Resources member '
|
||||
'must be defined.'}, res)
|
||||
|
||||
@ -1084,7 +1101,7 @@ class validateTest(HeatTestCase):
|
||||
self.m.ReplayAll()
|
||||
|
||||
engine = service.EngineService('a', 't')
|
||||
res = dict(engine.validate_template(None, hot_tpl))
|
||||
res = dict(engine.validate_template(None, hot_tpl, {}))
|
||||
self.assertEqual({'Error': 'u\'"Type" is not a valid keyword '
|
||||
'inside a resource definition\''}, res)
|
||||
|
||||
@ -1109,7 +1126,7 @@ class validateTest(HeatTestCase):
|
||||
self.m.ReplayAll()
|
||||
|
||||
engine = service.EngineService('a', 't')
|
||||
res = dict(engine.validate_template(None, hot_tpl))
|
||||
res = dict(engine.validate_template(None, hot_tpl, {}))
|
||||
self.assertEqual({'Error': 'u\'"Properties" is not a valid keyword '
|
||||
'inside a resource definition\''}, res)
|
||||
|
||||
@ -1134,7 +1151,7 @@ class validateTest(HeatTestCase):
|
||||
self.m.ReplayAll()
|
||||
|
||||
engine = service.EngineService('a', 't')
|
||||
res = dict(engine.validate_template(None, hot_tpl))
|
||||
res = dict(engine.validate_template(None, hot_tpl, {}))
|
||||
self.assertEqual({'Error': 'u\'"Metadata" is not a valid keyword '
|
||||
'inside a resource definition\''}, res)
|
||||
|
||||
@ -1159,7 +1176,7 @@ class validateTest(HeatTestCase):
|
||||
self.m.ReplayAll()
|
||||
|
||||
engine = service.EngineService('a', 't')
|
||||
res = dict(engine.validate_template(None, hot_tpl))
|
||||
res = dict(engine.validate_template(None, hot_tpl, {}))
|
||||
self.assertEqual({'Error': 'u\'"DependsOn" is not a valid keyword '
|
||||
'inside a resource definition\''}, res)
|
||||
|
||||
@ -1184,7 +1201,7 @@ class validateTest(HeatTestCase):
|
||||
self.m.ReplayAll()
|
||||
|
||||
engine = service.EngineService('a', 't')
|
||||
res = dict(engine.validate_template(None, hot_tpl))
|
||||
res = dict(engine.validate_template(None, hot_tpl, {}))
|
||||
self.assertEqual({'Error': 'u\'"DeletionPolicy" is not a valid '
|
||||
'keyword inside a resource definition\''},
|
||||
res)
|
||||
@ -1210,7 +1227,7 @@ class validateTest(HeatTestCase):
|
||||
self.m.ReplayAll()
|
||||
|
||||
engine = service.EngineService('a', 't')
|
||||
res = dict(engine.validate_template(None, hot_tpl))
|
||||
res = dict(engine.validate_template(None, hot_tpl, {}))
|
||||
self.assertEqual({'Error': 'u\'"UpdatePolicy" is not a valid '
|
||||
'keyword inside a resource definition\''},
|
||||
res)
|
||||
|
Loading…
Reference in New Issue
Block a user