1 # Copyright 2017 ZTE Corporation.
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
7 # http://www.apache.org/licenses/LICENSE-2.0
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.
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
21 logger = logging.getLogger(__name__)
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')
31 NFV_NS_RELATIONSHIPS = [["tosca.relationships.nfv.VirtualLinksTo", "tosca.relationships.DependsOn"], []]
34 class NsdInfoModel(BaseInfoModel):
35 def __init__(self, path, params):
36 super(NsdInfoModel, self).__init__(path, params)
38 def parseModel(self, tosca):
39 metadata = self.buildMetadata(tosca)
41 if self._is_etsi(metadata):
42 self.model = EtsiNsdInfoModel(tosca)
43 elif self._is_ecomp(metadata):
44 self.model = SdcServiceModel(tosca)
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
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
54 class EtsiNsdInfoModel(BaseInfoModel):
56 def __init__(self, tosca):
57 super(EtsiNsdInfoModel, self).__init__(tosca=tosca)
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 = list(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)
75 def _get_all_vnf(self, nodeTemplates, node_types):
77 for node in nodeTemplates:
78 if self.isNodeTypeX(node, node_types, NS_VNF_TYPE):
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)
90 def _get_all_pnf(self, nodeTemplates, node_types):
92 for node in nodeTemplates:
93 if self.isNodeTypeX(node, node_types, NS_PNF_TYPE):
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)
102 def _get_all_vl(self, nodeTemplates, node_types):
104 for node in nodeTemplates:
105 if self.isNodeTypeX(node, node_types, NS_VL_TYPE):
107 vl['vl_id'] = node['name']
108 vl['description'] = node['description']
109 vl['properties'] = node['properties']
113 def _get_all_fp(self, nodeTemplates, node_types):
115 for node in nodeTemplates:
116 if self.isNodeTypeX(node, node_types, NS_NFP_TYPE):
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)
125 def _getForwarderList(self, node, node_templates, node_types):
127 if 'requirements' in node:
128 for item in node['requirements']:
129 for key, value in list(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']})
138 forwarderList.append({"type": type, "node_name": req_node_name, "capability": ""})
141 def _get_all_vnffg(self, groups, group_types):
144 if self.isGroupTypeX(group, group_types, NS_VNFFG_TYPE):
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
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}
161 def _get_external_cps(self, subs_mappings):
163 if 'requirements' in subs_mappings:
164 for key, value in list(subs_mappings['requirements'].items()):
165 if isinstance(value, list) and len(value) > 0:
166 external_cps.append({"key_name": key, "cpd_id": value[0]})
168 external_cps.append({"key_name": key, "cpd_id": value})
171 def _get_forward_cps(self, subs_mappings):
173 if 'capabilities' in subs_mappings:
174 for key, value in list(subs_mappings['capabilities'].items()):
175 if isinstance(value, list) and len(value) > 0:
176 forward_cps.append({"key_name": key, "cpd_id": value[0]})
178 forward_cps.append({"key_name": key, "cpd_id": value})
181 def _get_all_nested_ns(self, nodes, node_types):
184 if self.isNodeTypeX(node, node_types, NS_TYPE):
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)
193 def _get_networks(self, node, node_types):
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 list(item.items()):
198 rets.append({"key_name": key, "vl_id": self.get_requirement_node_name(value)})
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