'StackNotFound',
'ResourceNotFound',
'ResourceNotAvailable',
+ 'ResourceTypeNotFound',
'PhysicalResourceNotFound',
'WatchRuleNotFound',
'StackValidationFailed',
'ValueError': webob.exc.HTTPBadRequest,
'StackNotFound': webob.exc.HTTPNotFound,
'ResourceNotFound': webob.exc.HTTPNotFound,
+ 'ResourceTypeNotFound': webob.exc.HTTPNotFound,
'ResourceNotAvailable': webob.exc.HTTPNotFound,
'PhysicalResourceNotFound': webob.exc.HTTPNotFound,
'InvalidTenant': webob.exc.HTTPForbidden,
"/resource_types",
action="list_resource_types",
conditions={'method': 'GET'})
+ stack_mapper.connect("generate_template",
+ "/resource_types/{type_name}/template",
+ action="generate_template",
+ conditions={'method': 'GET'})
# Stack collection
stack_mapper.connect("stack_index",
"""
Returns a list of valid resource types that may be used in a template.
"""
+ return {'resource_types': self.engine.list_resource_types(req.context)}
- types = self.engine.list_resource_types(req.context)
-
- return {'resource_types': types}
+ @util.tenant_local
+ def generate_template(self, req, type_name):
+ """
+ Generates a template based on the specified type.
+ """
+ return self.engine.generate_template(req.context, type_name)
class StackSerializer(wsgi.JSONResponseSerializer):
"in Stack %(stack_name)s.")
+class ResourceTypeNotFound(OpenstackException):
+ message = _("The Resource Type (%(type_name)s) could not be found.")
+
+
class ResourceNotAvailable(OpenstackException):
message = _("The Resource (%(resource_name)s) is not available.")
"""
return list(resource.get_types())
+ def generate_template(self, cnxt, type_name):
+ """
+ Generate a template based on the specified type.
+ arg1 -> RPC context.
+ arg2 -> Name of the resource type to generate a template for.
+ """
+ try:
+ return \
+ resource.get_class(type_name).resource_to_template(type_name)
+ except exception.StackValidationFailed:
+ raise exception.ResourceTypeNotFound(type_name=type_name)
+
@request_context
def list_events(self, cnxt, stack_identity):
"""
"""
return self.call(ctxt, self.make_msg('list_resource_types'))
+ def generate_template(self, ctxt, type_name):
+ """
+ Generate a template based on the specified type.
+
+ :param ctxt: RPC context.
+ :param type_name: The resource type name to generate a template for.
+ """
+ return self.call(ctxt, self.make_msg('generate_template',
+ type_name=type_name))
+
def list_events(self, ctxt, stack_identity):
"""
The list_events method lists all events associated with a given stack.
self.assertEqual(resp.json['error']['type'], 'ServerError')
self.m.VerifyAll()
+ def test_generate_template(self):
+
+ req = self._get('/resource_types/TEST_TYPE/template')
+
+ engine_response = {'Type': 'TEST_TYPE'}
+
+ self.m.StubOutWithMock(rpc, 'call')
+ rpc.call(req.context, self.topic,
+ {'namespace': None,
+ 'method': 'generate_template',
+ 'args': {'type_name': 'TEST_TYPE'},
+ 'version': self.api_version},
+ None).AndReturn(engine_response)
+ self.m.ReplayAll()
+ self.controller.generate_template(req, tenant_id=self.tenant,
+ type_name='TEST_TYPE')
+ self.m.VerifyAll()
+
+ def test_generate_template_not_found(self):
+ req = self._get('/resource_types/NOT_FOUND/template')
+ self.m.StubOutWithMock(rpc, 'call')
+ rpc.call(req.context, self.topic,
+ {'namespace': None,
+ 'method': 'generate_template',
+ 'args': {'type_name': 'NOT_FOUND'},
+ 'version': self.api_version},
+ None).AndRaise(remote_error(heat_exc.ResourceTypeNotFound))
+ self.m.ReplayAll()
+ resp = request_with_middleware(fault.FaultWrapper,
+ self.controller.generate_template,
+ req, tenant_id=self.tenant,
+ type_name='NOT_FOUND')
+ self.assertEqual(resp.json['code'], 404)
+ self.assertEqual(resp.json['error']['type'], 'ResourceTypeNotFound')
+ self.m.VerifyAll()
+
class StackSerializerTest(HeatTestCase):
'list_resource_types',
'StackController',
{
- 'tenant_id': 'aaaa'
+ 'tenant_id': 'aaaa',
+ })
+
+ self.assertRoute(
+ self.m,
+ '/aaaa/resource_types/test_type/template',
+ 'GET',
+ 'generate_template',
+ 'StackController',
+ {
+ 'tenant_id': 'aaaa',
+ 'type_name': 'test_type'
})
+
self.assertRoute(
self.m,
'/aaaa/validate',
self._test_engine_api('list_stack_resources', 'call',
stack_identity=self.identity)
+ def test_generate_template(self):
+ self._test_engine_api('generate_template', 'call', type_name="TYPE")
+
def test_stack_suspend(self):
self._test_engine_api('stack_suspend', 'call',
stack_identity=self.identity)