edit activity workflow plan for NS INIT
[vfc/nfvo/lcm.git] / lcm / pub / utils / toscaparser / nsdmodel.py
1 # Copyright 2017 ZTE Corporation.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #         http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 import functools
16
17 from lcm.pub.utils.toscaparser.basemodel import BaseInfoModel
18
19
20 class EtsiNsdInfoModel(BaseInfoModel):
21
22     def __init__(self, path, params):
23         tosca = self.buildToscaTemplate(path, params)
24         self.parseModel(tosca)
25
26     def parseModel(self, tosca):
27         self.buidMetadata(tosca)
28         if hasattr(tosca, 'topology_template') and hasattr(tosca.topology_template, 'inputs'):
29             self.inputs = self.buildInputs(tosca.topology_template.inputs)
30
31         nodeTemplates = map(functools.partial(self.buildNode, inputs=tosca.inputs, parsed_params=tosca.parsed_params),
32                             tosca.nodetemplates)
33
34         self.vnfs = self._get_all_vnf(nodeTemplates)
35         self.pnfs = self._get_all_pnf(nodeTemplates)
36         self.vls = self.get_all_vl(nodeTemplates)
37         self.cps = self.get_all_cp(nodeTemplates)
38         self.routers = self.get_all_router(nodeTemplates)
39         self.fps = self._get_all_fp(nodeTemplates)
40         self.vnffgs = self._get_all_vnffg(tosca.topology_template.groups)
41         self.server_groups = self.get_all_server_group(tosca.topology_template.groups)
42         self.ns_exposed = self.get_all_endpoint_exposed(tosca.topology_template)
43         self.policies = self._get_policies_scaling(tosca.topology_template.policies)
44         self.ns_flavours = self.get_all_flavour(tosca.topology_template.groups)
45         self.nested_ns = self.get_all_nested_ns(nodeTemplates)
46
47
48     def buildInputs(self, top_inputs):
49         ret = {}
50         for tmpinput in top_inputs:
51             tmp = {}
52             tmp['type'] = tmpinput.type
53             tmp['description'] = tmpinput.description
54             tmp['default'] = tmpinput.default
55
56             ret[tmpinput.name] = tmp
57         return ret
58
59     def buildNode(self, nodeTemplate, inputs, parsed_params):
60         ret ={}
61         ret['name'] = nodeTemplate.name
62         ret['nodeType'] = nodeTemplate.type
63         if 'description' in nodeTemplate.entity_tpl:
64             ret['description'] = nodeTemplate.entity_tpl['description']
65         else:
66             ret['description'] = ''
67         props = self.buildProperties(nodeTemplate, parsed_params)
68         ret['properties'] = self.verify_properties(props, inputs, parsed_params)
69         ret['requirements'] = self.build_requirements(nodeTemplate)
70         self.buildCapabilities(nodeTemplate, inputs, ret)
71         self.buildArtifacts(nodeTemplate, inputs, ret)
72         interfaces = self.build_interfaces(nodeTemplate)
73         if interfaces: ret['interfaces'] = interfaces
74         return ret
75
76     def _get_all_vnf(self, nodeTemplates):
77         vnfs = []
78         for node in nodeTemplates:
79             if self.isVnf(node):
80                 vnf = {}
81                 vnf['vnf_id'] = node['name']
82                 vnf['description'] = node['description']
83                 vnf['properties'] = node['properties']
84                 vnf['dependencies'] = map(lambda x: self.get_requirement_node_name(x), self.getNodeDependencys(node))
85                 vnf['networks'] = self.get_networks(node)
86
87                 vnfs.append(vnf)
88         return vnfs
89
90     def _get_all_pnf(self, nodeTemplates):
91         pnfs = []
92         for node in nodeTemplates:
93             if self.isPnf(node):
94                 pnf = {}
95                 pnf['pnf_id'] = node['name']
96                 pnf['description'] = node['description']
97                 pnf['properties'] = node['properties']
98                 pnf['cps'] = self.getVirtalBindingCpIds(node, nodeTemplates)
99
100                 pnfs.append(pnf)
101         return pnfs
102
103     def getVirtalBindingCpIds(self, node, nodeTemplates):
104         return map(lambda x: x['name'], self.getVirtalBindingCps(node, nodeTemplates))
105
106     def getVirtalBindingCps(self, node, nodeTemplates):
107         cps = []
108         for tmpnode in nodeTemplates:
109             if 'requirements' in tmpnode:
110                 for item in tmpnode['requirements']:
111                     for key, value in item.items():
112                         if key.upper().startswith('VIRTUALBINDING'):
113                             req_node_name = self.get_requirement_node_name(value)
114                             if req_node_name != None and req_node_name == node['name']:
115                                 cps.append(tmpnode)
116         return cps
117
118     def get_all_vl(self, nodeTemplates):
119         vls = []
120         for node in nodeTemplates:
121             if self.isVl(node):
122                 vl = {}
123                 vl['vl_id'] = node['name']
124                 vl['description'] = node['description']
125                 vl['properties'] = node['properties']
126                 vl['route_external'] = False
127                 vl['route_id'] = self._get_vl_route_id(node)
128                 vls.append(vl)
129             if self._isExternalVL(node):
130                 vl = {}
131                 vl['vl_id'] = node['name']
132                 vl['description'] = node['description']
133                 vl['properties'] = node['properties']
134                 vl['route_external'] = True
135                 vls.append(vl)
136         return vls
137
138     def _get_vl_route_id(self, node):
139         route_ids = map(lambda x: self.get_requirement_node_name(x),
140                         self.getRequirementByName(node, 'virtual_route'))
141         if len(route_ids) > 0:
142             return route_ids[0]
143         return ""
144
145     def _isExternalVL(self, node):
146         return node['nodeType'].upper().find('.ROUTEEXTERNALVL') >= 0
147
148     def get_all_cp(self, nodeTemplates):
149         cps = []
150         for node in nodeTemplates:
151             if self.isCp(node):
152                 cp = {}
153                 cp['cp_id'] = node['name']
154                 cp['cpd_id'] = node['name']
155                 cp['description'] = node['description']
156                 cp['properties'] = node['properties']
157                 cp['vl_id'] = self.get_node_vl_id(node)
158                 binding_node_ids = map(lambda x: self.get_requirement_node_name(x), self.getVirtualbindings(node))
159                 #                 cp['vnf_id'] = self._filter_vnf_id(binding_node_ids, nodeTemplates)
160                 cp['pnf_id'] = self._filter_pnf_id(binding_node_ids, nodeTemplates)
161                 vls = self.buil_cp_vls(node)
162                 if len(vls) > 1:
163                     cp['vls'] = vls
164                 cps.append(cp)
165         return cps
166
167     def buil_cp_vls(self, node):
168         return map(lambda x: self._build_cp_vl(x), self.getVirtualLinks(node))
169
170     def _build_cp_vl(self, req):
171         cp_vl = {}
172         cp_vl['vl_id'] = self.get_prop_from_obj(req, 'node')
173         relationship = self.get_prop_from_obj(req, 'relationship')
174         if relationship != None:
175             properties = self.get_prop_from_obj(relationship, 'properties')
176             if properties != None and isinstance(properties, dict):
177                 for key, value in properties.items():
178                     cp_vl[key] = value
179         return cp_vl
180
181     def _filter_pnf_id(self, node_ids, node_templates):
182         for node_id in node_ids:
183             node = self.get_node_by_name(node_templates, node_id)
184             if self.isPnf(node):
185                 return node_id
186         return ""
187
188     def get_all_router(self, nodeTemplates):
189         rets = []
190         for node in nodeTemplates:
191             if self._isRouter(node):
192                 ret = {}
193                 ret['router_id'] = node['name']
194                 ret['description'] = node['description']
195                 ret['properties'] = node['properties']
196                 ret['external_vl_id'] = self._get_router_external_vl_id(node)
197                 ret['external_ip_addresses'] = self._get_external_ip_addresses(node)
198
199                 rets.append(ret)
200         return rets
201
202     def _isRouter(self, node):
203         return node['nodeType'].upper().find('.ROUTER.') >= 0 or node['nodeType'].upper().endswith('.ROUTER')
204
205     def _get_router_external_vl(self, node):
206         return self.getRequirementByName(node, 'external_virtual_link')
207
208     def _get_router_external_vl_id(self, node):
209         ids = map(lambda x: self.get_requirement_node_name(x), self._get_router_external_vl(node))
210         if len(ids) > 0:
211             return ids[0]
212         return ""
213
214     def _get_external_ip_addresses(self, node):
215         external_vls = self._get_router_external_vl(node)
216         if len(external_vls) > 0:
217             if 'relationship' in external_vls[0] and 'properties' in external_vls[0]['relationship'] and 'router_ip_address' in external_vls[0]['relationship']['properties']:
218                 return external_vls[0]['relationship']['properties']['router_ip_address']
219         return []
220
221     def _get_all_fp(self, nodeTemplates):
222         fps = []
223         for node in nodeTemplates:
224             if self._isFp(node):
225                 fp = {}
226                 fp['fp_id'] = node['name']
227                 fp['description'] = node['description']
228                 fp['properties'] = node['properties']
229                 fp['forwarder_list'] = self._getForwarderList(node, nodeTemplates)
230
231                 fps.append(fp)
232         return fps
233
234     def _isFp(self, node):
235         return node['nodeType'].upper().find('.FP.') >= 0 or node['nodeType'].upper().find('.SFP.') >= 0 or node[
236             'nodeType'].upper().endswith('.FP') or node['nodeType'].upper().endswith('.SFP')
237
238     def _getForwarderList(self, node, node_templates):
239         forwarderList = []
240         if 'requirements' in node:
241             for item in node['requirements']:
242                 for key, value in item.items():
243                     if key == 'forwarder':
244                         tmpnode = self.get_node_by_req(node_templates, value)
245                         type = 'cp' if self.isCp(tmpnode) else 'vnf'
246                         req_node_name = self.get_requirement_node_name(value)
247                         if isinstance(value, dict) and 'capability' in value:
248                             forwarderList.append(
249                                 {"type": type, "node_name": req_node_name, "capability": value['capability']})
250                         else:
251                             forwarderList.append({"type": type, "node_name": req_node_name, "capability": ""})
252
253         return forwarderList
254
255     def get_node_by_req(self, node_templates, req):
256         req_node_name = self.get_requirement_node_name(req)
257         return self.get_node_by_name(node_templates, req_node_name)
258
259     def _get_all_vnffg(self, groups):
260         vnffgs = []
261         for group in groups:
262             if self._isVnffg(group):
263                 vnffg = {}
264                 vnffg['vnffg_id'] = group.name
265                 vnffg['description'] = group.description
266                 if 'properties' in group.tpl:
267                     vnffg['properties'] = group.tpl['properties']
268                 vnffg['members'] = group.members
269
270                 vnffgs.append(vnffg)
271         return vnffgs
272
273     def _isVnffg(self, group):
274         return group.type.upper().find('.VNFFG.') >= 0 or group.type.upper().find(
275             '.SFC.') >= 0 or group.type.upper().endswith('.VNFFG') or group.type.upper().endswith('.SFC')
276
277     def get_all_server_group(self, groups):
278         rets = []
279         for group in groups:
280             if self._isServerGroup(group):
281                 ret = {}
282                 ret['group_id'] = group.name
283                 ret['description'] = group.description
284                 if 'properties' in group.tpl:
285                     ret['properties'] = group.tpl['properties']
286                 ret['members'] = group.members
287
288                 rets.append(ret)
289         return rets
290
291     def _isServerGroup(self, group):
292         return group.type.upper().find('.AFFINITYORANTIAFFINITYGROUP.') >= 0 or group.type.upper().endswith(
293             '.AFFINITYORANTIAFFINITYGROUP')
294
295     def get_all_endpoint_exposed(self, topo_tpl):
296         if 'substitution_mappings' in topo_tpl.tpl:
297             external_cps = self._get_external_cps(topo_tpl.tpl['substitution_mappings'])
298             forward_cps = self._get_forward_cps(topo_tpl.tpl['substitution_mappings'])
299             return {"external_cps": external_cps, "forward_cps": forward_cps}
300         return {}
301
302     def _get_external_cps(self, subs_mappings):
303         external_cps = []
304         if 'requirements' in subs_mappings:
305             for key, value in subs_mappings['requirements'].items():
306                 if isinstance(value, list) and len(value) > 0:
307                     external_cps.append({"key_name": key, "cpd_id": value[0]})
308                 else:
309                     external_cps.append({"key_name": key, "cpd_id": value})
310         return external_cps
311
312     def _get_forward_cps(self, subs_mappings):
313         forward_cps = []
314         if 'capabilities' in subs_mappings:
315             for key, value in subs_mappings['capabilities'].items():
316                 if isinstance(value, list) and len(value) > 0:
317                     forward_cps.append({"key_name": key, "cpd_id": value[0]})
318                 else:
319                     forward_cps.append({"key_name": key, "cpd_id": value})
320         return forward_cps
321
322     def _get_policies_scaling(self, top_policies):
323         policies_scaling = []
324         scaling_policies = self.get_scaling_policies(top_policies)
325         if len(scaling_policies) > 0:
326             policies_scaling.append({"scaling": scaling_policies})
327         return policies_scaling
328
329     def get_policies_by_keyword(self, top_policies, keyword):
330         ret = []
331         for policy in top_policies:
332             if policy.type.upper().find(keyword) >= 0:
333                 tmp = {}
334                 tmp['policy_id'] = policy.name
335                 tmp['description'] = policy.description
336                 if 'properties' in policy.entity_tpl:
337                     tmp['properties'] = policy.entity_tpl['properties']
338                 tmp['targets'] = policy.targets
339                 ret.append(tmp)
340
341         return ret
342
343     def get_scaling_policies(self, top_policies):
344         return self.get_policies_by_keyword(top_policies, '.SCALING')
345
346     def get_all_flavour(self, groups):
347         rets = []
348         for group in groups:
349             if self._isFlavour(group):
350                 ret = {}
351                 ret['flavour_id'] = group.name
352                 ret['description'] = group.description
353                 if 'properties' in group.tpl:
354                     ret['properties'] = group.tpl['properties']
355                 ret['members'] = group.members
356
357                 rets.append(ret)
358         return rets
359
360     def _isFlavour(self, group):
361         return group.type.upper().find('FLAVOUR') >= 0