Add template-function-list
APIImpact DOCImpact Implements bp: template-function-list Change-Id: I51fc9c7acc30ba46ec7d550df5cb3d85562c49d2
This commit is contained in:
parent
8dd3d7888a
commit
08608f5002
@ -46,6 +46,7 @@
|
||||
"stacks:index": "rule:deny_stack_user",
|
||||
"stacks:list_resource_types": "rule:deny_stack_user",
|
||||
"stacks:list_template_versions": "rule:deny_stack_user",
|
||||
"stacks:list_template_functions": "rule:deny_stack_user",
|
||||
"stacks:lookup": "",
|
||||
"stacks:preview": "rule:deny_stack_user",
|
||||
"stacks:resource_schema": "rule:deny_stack_user",
|
||||
|
@ -119,6 +119,14 @@ class API(wsgi.Router):
|
||||
'method': 'GET'
|
||||
},
|
||||
|
||||
{
|
||||
'name': 'template_functions',
|
||||
'url': '/template_versions/{template_version}'
|
||||
'/functions',
|
||||
'action': 'list_template_functions',
|
||||
'method': 'GET'
|
||||
},
|
||||
|
||||
# Stack collection
|
||||
{
|
||||
'name': 'stack_index',
|
||||
|
@ -527,6 +527,17 @@ class StackController(object):
|
||||
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
|
||||
def resource_schema(self, req, type_name):
|
||||
"""
|
||||
|
@ -44,6 +44,7 @@ from heat.engine.cfn import template as cfntemplate
|
||||
from heat.engine import clients
|
||||
from heat.engine import environment
|
||||
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 properties
|
||||
from heat.engine import resources
|
||||
@ -267,7 +268,7 @@ class EngineService(service.Service):
|
||||
by the RPC caller.
|
||||
"""
|
||||
|
||||
RPC_API_VERSION = '1.12'
|
||||
RPC_API_VERSION = '1.13'
|
||||
|
||||
def __init__(self, host, topic, manager=None):
|
||||
super(EngineService, self).__init__()
|
||||
@ -1037,6 +1038,22 @@ class EngineService(service.Service):
|
||||
versions.append({'version': t[0], 'type': 'hot'})
|
||||
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):
|
||||
"""
|
||||
Return the schema of the specified type.
|
||||
|
@ -33,6 +33,7 @@ class EngineClient(object):
|
||||
1.10 - Add support for software config list
|
||||
1.11 - Add support for template versions 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'
|
||||
@ -338,6 +339,18 @@ class EngineClient(object):
|
||||
return self.call(ctxt, self.make_msg('list_template_versions'),
|
||||
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):
|
||||
"""
|
||||
Get the schema for a resource type.
|
||||
|
@ -2041,6 +2041,26 @@ class StackControllerTest(ControllerTest, common.HeatTestCase):
|
||||
self.assertEqual({'template_versions': engine_response}, response)
|
||||
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):
|
||||
self._mock_enforce_setup(mock_enforce, 'resource_schema', True)
|
||||
req = self._get('/resource_types/ResourceWithProps')
|
||||
|
@ -39,7 +39,7 @@ class ServiceEngineTest(common.HeatTestCase):
|
||||
|
||||
def test_make_sure_rpc_version(self):
|
||||
self.assertEqual(
|
||||
'1.12',
|
||||
'1.13',
|
||||
service.EngineService.RPC_API_VERSION,
|
||||
('RPC version is changed, please update this test to new version '
|
||||
'and make sure additional test cases are added for RPC APIs '
|
||||
|
@ -30,6 +30,7 @@ from heat.common import template_format
|
||||
from heat.engine.cfn import template as cfntemplate
|
||||
from heat.engine import dependencies
|
||||
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 import resource as res
|
||||
from heat.engine.resources.aws.ec2 import instance as instances
|
||||
@ -2227,6 +2228,40 @@ class StackServiceTest(common.HeatTestCase):
|
||||
{'version': 'c.d', 'type': 'hot'}]
|
||||
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')
|
||||
def test_list_resource_types_unavailable(
|
||||
self,
|
||||
|
Loading…
Reference in New Issue
Block a user