Merge "Add template-function-list"

This commit is contained in:
Jenkins 2015-07-13 02:14:34 +00:00 committed by Gerrit Code Review
commit 3510b4fcd7
8 changed files with 107 additions and 2 deletions

View File

@ -46,6 +46,7 @@
"stacks:index": "rule:deny_stack_user", "stacks:index": "rule:deny_stack_user",
"stacks:list_resource_types": "rule:deny_stack_user", "stacks:list_resource_types": "rule:deny_stack_user",
"stacks:list_template_versions": "rule:deny_stack_user", "stacks:list_template_versions": "rule:deny_stack_user",
"stacks:list_template_functions": "rule:deny_stack_user",
"stacks:lookup": "", "stacks:lookup": "",
"stacks:preview": "rule:deny_stack_user", "stacks:preview": "rule:deny_stack_user",
"stacks:resource_schema": "rule:deny_stack_user", "stacks:resource_schema": "rule:deny_stack_user",

View File

@ -119,6 +119,14 @@ class API(wsgi.Router):
'method': 'GET' 'method': 'GET'
}, },
{
'name': 'template_functions',
'url': '/template_versions/{template_version}'
'/functions',
'action': 'list_template_functions',
'method': 'GET'
},
# Stack collection # Stack collection
{ {
'name': 'stack_index', 'name': 'stack_index',

View File

@ -525,6 +525,17 @@ class StackController(object):
self.rpc_client.list_template_versions(req.context) self.rpc_client.list_template_versions(req.context)
} }
@util.policy_enforce
def list_template_functions(self, req, template_version):
"""
Returns a list of available functions in a given template
"""
return {
'template_functions':
self.rpc_client.list_template_functions(req.context,
template_version)
}
@util.policy_enforce @util.policy_enforce
def resource_schema(self, req, type_name): def resource_schema(self, req, type_name):
""" """

View File

@ -44,6 +44,7 @@ from heat.engine.cfn import template as cfntemplate
from heat.engine import clients from heat.engine import clients
from heat.engine import environment from heat.engine import environment
from heat.engine import event as evt from heat.engine import event as evt
from heat.engine.hot import functions as hot_functions
from heat.engine import parameter_groups from heat.engine import parameter_groups
from heat.engine import properties from heat.engine import properties
from heat.engine import resources from heat.engine import resources
@ -267,7 +268,7 @@ class EngineService(service.Service):
by the RPC caller. by the RPC caller.
""" """
RPC_API_VERSION = '1.12' RPC_API_VERSION = '1.13'
def __init__(self, host, topic, manager=None): def __init__(self, host, topic, manager=None):
super(EngineService, self).__init__() super(EngineService, self).__init__()
@ -1037,6 +1038,22 @@ class EngineService(service.Service):
versions.append({'version': t[0], 'type': 'hot'}) versions.append({'version': t[0], 'type': 'hot'})
return versions return versions
def list_template_functions(self, cnxt, template_version):
mgr = templatem._get_template_extension_manager()
tmpl_class = mgr[template_version]
functions = []
for func_name, func in six.iteritems(tmpl_class.plugin.functions):
if func is not hot_functions.Removed:
if func.__doc__.split('\n')[0]:
desc = func.__doc__.split('\n')[0].strip()
else:
desc = func.__doc__.split('\n')[1].strip()
functions.append(
{'functions': func_name,
'description': desc}
)
return functions
def resource_schema(self, cnxt, type_name): def resource_schema(self, cnxt, type_name):
""" """
Return the schema of the specified type. Return the schema of the specified type.

View File

@ -33,6 +33,7 @@ class EngineClient(object):
1.10 - Add support for software config list 1.10 - Add support for software config list
1.11 - Add support for template versions list 1.11 - Add support for template versions list
1.12 - Add with_detail option for stack resources list 1.12 - Add with_detail option for stack resources list
1.13 - Add support for template functions list
''' '''
BASE_RPC_API_VERSION = '1.0' BASE_RPC_API_VERSION = '1.0'
@ -338,6 +339,18 @@ class EngineClient(object):
return self.call(ctxt, self.make_msg('list_template_versions'), return self.call(ctxt, self.make_msg('list_template_versions'),
version='1.11') version='1.11')
def list_template_functions(self, ctxt, template_version):
"""
Get a list of available functions in a given template
:param ctxt: RPC context
:param template_name : name of the template which function list you
want to get
"""
return self.call(ctxt, self.make_msg(
'list_template_functions', template_version=template_version),
version='1.13')
def resource_schema(self, ctxt, type_name): def resource_schema(self, ctxt, type_name):
""" """
Get the schema for a resource type. Get the schema for a resource type.

