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.substitution_mappings import SubstitutionMappings
26 from toscaparser.tpl_relationship_graph import ToscaGraph
27 from toscaparser.utils.gettextutils import _
28 from org.openecomp.sdc.toscaparser.jython import JyTopologyTemplate
31 # Topology template key names
32 SECTIONS = (DESCRIPTION, INPUTS, NODE_TEMPLATES,
33 RELATIONSHIP_TEMPLATES, OUTPUTS, GROUPS,
34 SUBSTITUION_MAPPINGS, POLICIES) = \
35 ('description', 'inputs', 'node_templates',
36 'relationship_templates', 'outputs', 'groups',
37 'substitution_mappings', 'policies')
39 log = logging.getLogger("tosca.model")
42 class TopologyTemplate(JyTopologyTemplate):
44 '''Load the template data.'''
45 def __init__(self, template, custom_defs,
46 rel_types=None, parsed_params=None,
47 sub_mapped_node_template=None):
49 self.sub_mapped_node_template = sub_mapped_node_template
51 self.custom_defs = custom_defs
52 self.rel_types = rel_types
53 self.parsed_params = parsed_params
54 self._validate_field()
55 self.description = self._tpl_description()
56 self.inputs = self._inputs()
57 self.relationship_templates = self._relationship_templates()
58 self.nodetemplates = self._nodetemplates()
59 self.outputs = self._outputs()
60 if hasattr(self, 'nodetemplates'):
61 self.graph = ToscaGraph(self.nodetemplates)
62 self.groups = self._groups()
63 self.policies = self._policies()
64 self._process_intrinsic_functions()
65 self.substitution_mappings = self._substitution_mappings()
67 def getJyDescription(self):
68 return self.description
70 def getJyNodeTemplates(self):
71 return self.nodetemplates
73 def getJyInputs(self):
76 def getJyGroups(self):
79 def getJySubstitutionMappings(self):
80 return self.substitution_mappings
84 for name, attrs in self._tpl_inputs().items():
85 input = Input(name, attrs)
86 if self.parsed_params and name in self.parsed_params:
87 input.validate(self.parsed_params[name])
89 default = input.default
91 input.validate(default)
92 if (self.parsed_params and input.name not in self.parsed_params
93 or self.parsed_params is None) and input.required \
94 and input.default is None:
95 log.warning(_('The required parameter %s '
96 'is not provided') % input.name)
101 def _nodetemplates(self):
103 tpls = self._tpl_nodetemplates()
106 tpl = NodeTemplate(name, tpls, self.custom_defs,
107 self.relationship_templates,
109 if (tpl.type_definition and
110 (tpl.type in tpl.type_definition.TOSCA_DEF or
111 (tpl.type not in tpl.type_definition.TOSCA_DEF and
112 bool(tpl.custom_def)))):
114 nodetemplates.append(tpl)
117 def _relationship_templates(self):
119 tpls = self._tpl_relationship_templates()
121 tpl = RelationshipTemplate(tpls[name], name, self.custom_defs)
122 rel_templates.append(tpl)
127 for name, attrs in self._tpl_outputs().items():
128 output = Output(name, attrs)
130 outputs.append(output)
133 def _substitution_mappings(self):
134 tpl_substitution_mapping = self._tpl_substitution_mappings()
135 # if tpl_substitution_mapping and self.sub_mapped_node_template:
136 if tpl_substitution_mapping:
137 return SubstitutionMappings(tpl_substitution_mapping,
141 self.sub_mapped_node_template,
146 for policy in self._tpl_policies():
147 for policy_name, policy_tpl in policy.items():
148 target_list = policy_tpl.get('targets')
149 if target_list and len(target_list) >= 1:
151 targets_type = "groups"
152 target_objects = self._get_policy_groups(target_list)
153 if not target_objects:
154 targets_type = "node_templates"
155 target_objects = self._get_group_members(target_list)
156 policyObj = Policy(policy_name, policy_tpl,
157 target_objects, targets_type,
159 policies.append(policyObj)
165 for group_name, group_tpl in self._tpl_groups().items():
166 member_names = group_tpl.get('members')
167 if member_names is not None:
168 DataEntity.validate_datatype('list', member_names)
169 if len(member_names) < 1 or \
170 len(member_names) != len(set(member_names)):
171 exception.ExceptionCollector.appendException(
172 exception.InvalidGroupTargetException(
173 message=_('Member nodes "%s" should be >= 1 '
174 'and not repeated') % member_names))
176 member_nodes = self._get_group_members(member_names)
177 group = Group(group_name, group_tpl,
183 def _get_group_members(self, member_names):
185 self._validate_group_members(member_names)
186 for member in member_names:
187 for node in self.nodetemplates:
188 if node.name == member:
189 member_nodes.append(node)
192 def _get_policy_groups(self, member_names):
194 for member in member_names:
195 for group in self.groups:
196 if group.name == member:
197 member_groups.append(group)
200 def _validate_group_members(self, members):
202 for node in self.nodetemplates:
203 node_names.append(node.name)
204 for member in members:
205 if member not in node_names:
206 exception.ExceptionCollector.appendException(
207 exception.InvalidGroupTargetException(
208 message=_('Target member "%s" is not found in '
209 'node_templates') % member))
211 # topology template can act like node template
212 # it is exposed by substitution_mappings.
214 return self.substitution_mappings.node_type \
215 if self.substitution_mappings else None
217 def capabilities(self):
218 return self.substitution_mappings.capabilities \
219 if self.substitution_mappings else None
221 def requirements(self):
222 return self.substitution_mappings.requirements \
223 if self.substitution_mappings else None
225 def _tpl_description(self):
226 description = self.tpl.get(DESCRIPTION)
228 return description.rstrip()
230 def _tpl_inputs(self):
231 return self.tpl.get(INPUTS) or {}
233 def _tpl_nodetemplates(self):
234 return self.tpl.get(NODE_TEMPLATES)
236 def _tpl_relationship_templates(self):
237 return self.tpl.get(RELATIONSHIP_TEMPLATES) or {}
239 def _tpl_outputs(self):
240 return self.tpl.get(OUTPUTS) or {}
242 def _tpl_substitution_mappings(self):
243 return self.tpl.get(SUBSTITUION_MAPPINGS) or {}
245 def _tpl_groups(self):
246 return self.tpl.get(GROUPS) or {}
248 def _tpl_policies(self):
249 return self.tpl.get(POLICIES) or {}
251 def _validate_field(self):
252 for name in self.tpl:
253 if name not in SECTIONS:
254 exception.ExceptionCollector.appendException(
255 exception.UnknownFieldError(what='Template', field=name))
257 def _process_intrinsic_functions(self):
258 """Process intrinsic functions
260 Current implementation processes functions within node template
261 properties, requirements, interfaces inputs and template outputs.
263 if hasattr(self, 'nodetemplates'):
264 for node_template in self.nodetemplates:
265 for prop in node_template.get_properties_objects():
266 prop.value = functions.get_function(self,
269 for interface in node_template.interfaces:
271 for name, value in interface.inputs.items():
272 interface.inputs[name] = functions.get_function(
276 if node_template.requirements and \
277 isinstance(node_template.requirements, list):
278 for req in node_template.requirements:
280 for req_name, req_item in req.items():
281 if isinstance(req_item, dict):
282 rel = req_item.get('relationship')
284 if rel and 'properties' in rel:
285 for key, value in rel['properties'].items():
286 rel['properties'][key] = \
287 functions.get_function(self,
290 if node_template.get_capabilities_objects():
291 for cap in node_template.get_capabilities_objects():
292 if cap.get_properties_objects():
293 for prop in cap.get_properties_objects():
294 propvalue = functions.get_function(
298 if isinstance(propvalue, functions.GetInput):
299 propvalue = propvalue.result()
300 for p, v in cap._properties.items():
302 cap._properties[p] = propvalue
303 for rel, node in node_template.relationships.items():
304 rel_tpls = node.relationship_tpl
306 for rel_tpl in rel_tpls:
307 for interface in rel_tpl.interfaces:
310 interface.inputs.items():
311 interface.inputs[name] = \
312 functions.get_function(self,
315 for output in self.outputs:
316 func = functions.get_function(self, self.outputs, output.value)
317 if isinstance(func, functions.GetAttribute):
318 output.attrs[output.VALUE] = func
321 def get_sub_mapping_node_type(cls, topology_tpl):
322 if topology_tpl and isinstance(topology_tpl, dict):
323 submap_tpl = topology_tpl.get(SUBSTITUION_MAPPINGS)
324 return SubstitutionMappings.get_node_type(submap_tpl)