From 62f6045f2ad778edfc6e5305283e23cddc050ebe Mon Sep 17 00:00:00 2001 From: huangtianhua Date: Wed, 14 Sep 2016 15:03:18 +0800 Subject: [PATCH] Return condition functions based on the filter param Add 'with_condition_func' filter param for API template-function-list, if the param set to true, the response will include the condition functions. Change-Id: Icdfbafbb98698373648ff2d78db3c45fe2b924ee Closes-Bug: #1625505 --- heat/api/openstack/v1/stacks.py | 10 +++++- heat/engine/service.py | 11 +++++-- heat/rpc/client.py | 13 +++++--- heat/tests/api/openstack_v1/test_stacks.py | 33 ++++++++++++++----- .../engine/service/test_service_engine.py | 2 +- heat/tests/test_engine_service.py | 21 +++++++++++- 6 files changed, 72 insertions(+), 18 deletions(-) diff --git a/heat/api/openstack/v1/stacks.py b/heat/api/openstack/v1/stacks.py index 39ebe64929..237f3e566a 100644 --- a/heat/api/openstack/v1/stacks.py +++ b/heat/api/openstack/v1/stacks.py @@ -653,10 +653,18 @@ class StackController(object): @util.policy_enforce def list_template_functions(self, req, template_version): """Returns a list of available functions in a given template.""" + if req.params.get('with_condition_func') is not None: + with_condition = self._extract_bool_param( + 'with_condition_func', + req.params.get('with_condition_func')) + else: + with_condition = False + return { 'template_functions': self.rpc_client.list_template_functions(req.context, - template_version) + template_version, + with_condition) } @util.policy_enforce diff --git a/heat/engine/service.py b/heat/engine/service.py index a370925d1f..dbf5c34819 100644 --- a/heat/engine/service.py +++ b/heat/engine/service.py @@ -303,7 +303,7 @@ class EngineService(service.Service): by the RPC caller. """ - RPC_API_VERSION = '1.34' + RPC_API_VERSION = '1.35' def __init__(self, host, topic): super(EngineService, self).__init__() @@ -1562,7 +1562,8 @@ class EngineService(service.Service): return versions - def list_template_functions(self, cnxt, template_version): + def list_template_functions(self, cnxt, template_version, + with_condition=False): mgr = templatem._get_template_extension_manager() try: tmpl_class = mgr[template_version] @@ -1570,8 +1571,12 @@ class EngineService(service.Service): raise exception.NotFound(_("Template with version %s not found") % template_version) + supported_funcs = tmpl_class.plugin.functions + if with_condition: + supported_funcs.update(tmpl_class.plugin.condition_functions) + functions = [] - for func_name, func in six.iteritems(tmpl_class.plugin.functions): + for func_name, func in six.iteritems(supported_funcs): if func is not hot_functions.Removed: if func.__doc__.split('\n')[0]: desc = func.__doc__.split('\n')[0].strip() diff --git a/heat/rpc/client.py b/heat/rpc/client.py index 7f539538d8..ad00570871 100644 --- a/heat/rpc/client.py +++ b/heat/rpc/client.py @@ -57,6 +57,7 @@ class EngineClient(object): 1.33 - Remove tenant_safe from list_stacks, count_stacks and list_software_configs 1.34 - Add migrate_convergence_1 call + 1.35 - Add with_condition to list_template_functions """ BASE_RPC_API_VERSION = '1.0' @@ -473,16 +474,20 @@ class EngineClient(object): return self.call(ctxt, self.make_msg('list_template_versions'), version='1.11') - def list_template_functions(self, ctxt, template_version): + def list_template_functions(self, ctxt, template_version, + with_condition=False): """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 + :param with_condition: return includes condition functions. """ - return self.call(ctxt, self.make_msg( - 'list_template_functions', template_version=template_version), - version='1.13') + return self.call(ctxt, + self.make_msg('list_template_functions', + template_version=template_version, + with_condition=with_condition), + version='1.35') def resource_schema(self, ctxt, type_name, with_description=False): """Get the schema for a resource type. diff --git a/heat/tests/api/openstack_v1/test_stacks.py b/heat/tests/api/openstack_v1/test_stacks.py index 0a32ccad6a..ed311b519d 100644 --- a/heat/tests/api/openstack_v1/test_stacks.py +++ b/heat/tests/api/openstack_v1/test_stacks.py @@ -2567,19 +2567,16 @@ class StackControllerTest(tools.ControllerTest, common.HeatTestCase): self.assertEqual({'template_versions': engine_response}, response) self.m.VerifyAll() - def test_list_template_functions(self, mock_enforce): + def _test_list_template_functions(self, mock_enforce, req, engine_response, + with_condition=False): 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" + 'list_template_functions', + {'template_version': 't1', 'with_condition': with_condition}), + version="1.35" ).AndReturn(engine_response) self.m.ReplayAll() response = self.controller.list_template_functions( @@ -2587,6 +2584,26 @@ class StackControllerTest(tools.ControllerTest, common.HeatTestCase): self.assertEqual({'template_functions': engine_response}, response) self.m.VerifyAll() + def test_list_template_functions(self, mock_enforce): + req = self._get('/template_versions/t1/functions') + engine_response = [ + {'functions': 'func1', 'description': 'desc1'}, + ] + + self._test_list_template_functions(mock_enforce, req, engine_response) + + def test_list_template_funcs_includes_condition_funcs(self, mock_enforce): + params = {'with_condition_func': 'true'} + req = self._get('/template_versions/t1/functions', params=params) + + engine_response = [ + {'functions': 'func1', 'description': 'desc1'}, + {'functions': 'condition_func', 'description': 'desc2'} + ] + + self._test_list_template_functions(mock_enforce, req, engine_response, + with_condition=True) + def test_resource_schema(self, mock_enforce): self._mock_enforce_setup(mock_enforce, 'resource_schema', True) req = self._get('/resource_types/ResourceWithProps') diff --git a/heat/tests/engine/service/test_service_engine.py b/heat/tests/engine/service/test_service_engine.py index ef022f135e..e98e3a92ee 100644 --- a/heat/tests/engine/service/test_service_engine.py +++ b/heat/tests/engine/service/test_service_engine.py @@ -40,7 +40,7 @@ class ServiceEngineTest(common.HeatTestCase): def test_make_sure_rpc_version(self): self.assertEqual( - '1.34', + '1.35', 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 ' diff --git a/heat/tests/test_engine_service.py b/heat/tests/test_engine_service.py index 793e37246b..cda7ed2e4a 100644 --- a/heat/tests/test_engine_service.py +++ b/heat/tests/test_engine_service.py @@ -905,10 +905,17 @@ class StackServiceTest(common.HeatTestCase): Dummy Func2 Long Description. """ + class DummyConditionFunc(object): + """Dummy Condition Func. + + Dummy Condition Func Long Description. + """ + plugin_mock = mock.Mock( functions={'dummy1': DummyFunc1, 'dummy2': DummyFunc2, - 'removed': hot_functions.Removed}) + 'removed': hot_functions.Removed}, + condition_functions={'condition_dummy': DummyConditionFunc}) dummy_tmpl = mock.Mock(plugin=plugin_mock) class DummyMgr(object): @@ -924,6 +931,18 @@ class StackServiceTest(common.HeatTestCase): self.assertEqual(sorted(expected, key=lambda k: k['functions']), sorted(functions, key=lambda k: k['functions'])) + # test with_condition + functions = self.eng.list_template_functions(self.ctx, 'dummytemplate', + with_condition=True) + expected = [{'functions': 'dummy1', + 'description': 'Dummy Func1.'}, + {'functions': 'dummy2', + 'description': 'Dummy Func2.'}, + {'functions': 'condition_dummy', + 'description': 'Dummy Condition Func.'}] + self.assertEqual(sorted(expected, key=lambda k: k['functions']), + sorted(functions, key=lambda k: k['functions'])) + @mock.patch('heat.engine.template._get_template_extension_manager') def test_list_template_functions_version_not_found(self, templ_mock): class DummyMgr(object):