diff --git a/heat/api/openstack/v1/stacks.py b/heat/api/openstack/v1/stacks.py index 6d57dc3c12..781b379845 100644 --- a/heat/api/openstack/v1/stacks.py +++ b/heat/api/openstack/v1/stacks.py @@ -560,7 +560,8 @@ class StackController(object): data = InstantiationData(body) - whitelist = {'show_nested': util.PARAM_TYPE_SINGLE} + whitelist = {'show_nested': util.PARAM_TYPE_SINGLE, + 'ignore_errors': util.PARAM_TYPE_SINGLE} params = util.get_allowed_params(req.params, whitelist) show_nested = False @@ -569,13 +570,19 @@ class StackController(object): params[p_name] = self._extract_bool_param(p_name, params[p_name]) show_nested = params[p_name] + if rpc_api.PARAM_IGNORE_ERRORS in params: + ignorable_errors = params[rpc_api.PARAM_IGNORE_ERRORS].split(',') + else: + ignorable_errors = None + result = self.rpc_client.validate_template( req.context, data.template(), data.environment(), files=data.files(), environment_files=data.environment_files(), - show_nested=show_nested) + show_nested=show_nested, + ignorable_errors=ignorable_errors) if 'Error' in result: raise exc.HTTPBadRequest(result['Error']) diff --git a/heat/rpc/api.py b/heat/rpc/api.py index 9e8ebd0188..fbb6af27ee 100644 --- a/heat/rpc/api.py +++ b/heat/rpc/api.py @@ -20,14 +20,14 @@ PARAM_KEYS = ( PARAM_CLEAR_PARAMETERS, PARAM_GLOBAL_TENANT, PARAM_LIMIT, PARAM_NESTED_DEPTH, PARAM_TAGS, PARAM_SHOW_HIDDEN, PARAM_TAGS_ANY, PARAM_NOT_TAGS, PARAM_NOT_TAGS_ANY, TEMPLATE_TYPE, PARAM_WITH_DETAIL, - RESOLVE_OUTPUTS + RESOLVE_OUTPUTS, PARAM_IGNORE_ERRORS ) = ( 'timeout_mins', 'disable_rollback', 'adopt_stack_data', 'show_deleted', 'show_nested', 'existing', 'clear_parameters', 'global_tenant', 'limit', 'nested_depth', 'tags', 'show_hidden', 'tags_any', 'not_tags', 'not_tags_any', 'template_type', 'with_detail', - 'resolve_outputs', + 'resolve_outputs', 'ignore_errors' ) STACK_KEYS = ( diff --git a/heat/rpc/client.py b/heat/rpc/client.py index 2efdef3c07..3b37f9c881 100644 --- a/heat/rpc/client.py +++ b/heat/rpc/client.py @@ -42,6 +42,7 @@ class EngineClient(object): 1.21 - Add deployment_id to create_software_deployment 1.22 - Add support for stack export 1.23 - Add environment_files to create/update/preview/validate + 1.24 - Adds ignorable_errors to validate_template """ BASE_RPC_API_VERSION = '1.0' @@ -318,7 +319,8 @@ class EngineClient(object): version='1.23') def validate_template(self, ctxt, template, params=None, files=None, - environment_files=None, show_nested=False): + environment_files=None, show_nested=False, + ignorable_errors=None): """Uses the stack parser to check the validity of a template. :param ctxt: RPC context. @@ -328,15 +330,18 @@ class EngineClient(object): :param environment_files: ordered list of environment file names included in the files dict :param show_nested: if True nested templates will be validated + :param ignorable_errors: List of error_code to be ignored as part of + validation """ - return self.call(ctxt, - self.make_msg('validate_template', - template=template, - params=params, - files=files, - environment_files=environment_files, - show_nested=show_nested), - version='1.23') + return self.call(ctxt, self.make_msg( + 'validate_template', + template=template, + params=params, + files=files, + show_nested=show_nested, + environment_files=environment_files, + ignorable_errors=ignorable_errors), + version='1.24') def authenticated_to_backend(self, ctxt): """Validate the credentials in the RPC context. diff --git a/heat/tests/api/cfn/test_api_cfn_v1.py b/heat/tests/api/cfn/test_api_cfn_v1.py index 521d6b0469..d341c00c6b 100644 --- a/heat/tests/api/cfn/test_api_cfn_v1.py +++ b/heat/tests/api/cfn/test_api_cfn_v1.py @@ -1100,8 +1100,9 @@ class CfnStackControllerTest(common.HeatTestCase): dummy_req.context, ('validate_template', {'template': json_template, 'params': None, 'files': None, 'environment_files': None, - 'show_nested': False}), - version='1.23' + 'show_nested': False, + 'ignorable_errors': None}), + version='1.24' ).AndReturn(response) self.m.ReplayAll() diff --git a/heat/tests/api/openstack_v1/test_stacks.py b/heat/tests/api/openstack_v1/test_stacks.py index 313354bb1b..b68c040cb3 100644 --- a/heat/tests/api/openstack_v1/test_stacks.py +++ b/heat/tests/api/openstack_v1/test_stacks.py @@ -2248,8 +2248,9 @@ class StackControllerTest(tools.ControllerTest, common.HeatTestCase): 'resource_registry': {}}, 'files': {}, 'environment_files': None, - 'show_nested': False}), - version='1.23' + 'show_nested': False, + 'ignorable_errors': None}), + version='1.24' ).AndReturn(engine_response) self.m.ReplayAll() @@ -2278,8 +2279,9 @@ class StackControllerTest(tools.ControllerTest, common.HeatTestCase): 'resource_registry': {}}, 'files': {}, 'environment_files': None, - 'show_nested': False}), - version='1.23' + 'show_nested': False, + 'ignorable_errors': None}), + version='1.24' ).AndReturn({'Error': 'fubar'}) self.m.ReplayAll() diff --git a/heat/tests/test_rpc_client.py b/heat/tests/test_rpc_client.py index cf1f6e1dfe..f3bd7da607 100644 --- a/heat/tests/test_rpc_client.py +++ b/heat/tests/test_rpc_client.py @@ -204,7 +204,9 @@ class EngineRpcAPITestCase(common.HeatTestCase): params={u'Egg': u'spam'}, files=None, environment_files=['foo.yaml'], - show_nested=False) + ignorable_errors=None, + show_nested=False, + version='1.24') def test_list_resource_types(self): self._test_engine_api('list_resource_types',