fix missing vnfd composer constraint
[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 "addable": {
272 "callback": "addNode"
273 },
274 "removable": {
275 "callback": "removeNode"
276 }
277 },
278 "cp": {
279 "addable": {
280 "callback": "addNode"
281 },
282 "removable": {
283 "callback": "removeNode"
284 }
285 },
286 "int_cp": {
287 "addable": {
288 "callback": "addNode"
289 },
290 "removable": {
291 "callback": "removeNode"
292 }
293 },
294 "vnf_vl": {
295 "addable": {
296 "callback": "addNode"
297 },
298 "removable": {
299 "callback": "removeNode"
300 }
301 }
302 },
303 "allowed_edges": {
304 "vdu": {
305 "destination": {
306 "cp": {
307 "direct_edge": False,
308 },
309 "int_cp": {
310 "direct_edge": False,
311 }
312 }
313 },
314 "cp": {
315 "destination": {
316 "vdu": {
317 "direct_edge": False,
318 }
319 }
320 },
321 "int_cp": {
322 "destination": {
323 "vdu": {
324 "direct_edge": False,
325 },
326 "vnf_vl": {
327 "direct_edge": False,
328 }
329 }
330 },
331 "vnf_vl": {
332 "destination": {
333 "int_cp": {
334 "direct_edge": False
335 }
336 }
337 }
338 }
339 },
340 "name": "OSM",
341 "version": 1,
342 "description": "osm"
343 }, "callback": {"addNode": {"class": "OSMController"}, "removeNode": {"class": "OSMController"}}
344 }, 'graph_parameters': {'view': {'vnfd': {}}}}
345 if 'vnfd-catalog' in vnfd_catalog:
346 vnfd = vnfd_catalog['vnfd-catalog']['vnfd'][0]
347 elif 'vnfd:vnfd-catalog' in vnfd_catalog:
348 vnfd = vnfd_catalog['vnfd:vnfd-catalog']['vnfd'][0]
349 else:
350 return graph
351 vnfd_graph_param = graph['graph_parameters']['view']['vnfd']
352 vnfd_graph_param['id'] = vnfd['id'] if 'id' in vnfd else None
353 vnfd_graph_param['name'] = vnfd['name'] if 'name' in vnfd else None
354 vnfd_graph_param['short-name'] = vnfd['short-name'] if 'short-name' in vnfd else None
355 vnfd_graph_param['description'] = vnfd['description'] if 'description' in vnfd else None
356 vnfd_graph_param['version'] = vnfd['version'] if 'version' in vnfd else None
357 vnfd_graph_param['vendor'] = vnfd['vendor'] if 'vendor' in vnfd else None
358 if 'connection-point' in vnfd:
359 for extCp in vnfd['connection-point']:
360 self.add_node(extCp['name'], 'cp', vnfd['id'], None, graph,
361 {'property': {'custom_label': extCp['name']}, 'osm': extCp})
362 if 'vdu' in vnfd:
363 for vdu in vnfd['vdu']:
364 self.add_node(vdu['id'], 'vdu', vnfd['id'], None, graph,
365 {'property': {'custom_label': vdu['id']}, 'osm': vdu})
366 if 'internal-connection-point' in vdu:
367 for intCp in vdu['internal-connection-point']:
368 self.add_node(intCp['id'], 'int_cp', vnfd['id'], None, graph,
369 {'property': {'custom_label': intCp['id']}, 'osm': intCp})
370 if 'interface' in vdu:
371 for interface in vdu['interface']:
372 if interface['type'] == "EXTERNAL":
373 self.add_link(vdu['id'], interface['external-connection-point-ref'], 'vnfd', vnfd['id'], graph)
374 elif interface['type'] == "INTERNAL":
375 self.add_link(vdu['id'], interface['internal-connection-point-ref'], 'vnfd', vnfd['id'], graph, {'short': True})
376 if 'internal-vld' in vnfd:
377 for intVl in vnfd['internal-vld']:
378 self.add_node(intVl['id'], 'vnf_vl', intVl['id'], None, graph,
379 {'property': {'custom_label': intVl['id']}, 'osm': intVl})
380 for intCp in intVl['internal-connection-point']:
381 self.add_link(intVl['id'], intCp['id-ref'], 'vnfd', vnfd['id'], graph)
382
383 return graph
384
385 def nsd_to_graph(self, nsd_catalog):
386 graph = {'vertices': [], 'edges': [], 'model': {
387 "layer": {
388 "nsd": {
389 "nodes": {
390 "vnf": {"addable": {
391 "callback": "addNode"
392 },
393 "removable": {
394 "callback": "removeNode"
395 }},
396 "cp": {},
397 "ns_vl": {
398 "addable": {
399 "callback": "addNode"
400 },
401 "removable": {
402 "callback": "removeNode"
403 }
404 }
405 },
406 "allowed_edges": {
407 "cp": {
408 "destination": {
409 "vnfd": {
410 "direct_edge": False,
411 }
412 }
413 },
414 "vnf":{
415 "destination": {
416 "ns_vl": {
417 "direct_edge": False,
418 "callback": "addLink",
419 "removable" : {
420 "callback": "removeLink",
421 }
422 }
423 }
424 },
425 "ns_vl": {
426 "destination": {
427 "vnf": {
428 "direct_edge": False,
429 "callback": "addLink",
430 "removable": {
431 "callback": "removeLink",
432 }
433 }
434 }
435 }
436 }
437 },
438 "vnfd": {
439 "nodes": {
440 "vdu": {},
441 "cp": {},
442 "int_cp": {},
443 "vnf_vl": {}
444 },
445 "allowed_edges": {
446 "vdu": {
447 "destination": {
448 "cp": {
449 "direct_edge": False,
450 },
451 "int_cp": {
452 "direct_edge": False,
453 },
454 "vnf_vl": {
455 "direct_edge": False,
456 }
457 }
458 },
459 "cp": {
460 "destination": {
461 "vdu": {
462 "direct_edge": False,
463 }
464 }
465 },
466 "int_cp": {
467 "destination": {
468 "vdu": {
469 "direct_edge": False,
470 },
471 "vnf_vl": {
472 "direct_edge": False,
473 }
474 }
475 },
476 "vnf_vl": {
477 "destination": {
478 "vdu": {
479 "direct_edge": False
480 }
481 }
482 }
483 }
484 },
485 "name": "OSM",
486 "version": 1,
487 "description": "osm"
488 }, "callback": {"addNode": {"class": "OSMController"}, "removeNode": {"class": "OSMController"},
489 "removeLink": {"class": "OSMController"}, "addLink": {"class": "OSMController"}}
490 }, 'graph_parameters': {'view': {'nsd': {}}}}
491 if 'nsd-catalog' in nsd_catalog:
492 nsd = nsd_catalog['nsd-catalog']['nsd'][0]
493 elif 'nsd:nsd-catalog' in nsd_catalog:
494 nsd = nsd_catalog['nsd:nsd-catalog']['nsd'][0]
495 else:
496 return graph
497
498 nsd_graph_param = graph['graph_parameters']['view']['nsd']
499 nsd_graph_param['id'] = nsd['id'] if 'id' in nsd else None
500 nsd_graph_param['name'] = nsd['name'] if 'name' in nsd else None
501 nsd_graph_param['short-name'] = nsd['short-name'] if 'short-name' in nsd else None
502 nsd_graph_param['description'] = nsd['description'] if 'description' in nsd else None
503 nsd_graph_param['version'] = nsd['version'] if 'version' in nsd else None
504 nsd_graph_param['vendor'] = nsd['vendor'] if 'vendor' in nsd else None
505
506 if 'constituent-vnfd' in nsd:
507 for vnfd in nsd['constituent-vnfd']:
508 costinuent_id = vnfd['vnfd-id-ref']+":"+str(vnfd['member-vnf-index'])
509 self.add_node(costinuent_id, 'vnf', None, None, graph,
510 {'property': {'custom_label': costinuent_id}, 'osm': vnfd})
511
512 if 'vld' in nsd:
513 for vld in nsd['vld']:
514 self.add_node(vld['id'], 'ns_vl', None, None, graph,
515 {'property': {'custom_label': vld['id']}, 'osm': vld})
516 if 'vnfd-connection-point-ref' in vld:
517 for cp_ref in vld['vnfd-connection-point-ref']:
518 vnfd_id = cp_ref['vnfd-id-ref'] + ':' + str(cp_ref['member-vnf-index-ref'])
519 self.add_link(vld['id'], vnfd_id, 'nsd', None, graph)
520 return graph
521
522
523 if __name__ == '__main__':
524 parser = OsmParser()
525 print parser.nsr_to_graph({})