summaryrefslogtreecommitdiff
path: root/heat/common/environment_util.py
diff options
context:
space:
mode:
authorrabi <ramishra@redhat.com>2016-08-04 10:56:41 +0530
committerrabi <ramishra@redhat.com>2016-08-22 17:35:01 +0530
commit5b0fe812706e2bd23d0ec7836f8e120a25f2489f (patch)
treed830bb786b48421b0f205a9121769f46fdb9a2b3 /heat/common/environment_util.py
parent59b2a559ecf7c9302a1d8bd835ba4ea9380bbc0e (diff)
downloadheat-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.py57
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)