Remove unknown parameters in patched update

When updating a stack with the existing flag, we keep the parameters
from the old template to be used against the new version. Sometimes
parameters will get remove and won't make sense anymore, and keeping
them would break update with a 'Parameter was not defined' error. This
filters out such parameters so that the updates succeed.

Change-Id: I6f2aa77da28d271dd001a137bb574b5470292f15
Closes-Bug: #1558610
This commit is contained in:
Thomas Herve 2016-03-17 16:03:08 +01:00
parent 5a4f3e084c
commit 90fc4fe89e
3 changed files with 76 additions and 6 deletions

View File

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

View File

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

View File

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