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()
64 for name, attrs in self._tpl_inputs().items():
65 input = Input(name, attrs)
66 if self.parsed_params and name in self.parsed_params:
67 input.validate(self.parsed_params[name])
71 def _nodetemplates(self):
73 tpls = self._tpl_nodetemplates()
76 tpl = NodeTemplate(name, tpls, self.custom_defs,
77 self.relationship_templates,
79 if (tpl.type_definition and
80 (tpl.type in tpl.type_definition.TOSCA_DEF or
81 (tpl.type not in tpl.type_definition.TOSCA_DEF and
82 bool(tpl.custom_def)))):
84 nodetemplates.append(tpl)
87 def _relationship_templates(self):
89 tpls = self._tpl_relationship_templates()
91 tpl = RelationshipTemplate(tpls[name], name, self.custom_defs)
92 rel_templates.append(tpl)
97 for name, attrs in self._tpl_outputs().items():
98 output = Output(name, attrs)
100 outputs.append(output)
103 def _substitution_mappings(self):
108 for policy in self._tpl_policies():
109 for policy_name, policy_tpl in policy.items():
110 target_list = policy_tpl.get('targets')
111 if target_list and len(target_list) >= 1:
113 targets_type = "groups"
114 target_objects = self._get_policy_groups(target_list)
115 if not target_objects:
116 targets_type = "node_templates"
117 target_objects = self._get_group_members(target_list)
118 policyObj = Policy(policy_name, policy_tpl,
119 target_objects, targets_type,
121 policies.append(policyObj)
127 for group_name, group_tpl in self._tpl_groups().items():
128 member_names = group_tpl.get('members')
129 if member_names is not None:
130 DataEntity.validate_datatype('list', member_names)
131 if len(member_names) < 1 or \
132 len(member_names) != len(set(member_names)):
133 exception.ExceptionCollector.appendException(
134 exception.InvalidGroupTargetException(
135 message=_('Member nodes "%s" should be >= 1 '
136 'and not repeated') % member_names))
138 member_nodes = self._get_group_members(member_names)
139 group = Group(group_name, group_tpl,
145 def _get_group_members(self, member_names):
147 self._validate_group_members(member_names)
148 for member in member_names:
149 for node in self.nodetemplates:
150 if node.name == member:
151 member_nodes.append(node)
154 def _get_policy_groups(self, member_names):
156 for member in member_names:
157 for group in self.groups:
158 if group.name == member:
159 member_groups.append(group)
162 def _validate_group_members(self, members):
164 for node in self.nodetemplates:
165 node_names.append(node.name)
166 for member in members:
167 if member not in node_names:
168 exception.ExceptionCollector.appendException(
169 exception.InvalidGroupTargetException(
170 message=_('Target member "%s" is not found in '
171 'node_templates') % member))
173 # topology template can act like node template
174 # it is exposed by substitution_mappings.
178 def capabilities(self):
181 def requirements(self):
184 def _tpl_description(self):
185 description = self.tpl.get(DESCRIPTION)
187 return description.rstrip()
189 def _tpl_inputs(self):
190 return self.tpl.get(INPUTS) or {}
192 def _tpl_nodetemplates(self):
193 return self.tpl.get(NODE_TEMPLATES)
195 def _tpl_relationship_templates(self):
196 return self.tpl.get(RELATIONSHIP_TEMPLATES) or {}
198 def _tpl_outputs(self):
199 return self.tpl.get(OUTPUTS) or {}
201 def _tpl_substitution_mappings(self):
202 return self.tpl.get(SUBSTITUION_MAPPINGS) or {}
204 def _tpl_groups(self):
205 return self.tpl.get(GROUPS) or {}
207 def _tpl_policies(self):
208 return self.tpl.get(POLICIES) or {}
210 def _validate_field(self):
211 for name in self.tpl:
212 if name not in SECTIONS:
213 exception.ExceptionCollector.appendException(
214 exception.UnknownFieldError(what='Template', field=name))
216 def _process_intrinsic_functions(self):
217 """Process intrinsic functions
219 Current implementation processes functions within node template
220 properties, requirements, interfaces inputs and template outputs.
222 if hasattr(self, 'nodetemplates'):
223 for node_template in self.nodetemplates:
224 for prop in node_template.get_properties_objects():
225 prop.value = functions.get_function(self,
228 for interface in node_template.interfaces:
230 for name, value in interface.inputs.items():
231 interface.inputs[name] = functions.get_function(
235 if node_template.requirements:
236 for req in node_template.requirements:
238 for req_name, req_item in req.items():
239 if isinstance(req_item, dict):
240 rel = req_item.get('relationship')
242 if rel and 'properties' in rel:
243 for key, value in rel['properties'].items():
244 rel['properties'][key] = \
245 functions.get_function(self,
248 if node_template.get_capabilities_objects():
249 for cap in node_template.get_capabilities_objects():
250 if cap.get_properties_objects():
251 for prop in cap.get_properties_objects():
252 propvalue = functions.get_function(
256 if isinstance(propvalue, functions.GetInput):
257 propvalue = propvalue.result()
258 for p, v in cap._properties.items():
260 cap._properties[p] = propvalue
261 for rel, node in node_template.relationships.items():
262 rel_tpls = node.relationship_tpl
264 for rel_tpl in rel_tpls:
265 for interface in rel_tpl.interfaces:
268 interface.inputs.items():
269 interface.inputs[name] = \
270 functions.get_function(self,
273 for output in self.outputs:
274 func = functions.get_function(self, self.outputs, output.value)
275 if isinstance(func, functions.GetAttribute):
276 output.attrs[output.VALUE] = func