Merge "Keep encrypted_param_names environment internal to heat"
This commit is contained in:
commit
84cb131c5d
@ -704,12 +704,21 @@ class Environment(object):
|
||||
env_snippet.get(env_fmt.PARAMETER_DEFAULTS, {}))
|
||||
self._update_event_sinks(env_snippet.get(env_fmt.EVENT_SINKS, []))
|
||||
|
||||
def env_as_dict(self):
|
||||
"""Get the entire environment as a dict."""
|
||||
user_env = self.user_env_as_dict()
|
||||
user_env.update(
|
||||
# Any data here is to be stored in the DB but not reflected
|
||||
# as part of the user environment (e.g to pass to nested stacks
|
||||
# or made visible to the user via API calls etc
|
||||
{env_fmt.ENCRYPTED_PARAM_NAMES: self.encrypted_param_names})
|
||||
return user_env
|
||||
|
||||
def user_env_as_dict(self):
|
||||
"""Get the environment as a dict, ready for storing in the db."""
|
||||
"""Get the environment as a dict, only user-allowed keys."""
|
||||
return {env_fmt.RESOURCE_REGISTRY: self.registry.as_dict(),
|
||||
env_fmt.PARAMETERS: self.params,
|
||||
env_fmt.PARAMETER_DEFAULTS: self.param_defaults,
|
||||
env_fmt.ENCRYPTED_PARAM_NAMES: self.encrypted_param_names,
|
||||
env_fmt.EVENT_SINKS: self._event_sinks}
|
||||
|
||||
def register_class(self, resource_type, resource_class, path=None):
|
||||
|
@ -855,7 +855,7 @@ 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.user_env_as_dict()
|
||||
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()
|
||||
|
@ -138,7 +138,7 @@ class Template(collections.Mapping):
|
||||
rt = {
|
||||
'template': self.t,
|
||||
'files_id': self.files.store(context),
|
||||
'environment': self.env.user_env_as_dict()
|
||||
'environment': self.env.env_as_dict()
|
||||
}
|
||||
if self.id is None:
|
||||
new_rt = template_object.RawTemplate.create(context, rt)
|
||||
|
@ -22,6 +22,7 @@ from heat.common import exception
|
||||
from heat.common import messaging
|
||||
from heat.common import service_utils
|
||||
from heat.common import template_format
|
||||
from heat.db import api as db_api
|
||||
from heat.engine.clients.os import glance
|
||||
from heat.engine.clients.os import nova
|
||||
from heat.engine import environment
|
||||
@ -216,6 +217,65 @@ class ServiceStackUpdateTest(common.HeatTestCase):
|
||||
tmpl.env.params)
|
||||
self.assertEqual(stk.identifier(), result)
|
||||
|
||||
def test_stack_update_existing_encrypted_parameters(self):
|
||||
# Create the stack with encryption enabled
|
||||
# On update encrypted_param_names should be used from existing stack
|
||||
hidden_param_template = u'''
|
||||
heat_template_version: 2013-05-23
|
||||
parameters:
|
||||
param2:
|
||||
type: string
|
||||
description: value2.
|
||||
hidden: true
|
||||
resources:
|
||||
a_resource:
|
||||
type: GenericResourceType
|
||||
'''
|
||||
cfg.CONF.set_override('encrypt_parameters_and_properties', True,
|
||||
enforce_type=True)
|
||||
|
||||
stack_name = 'service_update_test_stack_encrypted_parameters'
|
||||
t = template_format.parse(hidden_param_template)
|
||||
env1 = environment.Environment({'param2': 'bar'})
|
||||
stk = stack.Stack(self.ctx, stack_name,
|
||||
templatem.Template(t, env=env1))
|
||||
stk.store()
|
||||
stk.set_stack_user_project_id('1234')
|
||||
|
||||
# Verify that hidden parameters are stored encrypted
|
||||
db_tpl = db_api.raw_template_get(self.ctx, stk.t.id)
|
||||
db_params = db_tpl.environment['parameters']
|
||||
self.assertEqual('cryptography_decrypt_v1', db_params['param2'][0])
|
||||
self.assertNotEqual("foo", db_params['param2'][1])
|
||||
|
||||
# Verify that loaded stack has decrypted paramters
|
||||
loaded_stack = stack.Stack.load(self.ctx, stack_id=stk.id)
|
||||
params = loaded_stack.t.env.params
|
||||
self.assertEqual('bar', params.get('param2'))
|
||||
|
||||
update_params = {'encrypted_param_names': [],
|
||||
'parameter_defaults': {},
|
||||
'event_sinks': [],
|
||||
'parameters': {},
|
||||
'resource_registry': {'resources': {}}}
|
||||
api_args = {rpc_api.PARAM_TIMEOUT: 60,
|
||||
rpc_api.PARAM_EXISTING: True}
|
||||
|
||||
with mock.patch('heat.engine.stack.Stack') as mock_stack:
|
||||
stk.update = mock.Mock()
|
||||
mock_stack.load.return_value = loaded_stack
|
||||
mock_stack.validate.return_value = None
|
||||
result = self.man.update_stack(self.ctx, stk.identifier(),
|
||||
t,
|
||||
update_params,
|
||||
None, api_args)
|
||||
tmpl = mock_stack.call_args[0][2]
|
||||
self.assertEqual({u'param2': u'bar'}, tmpl.env.params)
|
||||
# encrypted_param_names must be passed from existing to new
|
||||
# stack otherwise the updated stack won't decrypt the params
|
||||
self.assertEqual([u'param2'], tmpl.env.encrypted_param_names)
|
||||
self.assertEqual(stk.identifier(), result)
|
||||
|
||||
def test_stack_update_existing_parameters_remove(self):
|
||||
"""Test case for updating stack with changed parameters.
|
||||
|
||||
@ -288,7 +348,7 @@ class ServiceStackUpdateTest(common.HeatTestCase):
|
||||
stk = utils.parse_stack(t, stack_name=stack_name, params=intial_params,
|
||||
files=initial_files)
|
||||
stk.set_stack_user_project_id('1234')
|
||||
self.assertEqual(intial_params, stk.t.env.user_env_as_dict())
|
||||
self.assertEqual(intial_params, stk.t.env.env_as_dict())
|
||||
|
||||
expected_reg = {'OS::Foo': 'foo.yaml',
|
||||
'OS::Foo2': 'newfoo2.yaml',
|
||||
@ -317,7 +377,7 @@ class ServiceStackUpdateTest(common.HeatTestCase):
|
||||
api_args)
|
||||
tmpl = mock_stack.call_args[0][2]
|
||||
self.assertEqual(expected_env,
|
||||
tmpl.env.user_env_as_dict())
|
||||
tmpl.env.env_as_dict())
|
||||
self.assertEqual(expected_files,
|
||||
tmpl.files.files)
|
||||
self.assertEqual(stk.identifier(), result)
|
||||
@ -361,7 +421,7 @@ class ServiceStackUpdateTest(common.HeatTestCase):
|
||||
None, api_args)
|
||||
tmpl = mock_stack.call_args[0][2]
|
||||
self.assertEqual(expected_env,
|
||||
tmpl.env.user_env_as_dict())
|
||||
tmpl.env.env_as_dict())
|
||||
self.assertEqual(stk.identifier(), result)
|
||||
|
||||
def test_stack_update_reuses_api_params(self):
|
||||
|
@ -47,6 +47,8 @@ class EnvironmentTest(common.HeatTestCase):
|
||||
u'event_sinks': [],
|
||||
u'resource_registry': {u'resources': {}}}
|
||||
env = environment.Environment(old)
|
||||
self.assertEqual(expected, env.env_as_dict())
|
||||
del(expected['encrypted_param_names'])
|
||||
self.assertEqual(expected, env.user_env_as_dict())
|
||||
|
||||
def test_load_new_env(self):
|
||||
@ -57,6 +59,8 @@ class EnvironmentTest(common.HeatTestCase):
|
||||
u'resource_registry': {u'OS::Food': u'fruity.yaml',
|
||||
u'resources': {}}}
|
||||
env = environment.Environment(new_env)
|
||||
self.assertEqual(new_env, env.env_as_dict())
|
||||
del(new_env['encrypted_param_names'])
|
||||
self.assertEqual(new_env, env.user_env_as_dict())
|
||||
|
||||
def test_global_registry(self):
|
||||
@ -155,7 +159,7 @@ class EnvironmentTest(common.HeatTestCase):
|
||||
'b.yaml',
|
||||
path=['resources', 'res_x', 'test::two'])
|
||||
|
||||
self.assertEqual(env.user_env_as_dict(), env2.user_env_as_dict())
|
||||
self.assertEqual(env.env_as_dict(), env2.env_as_dict())
|
||||
|
||||
def test_constraints(self):
|
||||
env = environment.Environment({})
|
||||
@ -520,7 +524,7 @@ class ChildEnvTest(common.HeatTestCase):
|
||||
'event_sinks': [],
|
||||
'resource_registry': {'resources': {}}}
|
||||
cenv = environment.get_child_environment(penv, new_params)
|
||||
self.assertEqual(expected, cenv.user_env_as_dict())
|
||||
self.assertEqual(expected, cenv.env_as_dict())
|
||||
|
||||
def test_params_normal(self):
|
||||
new_params = {'parameters': {'foo': 'bar', 'tester': 'Yes'}}
|
||||
@ -531,7 +535,7 @@ class ChildEnvTest(common.HeatTestCase):
|
||||
'resource_registry': {'resources': {}}}
|
||||
expected.update(new_params)
|
||||
cenv = environment.get_child_environment(penv, new_params)
|
||||
self.assertEqual(expected, cenv.user_env_as_dict())
|
||||
self.assertEqual(expected, cenv.env_as_dict())
|
||||
|
||||
def test_params_parent_overwritten(self):
|
||||
new_params = {'parameters': {'foo': 'bar', 'tester': 'Yes'}}
|
||||
@ -543,7 +547,7 @@ class ChildEnvTest(common.HeatTestCase):
|
||||
'resource_registry': {'resources': {}}}
|
||||
expected.update(new_params)
|
||||
cenv = environment.get_child_environment(penv, new_params)
|
||||
self.assertEqual(expected, cenv.user_env_as_dict())
|
||||
self.assertEqual(expected, cenv.env_as_dict())
|
||||
|
||||
def test_registry_merge_simple(self):
|
||||
env1 = {u'resource_registry': {u'OS::Food': u'fruity.yaml'}}
|
||||
|
@ -844,8 +844,7 @@ class WithTemplateTest(StackResourceBaseTest):
|
||||
child_env = {'parameter_defaults': {},
|
||||
'event_sinks': [],
|
||||
'parameters': self.params,
|
||||
'resource_registry': {'resources': {}},
|
||||
'encrypted_param_names': []}
|
||||
'resource_registry': {'resources': {}}}
|
||||
self.parent_resource.child_params = mock.Mock(
|
||||
return_value=self.params)
|
||||
res_name = self.parent_resource.physical_resource_name()
|
||||
@ -891,8 +890,7 @@ class WithTemplateTest(StackResourceBaseTest):
|
||||
child_env = {'parameter_defaults': {},
|
||||
'event_sinks': [],
|
||||
'parameters': self.params,
|
||||
'resource_registry': {'resources': {}},
|
||||
'encrypted_param_names': []}
|
||||
'resource_registry': {'resources': {}}}
|
||||
self.parent_resource.child_params = mock.Mock(
|
||||
return_value=self.params)
|
||||
res_name = self.parent_resource.physical_resource_name()
|
||||
|
Loading…
Reference in New Issue
Block a user