1
"""Helpers for dealing with deployer files."""
2
from copy import deepcopy
5
from charmworld.lib.proof import ProofError
8
def parse_deployer(data, format='yaml'):
10
return yaml.safe_load(data)
11
except yaml.YAMLError, exc:
17
'Could not parse the yaml provided.'
21
class CycleDetected(Exception):
22
"""An inheritance cycle was detected in a deployment config."""
24
def __init__(self, key):
25
super(CycleDetected, self).__init__(
26
'An inheritance cycle was detected involving deployment "%s"'
30
# Utils from deployer 1
31
def relations_combine(onto, source):
32
target = deepcopy(onto)
33
# Support list of relations targets
34
if isinstance(onto, list) and isinstance(source, list):
37
for (key, value) in source.items():
39
if isinstance(target[key], dict) and isinstance(value, dict):
40
target[key] = relations_combine(target[key], value)
41
elif isinstance(target[key], list) and isinstance(value, list):
42
target[key] = list(set(target[key] + value))
48
def dict_merge(onto, source):
49
target = deepcopy(onto)
50
for (key, value) in source.items():
51
if key == 'relations' and key in target:
52
target[key] = relations_combine(target[key], value)
53
elif (key in target and isinstance(target[key], dict) and
54
isinstance(value, dict)):
55
target[key] = dict_merge(target[key], value)
62
parents = d.get('inherits', ())
63
if isinstance(parents, basestring):
68
def get_flattened_deployment(data, key, seen=None):
69
"""This flattens the inheritance hierarchy.
71
This is provided as a public API for tools, such as Charmworld, that need
72
to parse deployment configs.
77
raise CycleDetected(key)
78
deploy_data = data[key]
79
if not 'inherits' in deploy_data:
81
parents = inherits(deploy_data)
82
for parent_name in parents:
83
parent_data = get_flattened_deployment(
84
data, parent_name, seen | set([key]))
85
parents.extend(inherits(parent_data))
86
deploy_data = dict_merge(deploy_data, parent_data)
87
deploy_data['inherits'] = parents