Merge "Refactor to use param_schemata with env merge"
This commit is contained in:
commit
52e40f400c
|
@ -68,7 +68,8 @@ def merge_map(old, new, deep_merge=False):
|
||||||
return old
|
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.
|
"""Merges environment files into the stack input parameters.
|
||||||
|
|
||||||
If a list of environment files have been specified, this call will
|
If a list of environment files have been specified, this call will
|
||||||
|
|
|
@ -678,11 +678,11 @@ class EngineService(service.Service):
|
||||||
|
|
||||||
if template_id is not None:
|
if template_id is not None:
|
||||||
tmpl = templatem.Template.load(cnxt, template_id)
|
tmpl = templatem.Template.load(cnxt, template_id)
|
||||||
env = tmpl.env
|
|
||||||
else:
|
else:
|
||||||
env_util.merge_environments(environment_files, files, params)
|
tmpl = templatem.Template(template, files=files)
|
||||||
env = environment.Environment(params)
|
env_util.merge_environments(environment_files, files, params,
|
||||||
tmpl = templatem.Template(template, files=files, env=env)
|
tmpl.param_schemata())
|
||||||
|
tmpl.env = environment.Environment(params)
|
||||||
self._validate_new_stack(cnxt, stack_name, tmpl)
|
self._validate_new_stack(cnxt, stack_name, tmpl)
|
||||||
|
|
||||||
stack = parser.Stack(cnxt, stack_name, tmpl,
|
stack = parser.Stack(cnxt, stack_name, tmpl,
|
||||||
|
@ -698,7 +698,7 @@ class EngineService(service.Service):
|
||||||
stack.validate()
|
stack.validate()
|
||||||
# For the root stack print a summary of the TemplateResources loaded
|
# For the root stack print a summary of the TemplateResources loaded
|
||||||
if nested_depth == 0:
|
if nested_depth == 0:
|
||||||
env.registry.log_resource_info(prefix=stack_name)
|
tmpl.env.registry.log_resource_info(prefix=stack_name)
|
||||||
return stack
|
return stack
|
||||||
|
|
||||||
@context.request_context
|
@context.request_context
|
||||||
|
@ -822,7 +822,8 @@ class EngineService(service.Service):
|
||||||
|
|
||||||
return dict(stack.identifier())
|
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):
|
files, args, template_id=None):
|
||||||
"""Return the current and updated stack for a given transition.
|
"""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
|
# any environment provided into the existing one and attempt
|
||||||
# to use the existing stack template, if one is not provided.
|
# to use the existing stack template, if one is not provided.
|
||||||
if args.get(rpc_api.PARAM_EXISTING):
|
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, \
|
assert template_id is None, \
|
||||||
"Cannot specify template_id with PARAM_EXISTING"
|
"Cannot specify template_id with PARAM_EXISTING"
|
||||||
|
|
||||||
|
@ -882,17 +871,34 @@ class EngineService(service.Service):
|
||||||
'previous template stored'))
|
'previous template stored'))
|
||||||
msg = _('PATCH update to non-COMPLETE stack')
|
msg = _('PATCH update to non-COMPLETE stack')
|
||||||
raise exception.NotSupported(feature=msg)
|
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()):
|
for key in list(new_env.params.keys()):
|
||||||
if key not in tmpl.param_schemata():
|
if key not in tmpl.param_schemata():
|
||||||
new_env.params.pop(key)
|
new_env.params.pop(key)
|
||||||
|
tmpl.env = new_env
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if template_id is not None:
|
if template_id is not None:
|
||||||
tmpl = templatem.Template.load(cnxt, template_id)
|
tmpl = templatem.Template.load(cnxt, template_id)
|
||||||
else:
|
else:
|
||||||
tmpl = templatem.Template(template, files=files,
|
tmpl = templatem.Template(template, files=files)
|
||||||
env=environment.Environment(params))
|
env_util.merge_environments(environment_files, files, params,
|
||||||
|
tmpl.param_schemata())
|
||||||
|
tmpl.env = environment.Environment(params)
|
||||||
|
|
||||||
max_resources = cfg.CONF.max_resources_per_stack
|
max_resources = cfg.CONF.max_resources_per_stack
|
||||||
if max_resources != -1 and len(tmpl[tmpl.RESOURCES]) > max_resources:
|
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
|
:type environment_files: list or None
|
||||||
:param template_id: the ID of a pre-stored template in the DB
|
: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
|
# Get the database representation of the existing stack
|
||||||
db_stack = self._get_stack(cnxt, stack_identity)
|
db_stack = self._get_stack(cnxt, stack_identity)
|
||||||
LOG.info(_LI('Updating stack %s'), db_stack.name)
|
LOG.info(_LI('Updating stack %s'), db_stack.name)
|
||||||
|
@ -966,7 +969,8 @@ class EngineService(service.Service):
|
||||||
raise exception.NotSupported(feature=msg)
|
raise exception.NotSupported(feature=msg)
|
||||||
|
|
||||||
tmpl, current_stack, updated_stack = self._prepare_stack_updates(
|
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:
|
if current_stack.convergence:
|
||||||
current_stack.thread_group_mgr = self.thread_group_mgr
|
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
|
Note that at this stage the template has already been fetched from the
|
||||||
heat-api process if using a template-url.
|
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
|
# Get the database representation of the existing stack
|
||||||
db_stack = self._get_stack(cnxt, stack_identity)
|
db_stack = self._get_stack(cnxt, stack_identity)
|
||||||
LOG.info(_LI('Previewing update of stack %s'), db_stack.name)
|
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)
|
current_stack = parser.Stack.load(cnxt, stack=db_stack)
|
||||||
|
|
||||||
tmpl, current_stack, updated_stack = self._prepare_stack_updates(
|
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)
|
update_task = update.StackUpdate(current_stack, updated_stack, None)
|
||||||
|
|
||||||
|
@ -1192,9 +1194,10 @@ class EngineService(service.Service):
|
||||||
|
|
||||||
service_check_defer = True
|
service_check_defer = True
|
||||||
|
|
||||||
env_util.merge_environments(environment_files, files, params)
|
tmpl = templatem.Template(template, files=files)
|
||||||
env = environment.Environment(params)
|
env_util.merge_environments(environment_files, files, params,
|
||||||
tmpl = templatem.Template(template, files=files, env=env)
|
tmpl.param_schemata())
|
||||||
|
tmpl.env = environment.Environment(params)
|
||||||
try:
|
try:
|
||||||
self._validate_template(cnxt, tmpl)
|
self._validate_template(cnxt, tmpl)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
|
|
|
@ -63,7 +63,7 @@ class StackCreateTest(common.HeatTestCase):
|
||||||
self.assertIsInstance(result, dict)
|
self.assertIsInstance(result, dict)
|
||||||
self.assertTrue(result['stack_id'])
|
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_env.assert_called_once_with(params)
|
||||||
mock_stack.assert_called_once_with(
|
mock_stack.assert_called_once_with(
|
||||||
self.ctx, stack_name, stk.t, owner_id=None, nested_depth=0,
|
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)
|
convergence=cfg.CONF.convergence_engine, parent_resource=None)
|
||||||
|
|
||||||
if environment_files:
|
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()
|
mock_validate.assert_called_once_with()
|
||||||
|
|
||||||
def test_stack_create(self):
|
def test_stack_create(self):
|
||||||
|
@ -119,7 +120,7 @@ class StackCreateTest(common.HeatTestCase):
|
||||||
None, {})
|
None, {})
|
||||||
self.assertEqual(exception.StackValidationFailed, ex.exc_info[0])
|
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_env.assert_called_once_with(params)
|
||||||
mock_stack.assert_called_once_with(
|
mock_stack.assert_called_once_with(
|
||||||
self.ctx, stack_name, stk.t, owner_id=None, nested_depth=0,
|
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',
|
self.assertEqual('Missing required credential: X-Auth-Key',
|
||||||
six.text_type(ex.exc_info[1]))
|
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_env.assert_called_once_with(params)
|
||||||
mock_stack.assert_called_once_with(
|
mock_stack.assert_called_once_with(
|
||||||
ctx_no_pwd, stack_name, stk.t, owner_id=None, nested_depth=0,
|
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',
|
self.assertEqual('Missing required credential: X-Auth-User',
|
||||||
six.text_type(ex.exc_info[1]))
|
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_env.assert_called_once_with(params)
|
||||||
mock_stack.assert_called_once_with(
|
mock_stack.assert_called_once_with(
|
||||||
ctx_no_user, stack_name, stk.t, owner_id=None, nested_depth=0,
|
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,
|
result = self.man.create_stack(self.ctx, stack_name, template, params,
|
||||||
None, {})
|
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_env.assert_called_once_with(params)
|
||||||
mock_stack.assert_called_once_with(
|
mock_stack.assert_called_once_with(
|
||||||
self.ctx, stack_name, stk.t, owner_id=None, nested_depth=0,
|
self.ctx, stack_name, stk.t, owner_id=None, nested_depth=0,
|
||||||
|
|
|
@ -80,7 +80,7 @@ class ServiceStackUpdateTest(common.HeatTestCase):
|
||||||
self.assertIsInstance(result, dict)
|
self.assertIsInstance(result, dict)
|
||||||
self.assertTrue(result['stack_id'])
|
self.assertTrue(result['stack_id'])
|
||||||
self.assertEqual([msgq_mock], self.man.thread_group_mgr.msg_queues)
|
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_env.assert_called_once_with(params)
|
||||||
mock_stack.assert_called_once_with(
|
mock_stack.assert_called_once_with(
|
||||||
self.ctx, stk.name, stk.t,
|
self.ctx, stk.name, stk.t,
|
||||||
|
@ -131,7 +131,8 @@ class ServiceStackUpdateTest(common.HeatTestCase):
|
||||||
environment_files=environment_files)
|
environment_files=environment_files)
|
||||||
|
|
||||||
# Verify
|
# 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):
|
def test_stack_update_nested(self):
|
||||||
stack_name = 'service_update_nested_test_stack'
|
stack_name = 'service_update_nested_test_stack'
|
||||||
|
@ -458,7 +459,7 @@ resources:
|
||||||
self.assertTrue(result['stack_id'])
|
self.assertTrue(result['stack_id'])
|
||||||
|
|
||||||
mock_validate.assert_called_once_with()
|
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_env.assert_called_once_with(params)
|
||||||
mock_load.assert_called_once_with(self.ctx, stack=s)
|
mock_load.assert_called_once_with(self.ctx, stack=s)
|
||||||
mock_stack.assert_called_once_with(
|
mock_stack.assert_called_once_with(
|
||||||
|
@ -572,7 +573,7 @@ resources:
|
||||||
root_stack_id = old_stack.root_stack_id()
|
root_stack_id = old_stack.root_stack_id()
|
||||||
self.assertEqual(3, old_stack.total_resources(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_env.assert_called_once_with(params)
|
||||||
mock_stack.assert_called_once_with(
|
mock_stack.assert_called_once_with(
|
||||||
self.ctx, stk.name, stk.t,
|
self.ctx, stk.name, stk.t,
|
||||||
|
@ -688,7 +689,7 @@ resources:
|
||||||
|
|
||||||
# assertions
|
# assertions
|
||||||
self.assertEqual(exception.StackValidationFailed, ex.exc_info[0])
|
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_env.assert_called_once_with(params)
|
||||||
mock_stack.assert_called_once_with(
|
mock_stack.assert_called_once_with(
|
||||||
self.ctx, stk.name, stk.t,
|
self.ctx, stk.name, stk.t,
|
||||||
|
@ -751,7 +752,7 @@ resources:
|
||||||
|
|
||||||
mock_get.assert_called_once_with(self.ctx, stk.identifier())
|
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_env.assert_called_once_with(params)
|
||||||
mock_stack.assert_called_once_with(
|
mock_stack.assert_called_once_with(
|
||||||
self.ctx, stk.name, stk.t,
|
self.ctx, stk.name, stk.t,
|
||||||
|
@ -1017,13 +1018,13 @@ resources:
|
||||||
strict_validate=True, tenant_id='test_tenant_id', timeout_mins=60,
|
strict_validate=True, tenant_id='test_tenant_id', timeout_mins=60,
|
||||||
user_creds_id=u'1', username='test_username')
|
user_creds_id=u'1', username='test_username')
|
||||||
mock_load.assert_called_once_with(self.ctx, stack=s)
|
mock_load.assert_called_once_with(self.ctx, stack=s)
|
||||||
mock_tmpl.assert_called_once_with(new_template, files=None,
|
mock_tmpl.assert_called_once_with(new_template, files=None)
|
||||||
env=stk.env)
|
|
||||||
mock_env.assert_called_once_with(params)
|
mock_env.assert_called_once_with(params)
|
||||||
mock_validate.assert_called_once_with()
|
mock_validate.assert_called_once_with()
|
||||||
|
|
||||||
if environment_files:
|
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
|
return result
|
||||||
|
|
||||||
|
|
|
@ -235,8 +235,7 @@ class StackConvergenceServiceCreateUpdateTest(common.HeatTestCase):
|
||||||
self.m.StubOutWithMock(environment, 'Environment')
|
self.m.StubOutWithMock(environment, 'Environment')
|
||||||
self.m.StubOutWithMock(parser, 'Stack')
|
self.m.StubOutWithMock(parser, 'Stack')
|
||||||
|
|
||||||
templatem.Template(template, files=None,
|
templatem.Template(template, files=None).AndReturn(stack.t)
|
||||||
env=stack.env).AndReturn(stack.t)
|
|
||||||
environment.Environment(params).AndReturn(stack.env)
|
environment.Environment(params).AndReturn(stack.env)
|
||||||
parser.Stack(self.ctx, stack.name,
|
parser.Stack(self.ctx, stack.name,
|
||||||
stack.t, owner_id=None,
|
stack.t, owner_id=None,
|
||||||
|
@ -280,8 +279,7 @@ class StackConvergenceServiceCreateUpdateTest(common.HeatTestCase):
|
||||||
|
|
||||||
self._stub_update_mocks(s, old_stack)
|
self._stub_update_mocks(s, old_stack)
|
||||||
|
|
||||||
templatem.Template(template, files=None,
|
templatem.Template(template, files=None).AndReturn(stack.t)
|
||||||
env=stack.env).AndReturn(stack.t)
|
|
||||||
environment.Environment(params).AndReturn(stack.env)
|
environment.Environment(params).AndReturn(stack.env)
|
||||||
parser.Stack(self.ctx, stack.name,
|
parser.Stack(self.ctx, stack.name,
|
||||||
stack.t,
|
stack.t,
|
||||||
|
@ -1175,7 +1173,7 @@ class StackServiceTest(common.HeatTestCase):
|
||||||
self._preview_stack(environment_files=environment_files)
|
self._preview_stack(environment_files=environment_files)
|
||||||
|
|
||||||
# Verify
|
# 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')
|
@mock.patch.object(stack_object.Stack, 'get_by_name')
|
||||||
def test_validate_new_stack_checks_existing_stack(self, mock_stack_get):
|
def test_validate_new_stack_checks_existing_stack(self, mock_stack_get):
|
||||||
|
|
Loading…
Reference in New Issue