Merge "Add template-function-list"
This commit is contained in:
commit
3510b4fcd7
|
@ -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",
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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')
|
||||||
|
|
|
@ -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 '
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue