1 # Licensed under the Apache License, Version 2.0 (the "License"); you may
2 # not use this file except in compliance with the License. You may obtain
3 # a copy of the License at
5 # http://www.apache.org/licenses/LICENSE-2.0
7 # Unless required by applicable law or agreed to in writing, software
8 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10 # License for the specific language governing permissions and limitations
16 from toscaparser.common import exception
17 from toscaparser.dataentity import DataEntity
18 from toscaparser import functions
19 from toscaparser.groups import Group
20 from toscaparser.nodetemplate import NodeTemplate
21 from toscaparser.parameters import Input
22 from toscaparser.parameters import Output
23 from toscaparser.policy import Policy
24 from toscaparser.relationship_template import RelationshipTemplate
25 from toscaparser.tpl_relationship_graph import ToscaGraph
26 from toscaparser.utils.gettextutils import _
29 # Topology template key names
30 SECTIONS = (DESCRIPTION, INPUTS, NODE_TEMPLATES,
31 RELATIONSHIP_TEMPLATES, OUTPUTS, GROUPS,
32 SUBSTITUION_MAPPINGS, POLICIES) = \
33 ('description', 'inputs', 'node_templates',
34 'relationship_templates', 'outputs', 'groups',
35 'substitution_mappings', 'policies')
37 log = logging.getLogger("tosca.model")
40 class TopologyTemplate(object):
42 '''Load the template data.'''
43 def __init__(self, template, custom_defs,
44 rel_types=None, parsed_params=None):
47 self.custom_defs = custom_defs
48 self.rel_types = rel_types
49 self.parsed_params = parsed_params
50 self._validate_field()
51 self.description = self._tpl_description()
52 self.inputs = self._inputs()
53 self.relationship_templates = self._relationship_templates()
54 self.nodetemplates = self._nodetemplates()
55 self.outputs = self._outputs()
56 if hasattr(self, 'nodetemplates'):
57 self.graph = ToscaGraph(self.nodetemplates)
58 self.groups = self._groups()
59 self.policies = self._policies()
60 self._process_intrinsic_functions()
61 self.substitution_mappings = self._substitution_mappings()
65 for name, attrs in self._tpl_inputs().items():
66 input = Input(name, attrs)
67 if self.parsed_params and name in self.parsed_params:
68 input.validate(self.parsed_params[name])
70 default = input.default
72 input.validate(default)
76 def _nodetemplates(self):
78 tpls = self._tpl_nodetemplates()
81 tpl = NodeTemplate(name, tpls, self.custom_defs,
82 self.relationship_templates,
84 if (tpl.type_definition and
85 (tpl.type in tpl.type_definition.TOSCA_DEF or
86 (tpl.type not in tpl.type_definition.TOSCA_DEF and
87 bool(tpl.custom_def)))):
89 nodetemplates.append(tpl)
92 def _relationship_templates(self):
94 tpls = self._tpl_relationship_templates()
96 tpl = RelationshipTemplate(tpls[name], name, self.custom_defs)
97 rel_templates.append(tpl)
102 for name, attrs in self._tpl_outputs().items():
103 output = Output(name, attrs)
105 outputs.append(output)
108 def _substitution_mappings(self):
113 for policy in self._tpl_policies():
114 for policy_name, policy_tpl in policy.items():
115 target_list = policy_tpl.get('targets')
116 if target_list and len(target_list) >= 1:
118 targets_type = "groups"
119 target_objects = self._get_policy_groups(target_list)
120 if not target_objects:
121 targets_type = "node_templates"
122 target_objects = self._get_group_members(target_list)
123 policyObj = Policy(policy_name, policy_tpl,
124 target_objects, targets_type,
126 policies.append(policyObj)
132 for group_name, group_tpl in self._tpl_groups().items():
133 member_names = group_tpl.get('members')
134 if member_names is not None:
135 DataEntity.validate_datatype('list', member_names)
136 if len(member_names) < 1 or \
137 len(member_names) != len(set(member_names)):
138 exception.ExceptionCollector.appendException(
139 exception.InvalidGroupTargetException(
140 message=_('Member nodes "%s" should be >= 1 '
141 'and not repeated') % member_names))
143 member_nodes = self._get_group_members(member_names)
144 group = Group(group_name, group_tpl,
150 def _get_group_members(self, member_names):
152 self._validate_group_members(member_names)
153 for member in member_names:
154 for node in self.nodetemplates:
155 if node.name == member:
156 member_nodes.append(node)
159 def _get_policy_groups(self, member_names):
161 for member in member_names:
162 for group in self.groups:
163 if group.name == member:
164 member_groups.append(group)
167 def _validate_group_members(self, members):
169 for node in self.nodetemplates:
170 node_names.append(node.name)
171 for member in members:
172 if member not in node_names:
173 exception.ExceptionCollector.appendException(
174 exception.InvalidGroupTargetException(
175 message=_('Target member "%s" is not found in '
176 'node_templates') % member))
178 # topology template can act like node template
179 # it is exposed by substitution_mappings.
183 def capabilities(self):
186 def requirements(self):
189 def _tpl_description(self):
190 description = self.tpl.get(DESCRIPTION)
192 return description.rstrip()
194 def _tpl_inputs(self):
195 return self.tpl.get(INPUTS) or {}
197 def _tpl_nodetemplates(self):
198 return self.tpl.get(NODE_TEMPLATES)
200 def _tpl_relationship_templates(self):
201 return self.tpl.get(RELATIONSHIP_TEMPLATES) or {}
203 def _tpl_outputs(self):
204 return self.tpl.get(OUTPUTS) or {}
206 def _tpl_substitution_mappings(self):
207 return self.tpl.get(SUBSTITUION_MAPPINGS) or {}
209 def _tpl_groups(self):
210 return self.tpl.get(GROUPS) or {}
212 def _tpl_policies(self):
213 return self.tpl.get(POLICIES) or {}
215 def _validate_field(self):
216 for name in self.tpl:
217 if name not in SECTIONS:
218 exception.ExceptionCollector.appendException(
219 exception.UnknownFieldError(what='Template', field=name))
221 def _process_intrinsic_functions(self):
222 """Process intrinsic functions
224 Current implementation processes functions within node template
225 properties, requirements, interfaces inputs and template outputs.
227 if hasattr(self, 'nodetemplates'):
228 for node_template in self.nodetemplates:
229 for prop in node_template.get_properties_objects():
230 prop.value = functions.get_function(self,
233 for interface in node_template.interfaces:
235 for name, value in interface.inputs.items():
236 interface.inputs[name] = functions.get_function(
240 if node_template.requirements:
241 for req in node_template.requirements:
243 for req_name, req_item in req.items():
244 if isinstance(req_item, dict):
245 rel = req_item.get('relationship')
247 if rel and 'properties' in rel:
248 for key, value in rel['properties'].items():
249 rel['properties'][key] = \
250 functions.get_function(self,
253 if node_template.get_capabilities_objects():
254 for cap in node_template.get_capabilities_objects():
255 if cap.get_properties_objects():
256 for prop in cap.get_properties_objects():
257 propvalue = functions.get_function(
261 if isinstance(propvalue, functions.GetInput):
262 propvalue = propvalue.result()
263 for p, v in cap._properties.items():
265 cap._properties[p] = propvalue
266 for rel, node in node_template.relationships.items():
267 rel_tpls = node.relationship_tpl
269 for rel_tpl in rel_tpls:
270 for interface in rel_tpl.interfaces:
273 interface.inputs.items():
274 interface.inputs[name] = \
275 functions.get_function(self,
278 for output in self.outputs:
279 func = functions.get_function(self, self.outputs, output.value)
280 if isinstance(func, functions.GetAttribute):
281 output.attrs[output.VALUE] = func