Merge "Refactor to use param_schemata with env merge"

This commit is contained in:
Jenkins 2016-08-29 07:54:20 +00:00 committed by Gerrit Code Review
commit 52e40f400c
5 changed files with 58 additions and 54 deletions

View File

@ -68,7 +68,8 @@ def merge_map(old, new, deep_merge=False):
return old
def merge_environments(environment_files, files, params):
def merge_environments(environment_files, files,
params, param_schemata=None):
"""Merges environment files into the stack input parameters.
If a list of environment files have been specified, this call will

View File

@ -678,11 +678,11 @@ class EngineService(service.Service):
if template_id is not None:
tmpl = templatem.Template.load(cnxt, template_id)
env = tmpl.env
else:
env_util.merge_environments(environment_files, files, params)
env = environment.Environment(params)
tmpl = templatem.Template(template, files=files, env=env)
tmpl = templatem.Template(template, files=files)
env_util.merge_environments(environment_files, files, params,
tmpl.param_schemata())
tmpl.env = environment.Environment(params)
self._validate_new_stack(cnxt, stack_name, tmpl)
stack = parser.Stack(cnxt, stack_name, tmpl,
@ -698,7 +698,7 @@ class EngineService(service.Service):
stack.validate()
# For the root stack print a summary of the TemplateResources loaded
if nested_depth == 0:
env.registry.log_resource_info(prefix=stack_name)
tmpl.env.registry.log_resource_info(prefix=stack_name)
return stack
@context.request_context
@ -822,7 +822,8 @@ class EngineService(service.Service):
return dict(stack.identifier())
def _prepare_stack_updates(self, cnxt, current_stack, template, params,
def _prepare_stack_updates(self, cnxt, current_stack,
template, params, environment_files,
files, args, template_id=None):
"""Return the current and updated stack for a given transition.
@ -843,18 +844,6 @@ class EngineService(service.Service):
# 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):
existing_env = current_stack.env.env_as_dict()
existing_params = existing_env[env_fmt.PARAMETERS]
clear_params = set(args.get(rpc_api.PARAM_CLEAR_PARAMETERS, []))
retained = dict((k, v) for k, v in existing_params.items()
if k not in clear_params)
existing_env[env_fmt.PARAMETERS] = retained
new_env = environment.Environment(existing_env)
new_env.load(params)
new_files = current_stack.t.files
new_files.update(files or {})
assert template_id is None, \
"Cannot specify template_id with PARAM_EXISTING"
@ -882,17 +871,34 @@ 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)
new_files = current_stack.t.files
new_files.update(files or {})
tmpl = templatem.Template(new_template, files=new_files)
env_util.merge_environments(environment_files, files, params,
tmpl.param_schemata())
existing_env = current_stack.env.env_as_dict()
existing_params = existing_env[env_fmt.PARAMETERS]
clear_params = set(args.get(rpc_api.PARAM_CLEAR_PARAMETERS, []))
retained = dict((k, v) for k, v in existing_params.items()
if k not in clear_params)
existing_env[env_fmt.PARAMETERS] = retained
new_env = environment.Environment(existing_env)
new_env.load(params)
for key in list(new_env.params.keys()):
if key not in tmpl.param_schemata():
new_env.params.pop(key)
tmpl.env = new_env
else:
if template_id is not None:
tmpl = templatem.Template.load(cnxt, template_id)
else:
tmpl = templatem.Template(template, files=files,
env=environment.Environment(params))
tmpl = templatem.Template(template, files=files)
env_util.merge_environments(environment_files, files, params,
tmpl.param_schemata())
tmpl.env = environment.Environment(params)
max_resources = cfg.CONF.max_resources_per_stack
if max_resources != -1 and len(tmpl[tmpl.RESOURCES]) > max_resources:
@ -944,9 +950,6 @@ class EngineService(service.Service):
:type environment_files: list or None
:param template_id: the ID of a pre-stored template in the DB
"""
# Handle server-side environment file resolution
env_util.merge_environments(environment_files, files, params)
# Get the database representation of the existing stack
db_stack = self._get_stack(cnxt, stack_identity)
LOG.info(_LI('Updating stack %s'), db_stack.name)
@ -966,7 +969,8 @@ class EngineService(service.Service):
raise exception.NotSupported(feature=msg)
tmpl, current_stack, updated_stack = self._prepare_stack_updates(
cnxt, current_stack, template, params, files, args, template_id)
cnxt, current_stack, template, params,
environment_files, files, args, template_id)
if current_stack.convergence:
current_stack.thread_group_mgr = self.thread_group_mgr
@ -1001,9 +1005,6 @@ class EngineService(service.Service):
Note that at this stage the template has already been fetched from the
heat-api process if using a template-url.
"""
# Handle server-side environment file resolution
env_util.merge_environments(environment_files, files, params)
# Get the database representation of the existing stack
db_stack = self._get_stack(cnxt, stack_identity)
LOG.info(_LI('Previewing update of stack %s'), db_stack.name)
@ -1011,7 +1012,8 @@ class EngineService(service.Service):
current_stack = parser.Stack.load(cnxt, stack=db_stack)
tmpl, current_stack, updated_stack = self._prepare_stack_updates(
cnxt, current_stack, template, params, files, args)
cnxt, current_stack, template, params,
environment_files, files, args)
update_task = update.StackUpdate(current_stack, updated_stack, None)
@ -1192,9 +1194,10 @@ class EngineService(service.Service):
service_check_defer = True
env_util.merge_environments(environment_files, files, params)
env = environment.Environment(params)
tmpl = templatem.Template(template, files=files, env=env)
tmpl = templatem.Template(template, files=files)
env_util.merge_environments(environment_files, files, params,
tmpl.param_schemata())
tmpl.env = environment.Environment(params)
try:
self._validate_template(cnxt, tmpl)
except Exception as ex:

