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])
72 def _nodetemplates(self):
74 tpls = self._tpl_nodetemplates()
77 tpl = NodeTemplate(name, tpls, self.custom_defs,
78 self.relationship_templates,
80 if (tpl.type_definition and
81 (tpl.type in tpl.type_definition.TOSCA_DEF or
82 (tpl.type not in tpl.type_definition.TOSCA_DEF and
83 bool(tpl.custom_def)))):
85 nodetemplates.append(tpl)
88 def _relationship_templates(self):
90 tpls = self._tpl_relationship_templates()
92 tpl = RelationshipTemplate(tpls[name], name, self.custom_defs)
93 rel_templates.append(tpl)
98 for name, attrs in self._tpl_outputs().items():
99 output = Output(name, attrs)
101 outputs.append(output)
104 def _substitution_mappings(self):
109 for policy in self._tpl_policies():
110 for policy_name, policy_tpl in policy.items():
111 target_list = policy_tpl.get('targets')
112 if target_list and len(target_list) >= 1:
114 targets_type = "groups"
115 target_objects = self._get_policy_groups(target_list)
116 if not target_objects:
117 targets_type = "node_templates"
118 target_objects = self._get_group_members(target_list)
119 policyObj = Policy(policy_name, policy_tpl,
120 target_objects, targets_type,
122 policies.append(policyObj)
128 for group_name, group_tpl in self._tpl_groups().items():
129 member_names = group_tpl.get('members')
130 if member_names is not None:
131 DataEntity.validate_datatype('list', member_names)
132 if len(member_names) < 1 or \
133 len(member_names) != len(set(member_names)):
134 exception.ExceptionCollector.appendException(
135 exception.InvalidGroupTargetException(
136 message=_('Member nodes "%s" should be >= 1 '
137 'and not repeated') % member_names))
139 member_nodes = self._get_group_members(member_names)
140 group = Group(group_name, group_tpl,
146 def _get_group_members(self, member_names):
148 self._validate_group_members(member_names)
149 for member in member_names:
150 for node in self.nodetemplates:
151 if node.name == member:
152 member_nodes.append(node)
155 def _get_policy_groups(self, member_names):
157 for member in member_names:
158 for group in self.groups:
159 if group.name == member:
160 member_groups.append(group)
163 def _validate_group_members(self, members):
165 for node in self.nodetemplates:
166 node_names.append(node.name)
167 for member in members:
168 if member not in node_names:
169 exception.ExceptionCollector.appendException(
170 exception.InvalidGroupTargetException(
171 message=_('Target member "%s" is not found in '
172 'node_templates') % member))
174 # topology template can act like node template
175 # it is exposed by substitution_mappings.
179 def capabilities(self):
182 def requirements(self):
185 def _tpl_description(self):
186 description = self.tpl.get(DESCRIPTION)
188 return description.rstrip()
190 def _tpl_inputs(self):
191 return self.tpl.get(INPUTS) or {}
193 def _tpl_nodetemplates(self):
194 return self.tpl.get(NODE_TEMPLATES)
196 def _tpl_relationship_templates(self):
197 return self.tpl.get(RELATIONSHIP_TEMPLATES) or {}
199 def _tpl_outputs(self):
200 return self.tpl.get(OUTPUTS) or {}
202 def _tpl_substitution_mappings(self):
203 return self.tpl.get(SUBSTITUION_MAPPINGS) or {}
205 def _tpl_groups(self):
206 return self.tpl.get(GROUPS) or {}
208 def _tpl_policies(self):
209 return self.tpl.get(POLICIES) or {}
211 def _validate_field(self):
212 for name in self.tpl:
213 if name not in SECTIONS:
214 exception.ExceptionCollector.appendException(
215 exception.UnknownFieldError(what='Template', field=name))
217 def _process_intrinsic_functions(self):
218 """Process intrinsic functions
220 Current implementation processes functions within node template
221 properties, requirements, interfaces inputs and template outputs.
223 if hasattr(self, 'nodetemplates'):
224 for node_template in self.nodetemplates:
225 for prop in node_template.get_properties_objects():
226 prop.value = functions.get_function(self,
229 for interface in node_template.interfaces:
231 for name, value in interface.inputs.items():
232 interface.inputs[name] = functions.get_function(
236 if node_template.requirements:
237 for req in node_template.requirements:
239 for req_name, req_item in req.items():
240 if isinstance(req_item, dict):
241 rel = req_item.get('relationship')
243 if rel and 'properties' in rel:
244 for key, value in rel['properties'].items():
245 rel['properties'][key] = \
246 functions.get_function(self,
249 if node_template.get_capabilities_objects():
250 for cap in node_template.get_capabilities_objects():
251 if cap.get_properties_objects():
252 for prop in cap.get_properties_objects():
253 propvalue = functions.get_function(
257 if isinstance(propvalue, functions.GetInput):
258 propvalue = propvalue.result()
259 for p, v in cap._properties.items():
261 cap._properties[p] = propvalue
262 for rel, node in node_template.relationships.items():
263 rel_tpls = node.relationship_tpl
265 for rel_tpl in rel_tpls:
266 for interface in rel_tpl.interfaces:
269 interface.inputs.items():
270 interface.inputs[name] = \
271 functions.get_function(self,
274 for output in self.outputs:
275 func = functions.get_function(self, self.outputs, output.value)
276 if isinstance(func, functions.GetAttribute):
277 output.attrs[output.VALUE] = func