diff --git a/heat/engine/service.py b/heat/engine/service.py index 000ec6759b..67e1c4fa63 100644 --- a/heat/engine/service.py +++ b/heat/engine/service.py @@ -835,7 +835,7 @@ class EngineService(service.Service): # stack definition. If PARAM_EXISTING is specified, we merge # any environment provided into the existing one and attempt # to use the existing stack template, if one is not provided. - if args.get(rpc_api.PARAM_EXISTING, None): + if args.get(rpc_api.PARAM_EXISTING): existing_env = current_stack.env.user_env_as_dict() existing_params = existing_env[env_fmt.PARAMETERS] clear_params = set(args.get(rpc_api.PARAM_CLEAR_PARAMETERS, [])) @@ -872,12 +872,14 @@ class EngineService(service.Service): 'previous template stored')) msg = _('PATCH update to non-COMPLETE stack') raise exception.NotSupported(feature=msg) + tmpl = templatem.Template(new_template, files=new_files, + env=new_env) + for key in list(new_env.params.keys()): + if key not in tmpl.param_schemata(): + new_env.params.pop(key) else: - new_env = environment.Environment(params) - new_files = files - new_template = template - - tmpl = templatem.Template(new_template, files=new_files, env=new_env) + tmpl = templatem.Template(template, files=files, + env=environment.Environment(params)) max_resources = cfg.CONF.max_resources_per_stack if max_resources != -1 and len(tmpl[tmpl.RESOURCES]) > max_resources: diff --git a/heat/tests/engine/service/test_stack_update.py b/heat/tests/engine/service/test_stack_update.py index e33cd6ce94..766192eb88 100644 --- a/heat/tests/engine/service/test_stack_update.py +++ b/heat/tests/engine/service/test_stack_update.py @@ -149,6 +149,7 @@ class ServiceStackUpdateTest(common.HeatTestCase): stk.set_stack_user_project_id('1234') self.assertEqual({'KeyName': 'test'}, stk.t.env.params) + t['parameters']['newparam'] = {'type': 'number'} with mock.patch('heat.engine.stack.Stack') as mock_stack: stk.update = mock.Mock() mock_stack.load.return_value = stk @@ -187,6 +188,7 @@ class ServiceStackUpdateTest(common.HeatTestCase): self.assertEqual({'KeyName': 'test', 'removeme': 'foo'}, stk.t.env.params) + t['parameters']['newparam'] = {'type': 'number'} with mock.patch('heat.engine.stack.Stack') as mock_stack: stk.update = mock.Mock() mock_stack.load.return_value = stk diff --git a/heat_integrationtests/functional/test_template_resource.py b/heat_integrationtests/functional/test_template_resource.py index 9a3e833694..ebfd73e8a7 100644 --- a/heat_integrationtests/functional/test_template_resource.py +++ b/heat_integrationtests/functional/test_template_resource.py @@ -935,3 +935,69 @@ resources: stack_identifier, self.main_template_update, files={'resource.yaml': self.nested_templ_update}) + + +class TemplateResourceRemovedParamTest(functional_base.FunctionalTestsBase): + + main_template = ''' +heat_template_version: 2013-05-23 +parameters: + value1: + type: string + default: foo +resources: + my_resource: + type: resource.yaml + properties: + value1: {get_param: value1} +''' + nested_templ = ''' +heat_template_version: 2013-05-23 +parameters: + value1: + type: string + default: foo +resources: + test: + type: OS::Heat::TestResource + properties: + value: {get_param: value1} +''' + main_template_update = ''' +heat_template_version: 2013-05-23 +resources: + my_resource: + type: resource.yaml +''' + nested_templ_update = ''' +heat_template_version: 2013-05-23 +parameters: + value1: + type: string + default: foo + value2: + type: string + default: bar +resources: + test: + type: OS::Heat::TestResource + properties: + value: + str_replace: + template: VAL1-VAL2 + params: + VAL1: {get_param: value1} + VAL2: {get_param: value2} +''' + + def test_update(self): + stack_identifier = self.stack_create( + template=self.main_template, + environment={'parameters': {'value1': 'spam'}}, + files={'resource.yaml': self.nested_templ}) + + self.update_stack( + stack_identifier, + self.main_template_update, + environment={'parameter_defaults': {'value2': 'egg'}}, + files={'resource.yaml': self.nested_templ_update}, existing=True)