View File

@ -63,7 +63,7 @@ class StackCreateTest(common.HeatTestCase):
self.assertIsInstance(result, dict)
self.assertTrue(result['stack_id'])
mock_tmpl.assert_called_once_with(template, files=None, env=stk.env)
mock_tmpl.assert_called_once_with(template, files=None)
mock_env.assert_called_once_with(params)
mock_stack.assert_called_once_with(
self.ctx, stack_name, stk.t, owner_id=None, nested_depth=0,
@ -71,7 +71,8 @@ class StackCreateTest(common.HeatTestCase):
convergence=cfg.CONF.convergence_engine, parent_resource=None)
if environment_files:
mock_merge.assert_called_once_with(environment_files, None, params)
mock_merge.assert_called_once_with(environment_files, None,
params, mock.ANY)
mock_validate.assert_called_once_with()
def test_stack_create(self):
@ -119,7 +120,7 @@ class StackCreateTest(common.HeatTestCase):
None, {})
self.assertEqual(exception.StackValidationFailed, ex.exc_info[0])
mock_tmpl.assert_called_once_with(template, files=None, env=stk.env)
mock_tmpl.assert_called_once_with(template, files=None)
mock_env.assert_called_once_with(params)
mock_stack.assert_called_once_with(
self.ctx, stack_name, stk.t, owner_id=None, nested_depth=0,
@ -183,7 +184,7 @@ class StackCreateTest(common.HeatTestCase):
self.assertEqual('Missing required credential: X-Auth-Key',
six.text_type(ex.exc_info[1]))
mock_tmpl.assert_called_once_with(template, files=None, env=stk.env)
mock_tmpl.assert_called_once_with(template, files=None)
mock_env.assert_called_once_with(params)
mock_stack.assert_called_once_with(
ctx_no_pwd, stack_name, stk.t, owner_id=None, nested_depth=0,
@ -204,7 +205,7 @@ class StackCreateTest(common.HeatTestCase):
self.assertEqual('Missing required credential: X-Auth-User',
six.text_type(ex.exc_info[1]))
mock_tmpl.assert_called_once_with(template, files=None, env=stk.env)
mock_tmpl.assert_called_once_with(template, files=None)
mock_env.assert_called_once_with(params)
mock_stack.assert_called_once_with(
ctx_no_user, stack_name, stk.t, owner_id=None, nested_depth=0,
@ -238,7 +239,7 @@ class StackCreateTest(common.HeatTestCase):
result = self.man.create_stack(self.ctx, stack_name, template, params,
None, {})
mock_tmpl.assert_called_once_with(template, files=None, env=stk.env)
mock_tmpl.assert_called_once_with(template, files=None)
mock_env.assert_called_once_with(params)
mock_stack.assert_called_once_with(
self.ctx, stack_name, stk.t, owner_id=None, nested_depth=0,

View File

@ -80,7 +80,7 @@ class ServiceStackUpdateTest(common.HeatTestCase):
self.assertIsInstance(result, dict)
self.assertTrue(result['stack_id'])
self.assertEqual([msgq_mock], self.man.thread_group_mgr.msg_queues)
mock_tmpl.assert_called_once_with(template, files=None, env=stk.env)
mock_tmpl.assert_called_once_with(template, files=None)
mock_env.assert_called_once_with(params)
mock_stack.assert_called_once_with(
self.ctx, stk.name, stk.t,
@ -131,7 +131,8 @@ class ServiceStackUpdateTest(common.HeatTestCase):
environment_files=environment_files)
# Verify
mock_merge.assert_called_once_with(environment_files, None, params)
mock_merge.assert_called_once_with(environment_files, None,
params, mock.ANY)
def test_stack_update_nested(self):
stack_name = 'service_update_nested_test_stack'
@ -458,7 +459,7 @@ resources:
self.assertTrue(result['stack_id'])
mock_validate.assert_called_once_with()
mock_tmpl.assert_called_once_with(template, files=None, env=stk.env)
mock_tmpl.assert_called_once_with(template, files=None)
mock_env.assert_called_once_with(params)
mock_load.assert_called_once_with(self.ctx, stack=s)
mock_stack.assert_called_once_with(
@ -572,7 +573,7 @@ resources:
root_stack_id = old_stack.root_stack_id()
self.assertEqual(3, old_stack.total_resources(root_stack_id))
mock_tmpl.assert_called_once_with(template, files=None, env=stk.env)
mock_tmpl.assert_called_once_with(template, files=None)
mock_env.assert_called_once_with(params)
mock_stack.assert_called_once_with(
self.ctx, stk.name, stk.t,
@ -688,7 +689,7 @@ resources:
# assertions
self.assertEqual(exception.StackValidationFailed, ex.exc_info[0])
mock_tmpl.assert_called_once_with(template, files=None, env=stk.env)
mock_tmpl.assert_called_once_with(template, files=None)
mock_env.assert_called_once_with(params)
mock_stack.assert_called_once_with(
self.ctx, stk.name, stk.t,
@ -751,7 +752,7 @@ resources:
mock_get.assert_called_once_with(self.ctx, stk.identifier())
mock_tmpl.assert_called_once_with(template, files=None, env=stk.env)
mock_tmpl.assert_called_once_with(template, files=None)
mock_env.assert_called_once_with(params)
mock_stack.assert_called_once_with(
self.ctx, stk.name, stk.t,
@ -1017,13 +1018,13 @@ resources:
strict_validate=True, tenant_id='test_tenant_id', timeout_mins=60,
user_creds_id=u'1', username='test_username')
mock_load.assert_called_once_with(self.ctx, stack=s)
mock_tmpl.assert_called_once_with(new_template, files=None,
env=stk.env)
mock_tmpl.assert_called_once_with(new_template, files=None)
mock_env.assert_called_once_with(params)
mock_validate.assert_called_once_with()
if environment_files:
mock_merge.assert_called_once_with(environment_files, None, params)
mock_merge.assert_called_once_with(environment_files, None,
params, mock.ANY)
return result

View File

@ -235,8 +235,7 @@ class StackConvergenceServiceCreateUpdateTest(common.HeatTestCase):
self.m.StubOutWithMock(environment, 'Environment')
self.m.StubOutWithMock(parser, 'Stack')
templatem.Template(template, files=None,
env=stack.env).AndReturn(stack.t)
templatem.Template(template, files=None).AndReturn(stack.t)
environment.Environment(params).AndReturn(stack.env)
parser.Stack(self.ctx, stack.name,
stack.t, owner_id=None,
@ -280,8 +279,7 @@ class StackConvergenceServiceCreateUpdateTest(common.HeatTestCase):
self._stub_update_mocks(s, old_stack)
templatem.Template(template, files=None,
env=stack.env).AndReturn(stack.t)
templatem.Template(template, files=None).AndReturn(stack.t)
environment.Environment(params).AndReturn(stack.env)
parser.Stack(self.ctx, stack.name,
stack.t,
@ -1175,7 +1173,7 @@ class StackServiceTest(common.HeatTestCase):
self._preview_stack(environment_files=environment_files)
# Verify
mock_merge.assert_called_once_with(environment_files, None, {})
mock_merge.assert_called_once_with(environment_files, None, {}, {})
@mock.patch.object(stack_object.Stack, 'get_by_name')
def test_validate_new_stack_checks_existing_stack(self, mock_stack_get):