improved ns topology
[osm/LW-UI.git] / lib / osm / osm_rdcl_parser.py
1 #
2 # Copyright 2018 EveryUP Srl
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 #
16
17
18 import logging
19 # from lib.rdcl_graph import RdclGraph
20 import copy
21
22 logging.basicConfig(level=logging.DEBUG)
23 log = logging.getLogger('OsmParser')
24
25
26 class RdclGraph(object):
27 """ Operates on the graph representation used for the GUI graph views """
28 node_ids = []
29 node_t3d_base = {
30 'info': {
31 'property': {
32 'custom_label': '',
33 },
34 'type': '',
35 'group': []
36 }
37 }
38
39 def __init__(self):
40 pass
41
42 def add_link(self, source, target, view, group, graph_object, optional={}):
43 if (source is None or source not in self.node_ids) or (target is None or target not in self.node_ids):
44 return
45 edge_obj = {
46 'source': source,
47 'target': target,
48 'view': view,
49 'group': [group],
50 }
51
52 edge_obj.update(optional)
53 #if edge_obj not in graph_object['edges']:
54 # graph_object['edges'].append(edge_obj)
55 graph_object['edges'].append(edge_obj)
56
57 def add_node(self, id, type, group, positions, graph_object, optional={}):
58 if id is None:
59 return
60 node = next((x for x in graph_object['vertices'] if x['id'] == id), None)
61 if node is not None:
62 node['info']['group'].append(group)
63 else:
64 node = copy.deepcopy(self.node_t3d_base)
65 node['id'] = id
66 node['info']['type'] = type
67 if group is not None:
68 node['info']['group'].append(group)
69 if positions and id in positions['vertices'] and 'x' in positions['vertices'][id] and 'y' in \
70 positions['vertices'][id]:
71 node['fx'] = positions['vertices'][id]['x']
72 node['fy'] = positions['vertices'][id]['y']
73 node['info'].update(optional)
74 graph_object['vertices'].append(node)
75 self.node_ids.append(id)
76
77 def is_directed_edge(self, source_type=None, target_type=None, layer=None, model={}):
78 if source_type is None or target_type is None or layer is None:
79 return None
80 if layer in model['layer'] and 'allowed_edges' in model['layer'][layer]:
81 if source_type in model['layer'][layer]['allowed_edges'] and target_type in \
82 model['layer'][layer]['allowed_edges'][source_type]['destination']:
83 edge_pro = model['layer'][layer]['allowed_edges'][source_type]['destination'][target_type]
84 return edge_pro['direct_edge'] if 'direct_edge' in edge_pro else False
85
86 return None
87
88
89 class OsmParser(RdclGraph):
90 """ Operates on the graph representation used for the GUI graph views """
91
92 def nsr_to_graph(self, nsr_full):
93
94 graph = {'vertices': [], 'edges': [], 'model': {
95 "layer": {
96
97 "nsr": {
98 "nodes": {
99 "vnfr": {
100 "addable": {},
101 "removable": {},
102 "expands": "vnfr"
103 },
104 "ns_vl": {
105 "addable": {},
106 "removable": {}
107 },
108 "ns_cp": {
109 "addable": {},
110 "removable": {}
111 },
112
113 },
114 "allowed_edges": {
115 "ns_vl": {
116 "destination": {
117 "vnfr": {
118 "callback": "addLink",
119 "direct_edge": False,
120 "removable": {}
121 }
122 }
123 },
124 "vnfr": {
125 "destination": {
126 "ns_vl": {
127 "callback": "addLink",
128 "direct_edge": False,
129 "removable": {}
130 },
131
132 }
133 }
134
135 }
136 },
137
138 "vnfr": {
139 "nodes": {
140 "vdur": {},
141 "cp": {},
142 "int_cp": {},
143 "vnf_vl": {}
144
145 },
146 "allowed_edges": {
147 "vdur": {
148 "destination": {
149 "cp": {
150 "direct_edge": False,
151 },
152 "int_cp": {
153 "direct_edge": False,
154 },
155 "vnf_vl": {
156 "direct_edge": False,
157 }
158 }
159 },
160 "cp": {
161 "destination": {
162 "vdur": {
163 "direct_edge": False,
164 }
165 }
166 },
167 "int_cp": {
168 "destination": {
169 "vdur": {
170 "direct_edge": False,
171 },
172 "vnf_vl": {
173 "direct_edge": False,
174 }
175 }
176 },
177 "vnf_vl": {
178 "destination": {
179 "vdur": {
180 "direct_edge": False
181 }
182 }
183 }
184 }
185 },
186 "name": "OSM",
187 "version": 1,
188 "description": "osm"
189 }
190 }, 'graph_parameters': {'view': {'nsr': {}, 'vnfr': {}}}}
191
192 nsr = nsr_full['nsr']
193
194 graph['graph_parameters']['view']['nsr'] = {}
195 nsr_graph_param = graph['graph_parameters']['view']['nsr']
196 nsr_graph_param['id'] = nsr['_id'] if '_id' in nsr else None
197 nsr_graph_param['nsdId'] = nsr['nsdId'] if 'nsdId' in nsr else None
198 nsr_graph_param['name-ref'] = nsr['name-ref'] if 'name-ref' in nsr else None
199 nsr_graph_param['operational-status'] = nsr['operational-status'] if 'operational-status' in nsr else None
200 nsr_graph_param['config-status'] = nsr['config-status'] if 'config-status' in nsr else None
201 nsr_graph_param['detailed-status'] = nsr['detailed-status'] if 'detailed-status' in nsr else None
202 nsr_graph_param['create-time'] = nsr['create-time'] if 'create-time' in nsr else None
203 nsr_graph_param['instantiate_params'] = nsr['instantiate_params'] if 'instantiate_params' in nsr else None
204
205 map_vnf_index_to_id = {}
206 for vnfr_id in nsr['constituent-vnfr-ref']:
207 current_vnfr = nsr_full['vnfr'][vnfr_id]
208
209 graph['graph_parameters']['view']['vnfr'][vnfr_id] = {}
210 vnfr_graph_param = graph['graph_parameters']['view']['vnfr'][vnfr_id]
211 vnfr_graph_param['id'] = vnfr_id
212 vnfr_graph_param['vnfd-id'] = current_vnfr['vnfd-id']
213 vnfr_graph_param['vnfd-ref'] = current_vnfr['vnfd-ref']
214 vnfr_graph_param['member-vnf-index-ref'] = current_vnfr['member-vnf-index-ref']
215 vnfr_graph_param['vim-account-id'] = current_vnfr['vim-account-id']
216 vnfr_graph_param['created-time'] = current_vnfr['created-time']
217
218 vnfr_label = current_vnfr['vnfd-ref'] + ':' + current_vnfr['member-vnf-index-ref']
219 map_vnf_index_to_id[current_vnfr['member-vnf-index-ref']] = vnfr_id
220 self.add_node(vnfr_id, 'vnfr', None, None, graph,
221 {'property': {'custom_label': vnfr_label}, 'osm': current_vnfr})
222
223 for cp in current_vnfr['connection-point']:
224 if cp['id']:
225 cp_id = vnfr_label + ':' + cp['id']
226 self.add_node(cp_id, 'cp', vnfr_id, None, graph, {'osm': cp})
227
228 for vdur in current_vnfr['vdur']:
229 vdur_id = vnfr_label + ':' + vdur['vdu-id-ref']
230 self.add_node(vdur_id, 'vdur', vnfr_id, None, graph, {'osm': vdur})
231 if current_vnfr['vnfd-id'] in nsr_full['vnfd']:
232 for vdu in nsr_full['vnfd'][current_vnfr['vnfd-id']]['vdu']:
233 if vdu['id'] == vdur['vdu-id-ref']:
234 if 'internal-connection-point' in vdu:
235 for int_cp in vdu['internal-connection-point']:
236 cp_id = vnfr_label + ':' + int_cp['id']
237 self.add_node(cp_id, 'int_cp', vnfr_id, None, graph, {'osm': int_cp})
238 for interface in vdu['interface']:
239 if interface['type'] == "EXTERNAL":
240 cp_id = vnfr_label + ':' + interface['external-connection-point-ref']
241 self.add_link(cp_id, vdur_id, 'vnfr', vnfr_id, graph)
242 elif interface['type'] == "INTERNAL":
243 cp_id = vnfr_label + ':' + interface['internal-connection-point-ref']
244 self.add_link(cp_id, vdur_id, 'vnfr', vnfr_id, graph)
245
246 if current_vnfr['vnfd-id'] in nsr_full['vnfd'] and 'internal-vld' in nsr_full['vnfd'][
247 current_vnfr['vnfd-id']]:
248 for vnfd_vld in nsr_full['vnfd'][current_vnfr['vnfd-id']]['internal-vld']:
249 vld_id = vnfr_label + ':' + vnfd_vld['id']
250 self.add_node(vld_id, 'vnf_vl', vnfr_id, None, graph, {'osm': vnfd_vld})
251 if vnfd_vld['internal-connection-point']:
252 for int_cp in vnfd_vld['internal-connection-point']:
253 int_cp_id = vnfr_label + ':' + int_cp['id-ref']
254 self.add_link(vld_id, int_cp_id, 'vnfr', vnfr_id, graph)
255
256 for ns_vld in nsr['nsd']['vld']:
257 self.add_node(ns_vld['id'], 'ns_vl', None, None, graph,
258 {'property': {'custom_label': ns_vld['name']}, 'osm': ns_vld})
259 for cp_ref in ns_vld['vnfd-connection-point-ref']:
260 self.add_link(map_vnf_index_to_id[str(cp_ref['member-vnf-index-ref'])], ns_vld['id'], 'nsr', None,
261 graph)
262
263 return graph
264
265 def vnfd_to_graph(self, vnfd_catalog):
266 graph = {'vertices': [], 'edges': [], 'model': {
267 "layer": {
268 "vnfd": {
269 "nodes": {
270 "vdu": {},
271 "cp": {},
272 "int_cp": {},
273 "vnf_vl": {}
274
275 },
276 "allowed_edges": {
277 "vdu": {
278 "destination": {
279 "cp": {
280 "direct_edge": False,
281 },
282 "int_cp": {
283 "direct_edge": False,
284 },
285 "vnf_vl": {
286 "direct_edge": False,
287 }
288 }
289 },
290 "cp": {
291 "destination": {
292 "vdu": {
293 "direct_edge": False,
294 }
295 }
296 },
297 "int_cp": {
298 "destination": {
299 "vdu": {
300 "direct_edge": False,
301 },
302 "vnf_vl": {
303 "direct_edge": False,
304 }
305 }
306 },
307 "vnf_vl": {
308 "destination": {
309 "vdu": {
310 "direct_edge": False
311 }
312 }
313 }
314 }
315 },
316 "name": "OSM",
317 "version": 1,
318 "description": "osm"
319 }
320 }, 'graph_parameters': {'view': {'vnfd': {}}}}
321 if 'vnfd-catalog' in vnfd_catalog:
322 vnfd = vnfd_catalog['vnfd-catalog']['vnfd'][0]
323 elif 'vnfd:vnfd-catalog' in vnfd_catalog:
324 vnfd = vnfd_catalog['vnfd:vnfd-catalog']['vnfd'][0]
325 else:
326 return graph
327 if 'connection-point' in vnfd:
328 for extCp in vnfd['connection-point']:
329 self.add_node(extCp['name'], 'cp', vnfd['id'], None, graph,
330 {'property': {'custom_label': extCp['name']}, 'osm': extCp})
331 if 'vdu' in vnfd:
332 for vdu in vnfd['vdu']:
333 self.add_node(vdu['id'], 'vdu', vnfd['id'], None, graph,
334 {'property': {'custom_label': vdu['id']}, 'osm': vdu})
335 if 'internal-connection-point' in vdu:
336 for intCp in vdu['internal-connection-point']:
337 self.add_node(intCp['id'], 'int_cp', vnfd['id'], None, graph,
338 {'property': {'custom_label': intCp['id']}, 'osm': intCp})
339 if 'interface' in vdu:
340 for interface in vdu['interface']:
341 if interface['type'] == "EXTERNAL":
342 self.add_link(vdu['id'], interface['external-connection-point-ref'], 'vnfd', vnfd['id'], graph)
343 elif interface['type'] == "INTERNAL":
344 self.add_link(vdu['id'], interface['internal-connection-point-ref'], 'vnfd', vnfd['id'], graph, {'short': True})
345 if 'internal-vld' in vnfd:
346 for intVl in vnfd['internal-vld']:
347 self.add_node(intVl['id'], 'vnf_vl', intVl['id'], None, graph,
348 {'property': {'custom_label': intVl['id']}, 'osm': intVl})
349 for intCp in intVl['internal-connection-point']:
350 self.add_link(intVl['id'], intCp['id-ref'], 'vnfd', vnfd['id'], graph)
351
352 return graph
353
354 def nsd_to_graph(self, nsd_catalog):
355 graph = {'vertices': [], 'edges': [], 'model': {
356 "layer": {
357 "nsd": {
358 "nodes": {
359 "vnfd": {},
360 "cp": {},
361 "ns_vl": {}
362 },
363 "allowed_edges": {
364 "cp": {
365 "destination": {
366 "vnfd": {
367 "direct_edge": False,
368 }
369 }
370 },
371 "vnfd":{
372 "destination": {
373 "ns_vl": {
374 "direct_edge": False,
375 }
376 }
377 },
378 "ns_vl": {
379 "destination": {
380 "vnfd": {
381 "direct_edge": False,
382 }
383 }
384 }
385 }
386 },
387 "vnfd": {
388 "nodes": {
389 "vdu": {},
390 "cp": {},
391 "int_cp": {},
392 "vnf_vl": {}
393 },
394 "allowed_edges": {
395 "vdu": {
396 "destination": {
397 "cp": {
398 "direct_edge": False,
399 },
400 "int_cp": {
401 "direct_edge": False,
402 },
403 "vnf_vl": {
404 "direct_edge": False,
405 }
406 }
407 },
408 "cp": {
409 "destination": {
410 "vdu": {
411 "direct_edge": False,
412 }
413 }
414 },
415 "int_cp": {
416 "destination": {
417 "vdu": {
418 "direct_edge": False,
419 },
420 "vnf_vl": {
421 "direct_edge": False,
422 }
423 }
424 },
425 "vnf_vl": {
426 "destination": {
427 "vdu": {
428 "direct_edge": False
429 }
430 }
431 }
432 }
433 },
434 "name": "OSM",
435 "version": 1,
436 "description": "osm"
437 }
438 }, 'graph_parameters': {'view': {'vnfd': {}}}}
439 if 'nsd-catalog' in nsd_catalog:
440 nsd = nsd_catalog['nsd-catalog']['nsd'][0]
441 elif 'nsd:nsd-catalog' in nsd_catalog:
442 nsd = nsd_catalog['nsd:nsd-catalog']['nsd'][0]
443 else:
444 return graph
445 if 'constituent-vnfd' in nsd:
446 for vnfd in nsd['constituent-vnfd']:
447 costinuent_id = vnfd['vnfd-id-ref']+":"+vnfd['member-vnf-index']
448 self.add_node(costinuent_id, 'vnf', None, None, graph,
449 {'property': {'custom_label': costinuent_id}, 'osm': vnfd})
450
451 if 'vld' in nsd:
452 for vld in nsd['vld']:
453 self.add_node(vld['id'], 'ns_vl', None, None, graph,
454 {'property': {'custom_label': vld['id']}, 'osm': vld})
455 if 'vnfd-connection-point-ref' in vld:
456 for cp_ref in vld['vnfd-connection-point-ref']:
457 vnfd_id = cp_ref['vnfd-id-ref'] + ':' + str(cp_ref['member-vnf-index-ref'])
458 self.add_link(vld['id'], vnfd_id, 'nsd', None, graph)
459
460 return graph
461
462
463 if __name__ == '__main__':
464 parser = OsmParser()
465 print parser.nsr_to_graph({})