Merge "Move merge_environment to environment_util module"
This commit is contained in:
commit
39f43109e0
|
@ -10,6 +10,9 @@
|
|||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
import collections
|
||||
|
||||
from heat.common import environment_format
|
||||
|
||||
ALLOWED_PARAM_MERGE_STRATEGIES = (OVERWRITE, MERGE, DEEP_MERGE) = (
|
||||
'overwrite', 'merge', 'deep_merge')
|
||||
|
@ -27,3 +30,38 @@ def get_param_merge_strategy(merge_strategies, param_key):
|
|||
return merge_strategy
|
||||
|
||||
return env_default
|
||||
|
||||
|
||||
def deep_update(old, new):
|
||||
'''Merge nested dictionaries.'''
|
||||
for k, v in new.items():
|
||||
if isinstance(v, collections.Mapping):
|
||||
r = deep_update(old.get(k, {}), v)
|
||||
old[k] = r
|
||||
else:
|
||||
old[k] = new[k]
|
||||
return old
|
||||
|
||||
|
||||
def merge_environments(environment_files, files, params):
|
||||
"""Merges environment files into the stack input parameters.
|
||||
|
||||
If a list of environment files have been specified, this call will
|
||||
pull the contents of each from the files dict, parse them as
|
||||
environments, and merge them into the stack input params. This
|
||||
behavior is the same as earlier versions of the Heat client that
|
||||
performed this params population client-side.
|
||||
|
||||
:param environment_files: ordered names of the environment files
|
||||
found in the files dict
|
||||
:type environment_files: list or None
|
||||
:param files: mapping of stack filenames to contents
|
||||
:type files: dict
|
||||
:param params: parameters describing the stack
|
||||
:type dict:
|
||||
"""
|
||||
if environment_files:
|
||||
for filename in environment_files:
|
||||
raw_env = files[filename]
|
||||
parsed_env = environment_format.parse(raw_env)
|
||||
deep_update(params, parsed_env)
|
||||
|
|
|
@ -33,6 +33,7 @@ import webob
|
|||
|
||||
from heat.common import context
|
||||
from heat.common import environment_format as env_fmt
|
||||
from heat.common import environment_util as env_util
|
||||
from heat.common import exception
|
||||
from heat.common.i18n import _
|
||||
from heat.common.i18n import _LE
|
||||
|
@ -69,8 +70,6 @@ from heat.objects import watch_data
|
|||
from heat.objects import watch_rule
|
||||
from heat.rpc import api as rpc_api
|
||||
from heat.rpc import worker_api as rpc_worker_api
|
||||
from heatclient.common import environment_format
|
||||
from heatclient.common import template_utils
|
||||
|
||||
cfg.CONF.import_opt('engine_life_check_timeout', 'heat.common.config')
|
||||
cfg.CONF.import_opt('max_resources_per_stack', 'heat.common.config')
|
||||
|
@ -680,7 +679,7 @@ class EngineService(service.Service):
|
|||
tmpl = templatem.Template.load(cnxt, template_id)
|
||||
env = tmpl.env
|
||||
else:
|
||||
self._merge_environments(environment_files, files, params)
|
||||
env_util.merge_environments(environment_files, files, params)
|
||||
env = environment.Environment(params)
|
||||
tmpl = templatem.Template(template, files=files, env=env)
|
||||
self._validate_new_stack(cnxt, stack_name, tmpl)
|
||||
|
@ -701,30 +700,6 @@ class EngineService(service.Service):
|
|||
env.registry.log_resource_info(prefix=stack_name)
|
||||
return stack
|
||||
|
||||
@staticmethod
|
||||
def _merge_environments(environment_files, files, params):
|
||||
"""Merges environment files into the stack input parameters.
|
||||
|
||||
If a list of environment files have been specified, this call will
|
||||
pull the contents of each from the files dict, parse them as
|
||||
environments, and merge them into the stack input params. This
|
||||
behavior is the same as earlier versions of the Heat client that
|
||||
performed this params population client-side.
|
||||
|
||||
:param environment_files: ordered names of the environment files
|
||||
found in the files dict
|
||||
:type environment_files: list or None
|
||||
:param files: mapping of stack filenames to contents
|
||||
:type files: dict
|
||||
:param params: parameters describing the stack
|
||||
:type dict:
|
||||
"""
|
||||
if environment_files:
|
||||
for filename in environment_files:
|
||||
raw_env = files[filename]
|
||||
parsed_env = environment_format.parse(raw_env)
|
||||
template_utils.deep_update(params, parsed_env)
|
||||
|
||||
@context.request_context
|
||||
def preview_stack(self, cnxt, stack_name, template, params, files,
|
||||
args, environment_files=None):
|
||||
|
@ -969,7 +944,7 @@ class EngineService(service.Service):
|
|||
:param template_id: the ID of a pre-stored template in the DB
|
||||
"""
|
||||
# Handle server-side environment file resolution
|
||||
self._merge_environments(environment_files, files, params)
|
||||
env_util.merge_environments(environment_files, files, params)
|
||||
|
||||
# Get the database representation of the existing stack
|
||||
db_stack = self._get_stack(cnxt, stack_identity)
|
||||
|
@ -1026,7 +1001,7 @@ class EngineService(service.Service):
|
|||
heat-api process if using a template-url.
|
||||
"""
|
||||
# Handle server-side environment file resolution
|
||||
self._merge_environments(environment_files, files, params)
|
||||
env_util.merge_environments(environment_files, files, params)
|
||||
|
||||
# Get the database representation of the existing stack
|
||||
db_stack = self._get_stack(cnxt, stack_identity)
|
||||
|
@ -1206,7 +1181,7 @@ class EngineService(service.Service):
|
|||
|
||||
service_check_defer = True
|
||||
|
||||
self._merge_environments(environment_files, files, params)
|
||||
env_util.merge_environments(environment_files, files, params)
|
||||
env = environment.Environment(params)
|
||||
tmpl = templatem.Template(template, files=files, env=env)
|
||||
try:
|
||||
|
|
|
@ -411,50 +411,3 @@ class ServiceEngineTest(common.HeatTestCase):
|
|||
self.eng.start()
|
||||
self.assertEqual(cfg.CONF.executor_thread_pool_size,
|
||||
cfg.CONF.database.max_overflow)
|
||||
|
||||
def test_merge_environments(self):
|
||||
# Setup
|
||||
params = {'parameters': {
|
||||
'p0': 'CORRECT',
|
||||
'p1': 'INCORRECT',
|
||||
'p2': 'INCORRECT'}
|
||||
}
|
||||
env_1 = '''
|
||||
{'parameters' : {
|
||||
'p1': 'CORRECT',
|
||||
'p2': 'INCORRECT-ENV-1',
|
||||
}}'''
|
||||
env_2 = '''
|
||||
{'parameters': {
|
||||
'p2': 'CORRECT'
|
||||
}}'''
|
||||
|
||||
files = {'env_1': env_1, 'env_2': env_2}
|
||||
environment_files = ['env_1', 'env_2']
|
||||
|
||||
# Test
|
||||
self.eng._merge_environments(environment_files, files, params)
|
||||
|
||||
# Verify
|
||||
expected = {'parameters': {
|
||||
'p0': 'CORRECT',
|
||||
'p1': 'CORRECT',
|
||||
'p2': 'CORRECT',
|
||||
}}
|
||||
self.assertEqual(expected, params)
|
||||
|
||||
def test_merge_environments_no_env_files(self):
|
||||
params = {'parameters': {'p0': 'CORRECT'}}
|
||||
env_1 = '''
|
||||
{'parameters' : {
|
||||
'p0': 'INCORRECT',
|
||||
}}'''
|
||||
|
||||
files = {'env_1': env_1}
|
||||
|
||||
# Test - Should ignore env_1 in files
|
||||
self.eng._merge_environments(None, files, params)
|
||||
|
||||
# Verify
|
||||
expected = {'parameters': {'p0': 'CORRECT'}}
|
||||
self.assertEqual(expected, params)
|
||||
|
|
|
@ -16,6 +16,7 @@ from oslo_messaging.rpc import dispatcher
|
|||
from oslo_service import threadgroup
|
||||
import six
|
||||
|
||||
from heat.common import environment_util as env_util
|
||||
from heat.common import exception
|
||||
from heat.engine.clients.os import glance
|
||||
from heat.engine.clients.os import nova
|
||||
|
@ -54,7 +55,7 @@ class StackCreateTest(common.HeatTestCase):
|
|||
mock_env = self.patchobject(environment, 'Environment',
|
||||
return_value=stk.env)
|
||||
mock_stack = self.patchobject(stack, 'Stack', return_value=stk)
|
||||
mock_merge = self.patchobject(self.man, '_merge_environments')
|
||||
mock_merge = self.patchobject(env_util, 'merge_environments')
|
||||
result = self.man.create_stack(self.ctx, stack_name,
|
||||
template, params, None, {},
|
||||
environment_files=environment_files)
|
||||
|
|
|
@ -18,6 +18,7 @@ from oslo_config import cfg
|
|||
from oslo_messaging.rpc import dispatcher
|
||||
import six
|
||||
|
||||
from heat.common import environment_util as env_util
|
||||
from heat.common import exception
|
||||
from heat.common import messaging
|
||||
from heat.common import service_utils
|
||||
|
@ -121,7 +122,7 @@ class ServiceStackUpdateTest(common.HeatTestCase):
|
|||
self.patchobject(eventlet.queue, 'LightQueue',
|
||||
return_value=mock.Mock())
|
||||
|
||||
mock_merge = self.patchobject(self.man, '_merge_environments')
|
||||
mock_merge = self.patchobject(env_util, 'merge_environments')
|
||||
|
||||
# Test
|
||||
environment_files = ['env_1']
|
||||
|
@ -991,7 +992,7 @@ resources:
|
|||
mock_env = self.patchobject(environment, 'Environment',
|
||||
return_value=stk.env)
|
||||
mock_validate = self.patchobject(stk, 'validate', return_value=None)
|
||||
mock_merge = self.patchobject(self.man, '_merge_environments')
|
||||
mock_merge = self.patchobject(env_util, 'merge_environments')
|
||||
|
||||
# Patch _resolve_all_attributes or it tries to call novaclient
|
||||
self.patchobject(resource.Resource, '_resolve_all_attributes',
|
||||
|
|
|
@ -48,3 +48,53 @@ class TestEnvironmentUtil(common.HeatTestCase):
|
|||
param_strategy = env_util.get_param_merge_strategy(merge_strategies,
|
||||
'param1')
|
||||
self.assertEqual(env_util.OVERWRITE, param_strategy)
|
||||
|
||||
|
||||
class TestMergeEnvironments(common.HeatTestCase):
|
||||
|
||||
def test_merge_environments(self):
|
||||
# Setup
|
||||
params = {'parameters': {
|
||||
'p0': 'CORRECT',
|
||||
'p1': 'INCORRECT',
|
||||
'p2': 'INCORRECT'}
|
||||
}
|
||||
env_1 = '''
|
||||
{'parameters' : {
|
||||
'p1': 'CORRECT',
|
||||
'p2': 'INCORRECT-ENV-1',
|
||||
}}'''
|
||||
env_2 = '''
|
||||
{'parameters': {
|
||||
'p2': 'CORRECT'
|
||||
}}'''
|
||||
|
||||
files = {'env_1': env_1, 'env_2': env_2}
|
||||
environment_files = ['env_1', 'env_2']
|
||||
|
||||
# Test
|
||||
env_util.merge_environments(environment_files, files, params)
|
||||
|
||||
# Verify
|
||||
expected = {'parameters': {
|
||||
'p0': 'CORRECT',
|
||||
'p1': 'CORRECT',
|
||||
'p2': 'CORRECT',
|
||||
}}
|
||||
self.assertEqual(expected, params)
|
||||
|
||||
def test_merge_environments_no_env_files(self):
|
||||
params = {'parameters': {'p0': 'CORRECT'}}
|
||||
env_1 = '''
|
||||
{'parameters' : {
|
||||
'p0': 'INCORRECT',
|
||||
}}'''
|
||||
|
||||
files = {'env_1': env_1}
|
||||
|
||||
# Test - Should ignore env_1 in files
|
||||
env_util.merge_environments(None, files, params)
|
||||
|
||||
# Verify
|
||||
expected = {'parameters': {'p0': 'CORRECT'}}
|
||||
self.assertEqual(expected, params)
|
||||
|
|
|
@ -21,6 +21,7 @@ from oslo_serialization import jsonutils as json
|
|||
import six
|
||||
|
||||
from heat.common import context
|
||||
from heat.common import environment_util as env_util
|
||||
from heat.common import exception
|
||||
from heat.common import identifier
|
||||
from heat.common import template_format
|
||||
|
@ -1165,7 +1166,7 @@ class StackServiceTest(common.HeatTestCase):
|
|||
self._preview_stack)
|
||||
self.assertEqual(exception.StackValidationFailed, ex.exc_info[0])
|
||||
|
||||
@mock.patch.object(service.EngineService, '_merge_environments')
|
||||
@mock.patch.object(env_util, 'merge_environments')
|
||||
def test_preview_environment_files(self, mock_merge):
|
||||
# Setup
|
||||
environment_files = ['env_1']
|
||||
|
|
Loading…
Reference in New Issue