View File

@ -2160,6 +2160,26 @@ class StackControllerTest(ControllerTest, common.HeatTestCase):
self.assertEqual({'template_versions': engine_response}, response) self.assertEqual({'template_versions': engine_response}, response)
self.m.VerifyAll() self.m.VerifyAll()
def test_list_template_functions(self, mock_enforce):
self._mock_enforce_setup(mock_enforce, 'list_template_functions', True)
req = self._get('/template_versions/t1/functions')
engine_response = [
{'functions': 'func1', 'description': 'desc1'},
]
self.m.StubOutWithMock(rpc_client.EngineClient, 'call')
rpc_client.EngineClient.call(
req.context, (
'list_template_functions', {'template_version': 't1'}),
version="1.13"
).AndReturn(engine_response)
self.m.ReplayAll()
response = self.controller.list_template_functions(
req, tenant_id=self.tenant, template_version='t1')
self.assertEqual({'template_functions': engine_response}, response)
self.m.VerifyAll()
def test_resource_schema(self, mock_enforce): def test_resource_schema(self, mock_enforce):
self._mock_enforce_setup(mock_enforce, 'resource_schema', True) self._mock_enforce_setup(mock_enforce, 'resource_schema', True)
req = self._get('/resource_types/ResourceWithProps') req = self._get('/resource_types/ResourceWithProps')

View File

@ -39,7 +39,7 @@ class ServiceEngineTest(common.HeatTestCase):
def test_make_sure_rpc_version(self): def test_make_sure_rpc_version(self):
self.assertEqual( self.assertEqual(
'1.12', '1.13',
service.EngineService.RPC_API_VERSION, service.EngineService.RPC_API_VERSION,
('RPC version is changed, please update this test to new version ' ('RPC version is changed, please update this test to new version '
'and make sure additional test cases are added for RPC APIs ' 'and make sure additional test cases are added for RPC APIs '

View File

@ -30,6 +30,7 @@ from heat.common import template_format
from heat.engine.cfn import template as cfntemplate from heat.engine.cfn import template as cfntemplate
from heat.engine import dependencies from heat.engine import dependencies
from heat.engine import environment from heat.engine import environment
from heat.engine.hot import functions as hot_functions
from heat.engine.hot import template as hottemplate from heat.engine.hot import template as hottemplate
from heat.engine import resource as res from heat.engine import resource as res
from heat.engine import service from heat.engine import service
@ -2013,6 +2014,40 @@ class StackServiceTest(common.HeatTestCase):
{'version': 'c.d', 'type': 'hot'}] {'version': 'c.d', 'type': 'hot'}]
self.assertEqual(expected, templates) self.assertEqual(expected, templates)
@mock.patch('heat.engine.template._get_template_extension_manager')
def test_list_template_functions(self, templ_mock):
class DummyFunc1(object):
"""
Dummy Func1
Dummy Func1 Long Description
"""
class DummyFunc2(object):
"""Dummy Func2
Dummy Func2 Long Description
"""
plugin_mock = mock.Mock(
functions={'dummy1': DummyFunc1,
'dummy2': DummyFunc2,
'removed': hot_functions.Removed})
dummy_tmpl = mock.Mock(plugin=plugin_mock)
class DummyMgr(object):
def __getitem__(self, item):
return dummy_tmpl
templ_mock.return_value = DummyMgr()
functions = self.eng.list_template_functions(self.ctx, 'dummytemplate')
expected = [{'functions': 'dummy1',
'description': 'Dummy Func1'},
{'functions': 'dummy2',
'description': 'Dummy Func2'}]
self.assertEqual(sorted(expected), sorted(functions))
@mock.patch.object(res.Resource, 'is_service_available') @mock.patch.object(res.Resource, 'is_service_available')
def test_list_resource_types_unavailable( def test_list_resource_types_unavailable(
self, self,