Browse Source

Add template-function-list

APIImpact
DOCImpact

Implements bp: template-function-list
Change-Id: I51fc9c7acc30ba46ec7d550df5cb3d85562c49d2
changes/55/195055/4
Oleksii Chuprykov 7 years ago
parent
commit
08608f5002
  1. 1
      etc/heat/policy.json
  2. 8
      heat/api/openstack/v1/__init__.py
  3. 11
      heat/api/openstack/v1/stacks.py
  4. 19
      heat/engine/service.py
  5. 13
      heat/rpc/client.py
  6. 20
      heat/tests/api/openstack/test_api_openstack_v1.py
  7. 2
      heat/tests/engine/test_service_engine.py
  8. 35
      heat/tests/test_engine_service.py

1
etc/heat/policy.json

@ -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",

8
heat/api/openstack/v1/__init__.py

@ -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',

11
heat/api/openstack/v1/stacks.py

@ -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):
"""

19
heat/engine/service.py

@ -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.

13
heat/rpc/client.py

@ -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.

20
heat/tests/api/openstack/test_api_openstack_v1.py

@ -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')

2
heat/tests/engine/test_service_engine.py

@ -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 '

35
heat/tests/test_engine_service.py

@ -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…
Cancel
Save