diff options
author | rabi <ramishra@redhat.com> | 2016-08-04 10:56:41 +0530 |
---|---|---|
committer | rabi <ramishra@redhat.com> | 2016-08-22 17:35:01 +0530 |
commit | 5b0fe812706e2bd23d0ec7836f8e120a25f2489f (patch) | |
tree | d830bb786b48421b0f205a9121769f46fdb9a2b3 /heat/common/environment_util.py | |
parent | 59b2a559ecf7c9302a1d8bd835ba4ea9380bbc0e (diff) | |
download | heat-5b0fe812706e2bd23d0ec7836f8e120a25f2489f.tar.gz |
Improve deep merge for parameters
This allows for merging lists and deep merging maps.
This does not support comma_delimited_lists and is
implemented by using parameter schema in the subsequent
patches.
Change-Id: I89df95eca713a7125cc53ed8bf352274f28bf6d9
Blueprint: environment_merging
Diffstat (limited to 'heat/common/environment_util.py')
-rw-r--r-- | heat/common/environment_util.py | 57 |
1 files changed, 44 insertions, 13 deletions
diff --git a/heat/common/environment_util.py b/heat/common/environment_util.py index b19a4606d..833ee0c81 100644 --- a/heat/common/environment_util.py +++ b/heat/common/environment_util.py @@ -12,7 +12,9 @@ # under the License. import collections -from heat.common import environment_format +import six + +from heat.common import environment_format as env_fmt ALLOWED_PARAM_MERGE_STRATEGIES = (OVERWRITE, MERGE, DEEP_MERGE) = ( 'overwrite', 'merge', 'deep_merge') @@ -32,14 +34,37 @@ def get_param_merge_strategy(merge_strategies, param_key): return env_default -def deep_update(old, new): - '''Merge nested dictionaries.''' +def merge_list(old, new): + """merges lists and comma delimited lists.""" + if not old: + return new + + if isinstance(new, list): + old.extend(new) + return old + else: + return ','.join([old, new]) + + +def merge_map(old, new, deep_merge=False): + """Merge nested dictionaries.""" + if not old: + return new + 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] + if v: + if not deep_merge: + old[k] = v + elif isinstance(v, collections.Mapping): + old_v = old.get(k) + old[k] = merge_map(old_v, v, deep_merge) if old_v else v + elif (isinstance(v, collections.Sequence) and + not isinstance(v, six.string_types)): + old_v = old.get(k) + old[k] = merge_list(old_v, v) if old_v else v + else: + old[k] = v + return old @@ -60,8 +85,14 @@ def merge_environments(environment_files, files, params): :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) + if not environment_files: + return + + for filename in environment_files: + raw_env = files[filename] + parsed_env = env_fmt.parse(raw_env) + for section_key, section_value in parsed_env.items(): + if section_value: + params[section_key] = merge_map(params[section_key], + section_value, + deep_merge=True) |