Add rest endpoints for resource template generation.
Add api endpoints for generating a template based on a resource implementation. blueprint resource-template Change-Id: Iebebad70befd1df6cd8989538cbb61350a17bc23
This commit is contained in:
parent
87e02d79b8
commit
48fe2f04ba
|
@ -259,6 +259,7 @@ def map_remote_error(ex):
|
|||
'StackNotFound',
|
||||
'ResourceNotFound',
|
||||
'ResourceNotAvailable',
|
||||
'ResourceTypeNotFound',
|
||||
'PhysicalResourceNotFound',
|
||||
'WatchRuleNotFound',
|
||||
'StackValidationFailed',
|
||||
|
|
|
@ -57,6 +57,7 @@ class FaultWrapper(wsgi.Middleware):
|
|||
'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,
|
||||
|
|
|
@ -53,6 +53,10 @@ class API(wsgi.Router):
|
|||
"/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",
|
||||
|
|
|
@ -329,10 +329,14 @@ class StackController(object):
|
|||
"""
|
||||
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):
|
||||
|
|
|
@ -248,6 +248,10 @@ class ResourceNotFound(OpenstackException):
|
|||
"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.")
|
||||
|
||||
|
|
|
@ -383,6 +383,18 @@ class EngineService(service.Service):
|
|||
"""
|
||||
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):
|
||||
"""
|
||||
|
|
|
@ -160,6 +160,16 @@ class EngineClient(heat.openstack.common.rpc.proxy.RpcProxy):
|
|||
"""
|
||||
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.
|
||||
|
|
|
@ -1138,6 +1138,42 @@ class StackControllerTest(ControllerTest, HeatTestCase):
|
|||
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):
|
||||
|
||||
|
@ -1953,8 +1989,20 @@ class RoutesTest(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',
|
||||
|
|
|
@ -139,6 +139,9 @@ class EngineRpcAPITestCase(testtools.TestCase):
|
|||
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)
|
||||
|
|
Loading…
Reference in New Issue