genericparser seed code
[modeling/etsicatalog.git] / genericparser / pub / utils / toscaparsers / 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 import logging
17 from genericparser.pub.utils.toscaparsers.basemodel import BaseInfoModel
18 from genericparser.pub.utils.toscaparsers.const import SDC_SERVICE_METADATA_SECTIONS
19 from genericparser.pub.utils.toscaparsers.servicemodel import SdcServiceModel
20
21 logger = logging.getLogger(__name__)
22
23 SECTIONS = (NS_TYPE, NS_VNF_TYPE, NS_VL_TYPE, NS_PNF_TYPE, NS_NFP_TYPE, NS_VNFFG_TYPE) = \
24     ('tosca.nodes.nfv.NS',
25      'tosca.nodes.nfv.VNF',
26      'tosca.nodes.nfv.NsVirtualLink',
27      'tosca.nodes.nfv.PNF',
28      'tosca.nodes.nfv.NFP',
29      'tosca.nodes.nfv.VNFFG')
30
31 NFV_NS_RELATIONSHIPS = [["tosca.relationships.nfv.VirtualLinksTo", "tosca.relationships.DependsOn"], []]
32
33
34 class NsdInfoModel(BaseInfoModel):
35     def __init__(self, path, params):
36         super(NsdInfoModel, self).__init__(path, params)
37
38     def parseModel(self, tosca):
39         metadata = self.buildMetadata(tosca)
40         self.model = {}
41         if self._is_etsi(metadata):
42             self.model = EtsiNsdInfoModel(tosca)
43         elif self._is_ecomp(metadata):
44             self.model = SdcServiceModel(tosca)
45
46     def _is_etsi(self, metadata):
47         NS_METADATA_MUST = ["nsd_invariant_id", "nsd_name", "nsd_file_structure_version", "nsd_designer", "nsd_release_date_time"]
48         return True if len([1 for key in NS_METADATA_MUST if key in metadata]) == len(NS_METADATA_MUST) else False
49
50     def _is_ecomp(self, metadata):
51         return True if len([1 for key in SDC_SERVICE_METADATA_SECTIONS if key in metadata]) == len(SDC_SERVICE_METADATA_SECTIONS) else False
52
53
54 class EtsiNsdInfoModel(BaseInfoModel):
55
56     def __init__(self, tosca):
57         super(EtsiNsdInfoModel, self).__init__(tosca=tosca)
58
59     def parseModel(self, tosca):
60         self.metadata = self.buildMetadata(tosca)
61         self.ns = self._build_ns(tosca)
62         self.inputs = self.buildInputs(tosca)
63         nodeTemplates = map(functools.partial(self.buildNode, tosca=tosca), tosca.nodetemplates)
64         types = tosca.topology_template.custom_defs
65         self.basepath = self.get_base_path(tosca)
66         self.vnfs = self._get_all_vnf(nodeTemplates, types)
67         self.pnfs = self._get_all_pnf(nodeTemplates, types)
68         self.vls = self._get_all_vl(nodeTemplates, types)
69         self.fps = self._get_all_fp(nodeTemplates, types)
70         self.vnffgs = self._get_all_vnffg(tosca.topology_template.groups, types)
71         self.ns_exposed = self._get_all_endpoint_exposed(tosca.topology_template)
72         self.nested_ns = self._get_all_nested_ns(nodeTemplates, types)
73         self.graph = self.get_deploy_graph(tosca, NFV_NS_RELATIONSHIPS)
74
75     def _get_all_vnf(self, nodeTemplates, node_types):
76         vnfs = []
77         for node in nodeTemplates:
78             if self.isNodeTypeX(node, node_types, NS_VNF_TYPE):
79                 vnf = {}
80                 vnf['vnf_id'] = node['name']
81                 vnf['description'] = node['description']
82                 vnf['properties'] = node['properties']
83                 if not vnf['properties'].get('id', None):
84                     vnf['properties']['id'] = vnf['properties'].get('descriptor_id', None)
85                 vnf['dependencies'] = self._get_networks(node, node_types)
86                 vnf['networks'] = self._get_networks(node, node_types)
87                 vnfs.append(vnf)
88         return vnfs
89
90     def _get_all_pnf(self, nodeTemplates, node_types):
91         pnfs = []
92         for node in nodeTemplates:
93             if self.isNodeTypeX(node, node_types, NS_PNF_TYPE):
94                 pnf = {}
95                 pnf['pnf_id'] = node['name']
96                 pnf['description'] = node['description']
97                 pnf['properties'] = node['properties']
98                 pnf['networks'] = self._get_networks(node, node_types)
99                 pnfs.append(pnf)
100         return pnfs
101
102     def _get_all_vl(self, nodeTemplates, node_types):
103         vls = []
104         for node in nodeTemplates:
105             if self.isNodeTypeX(node, node_types, NS_VL_TYPE):
106                 vl = dict()
107                 vl['vl_id'] = node['name']
108                 vl['description'] = node['description']
109                 vl['properties'] = node['properties']
110                 vls.append(vl)
111         return vls
112
113     def _get_all_fp(self, nodeTemplates, node_types):
114         fps = []
115         for node in nodeTemplates:
116             if self.isNodeTypeX(node, node_types, NS_NFP_TYPE):
117                 fp = {}
118                 fp['fp_id'] = node['name']
119                 fp['description'] = node['description']
120                 fp['properties'] = node['properties']
121                 fp['forwarder_list'] = self._getForwarderList(node, nodeTemplates, node_types)
122                 fps.append(fp)
123         return fps
124
125     def _getForwarderList(self, node, node_templates, node_types):
126         forwarderList = []
127         if 'requirements' in node:
128             for item in node['requirements']:
129                 for key, value in item.items():
130                     if key == 'forwarder':
131                         tmpnode = self.get_node_by_req(node_templates, value)
132                         type = 'pnf' if self.isNodeTypeX(tmpnode, node_types, NS_PNF_TYPE) else 'vnf'
133                         req_node_name = self.get_requirement_node_name(value)
134                         if isinstance(value, dict) and 'capability' in value:
135                             forwarderList.append(
136                                 {"type": type, "node_name": req_node_name, "capability": value['capability']})
137                         else:
138                             forwarderList.append({"type": type, "node_name": req_node_name, "capability": ""})
139         return forwarderList
140
141     def _get_all_vnffg(self, groups, group_types):
142         vnffgs = []
143         for group in groups:
144             if self.isGroupTypeX(group, group_types, NS_VNFFG_TYPE):
145                 vnffg = {}
146                 vnffg['vnffg_id'] = group.name
147                 vnffg['description'] = group.description
148                 if 'properties' in group.tpl:
149                     vnffg['properties'] = group.tpl['properties']
150                 vnffg['members'] = group.members
151                 vnffgs.append(vnffg)
152         return vnffgs
153
154     def _get_all_endpoint_exposed(self, topo_tpl):
155         if 'substitution_mappings' in topo_tpl.tpl:
156             external_cps = self._get_external_cps(topo_tpl.tpl['substitution_mappings'])
157             forward_cps = self._get_forward_cps(topo_tpl.tpl['substitution_mappings'])
158             return {"external_cps": external_cps, "forward_cps": forward_cps}
159         return {}
160
161     def _get_external_cps(self, subs_mappings):
162         external_cps = []
163         if 'requirements' in subs_mappings:
164             for key, value in subs_mappings['requirements'].items():
165                 if isinstance(value, list) and len(value) > 0:
166                     external_cps.append({"key_name": key, "cpd_id": value[0]})
167                 else:
168                     external_cps.append({"key_name": key, "cpd_id": value})
169         return external_cps
170
171     def _get_forward_cps(self, subs_mappings):
172         forward_cps = []
173         if 'capabilities' in subs_mappings:
174             for key, value in subs_mappings['capabilities'].items():
175                 if isinstance(value, list) and len(value) > 0:
176                     forward_cps.append({"key_name": key, "cpd_id": value[0]})
177                 else:
178                     forward_cps.append({"key_name": key, "cpd_id": value})
179         return forward_cps
180
181     def _get_all_nested_ns(self, nodes, node_types):
182         nss = []
183         for node in nodes:
184             if self.isNodeTypeX(node, node_types, NS_TYPE):
185                 ns = {}
186                 ns['ns_id'] = node['name']
187                 ns['description'] = node['description']
188                 ns['properties'] = node['properties']
189                 ns['networks'] = self._get_networks(node, node_types)
190                 nss.append(ns)
191         return nss
192
193     def _get_networks(self, node, node_types):
194         rets = []
195         if 'requirements' in node and (self.isNodeTypeX(node, node_types, NS_TYPE) or self.isNodeTypeX(node, node_types, NS_VNF_TYPE)):
196             for item in node['requirements']:
197                 for key, value in item.items():
198                     rets.append({"key_name": key, "vl_id": self.get_requirement_node_name(value)})
199         return rets
200
201     def _build_ns(self, tosca):
202         ns = self.get_substitution_mappings(tosca)
203         properties = ns.get("properties", {})
204         metadata = ns.get("metadata", {})
205         if properties.get("descriptor_id", "") == "":
206             descriptor_id = metadata.get("nsd_id", "")
207             properties["descriptor_id"] = descriptor_id
208         if properties.get("verison", "") == "":
209             version = metadata.get("nsd_file_structure_version", "")
210             properties["verison"] = version
211         if properties.get("designer", "") == "":
212             author = metadata.get("nsd_designer", "")
213             properties["designer"] = author
214         if properties.get("name", "") == "":
215             template_name = metadata.get("nsd_name", "")
216             properties["name"] = template_name
217         if properties.get("invariant_id", "") == "":
218             nsd_invariant_id = metadata.get("nsd_invariant_id", "")
219             properties["invariant_id"] = nsd_invariant_id
220         return ns