1 # -*- coding: utf-8 -*-
4 # Copyright 2015 Telefonica Investigacion y Desarrollo, S.A.U.
5 # This file is part of openmano
8 # Licensed under the Apache License, Version 2.0 (the "License"); you may
9 # not use this file except in compliance with the License. You may obtain
10 # a copy of the License at
12 # http://www.apache.org/licenses/LICENSE-2.0
14 # Unless required by applicable law or agreed to in writing, software
15 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
17 # License for the specific language governing permissions and limitations
20 # For those usages not covered by the Apache License, Version 2.0 please
21 # contact with: nfvlabs@tid.es
25 NFVO engine, implementing all the methods for the creation, deletion and management of vnfs, scenarios and instances
27 __author__
="Alfonso Tierno, Gerardo Garcia, Pablo Montes"
28 __date__
="$16-sep-2014 22:05:01$"
34 from utils
import deprecated
36 import console_proxy_thread
as cli
41 from uuid
import uuid4
42 from db_base
import db_base_Exception
45 from threading
import Lock
47 from lib_osm_openvim
import ovim
as ovim_module
48 from lib_osm_openvim
.ovim
import ovimException
49 from Crypto
.PublicKey
import RSA
51 import osm_im
.vnfd
as vnfd_catalog
52 import osm_im
.nsd
as nsd_catalog
53 from pyangbind
.lib
.serialise
import pybindJSONDecoder
54 from copy
import deepcopy
58 import wim
.wimconn
as wimconn
59 import wim
.wim_thread
as wim_thread
60 from .http_tools
import errors
as httperrors
61 from .wim
.engine
import WimEngine
62 from .wim
.persistence
import WimPersistence
63 from copy
import deepcopy
64 from pprint
import pformat
68 global vimconn_imported
72 global wimconn_imported
75 global default_volume_size
76 default_volume_size
= '5' #size in GB
81 vimconn_imported
= {} # dictionary with VIM type as key, loaded module as value
82 vim_threads
= {"running":{}, "deleting": {}, "names": []} # threads running for attached-VIMs
83 vim_persistent_info
= {}
85 wimconn_imported
= {} # dictionary with WIM type as key, loaded module as value
86 wim_threads
= {"running":{}, "deleting": {}, "names": []} # threads running for attached-WIMs
87 wim_persistent_info
= {}
90 logger
= logging
.getLogger('openmano.nfvo')
97 class NfvoException(httperrors
.HttpMappedError
):
98 """Common Class for NFVO errors"""
104 if task_id
<= last_task_id
:
105 task_id
= last_task_id
+ 0.000001
106 last_task_id
= task_id
107 return "ACTION-{:.6f}".format(task_id
)
108 # return (t.strftime("%Y%m%dT%H%M%S.{}%Z", t.localtime(task_id))).format(int((task_id % 1)*1e6))
111 def new_task(name
, params
, depends
=None):
113 task_id
= get_task_id()
114 task
= {"status": "enqueued", "id": task_id
, "name": name
, "params": params
}
116 task
["depends"] = depends
121 return True if id[:5] == "TASK-" else False
124 def get_non_used_vim_name(datacenter_name
, datacenter_id
, tenant_name
, tenant_id
):
125 name
= datacenter_name
[:16]
126 if name
not in vim_threads
["names"]:
127 vim_threads
["names"].append(name
)
129 name
= datacenter_name
[:16] + "." + tenant_name
[:16]
130 if name
not in vim_threads
["names"]:
131 vim_threads
["names"].append(name
)
133 name
= datacenter_id
+ "-" + tenant_id
134 vim_threads
["names"].append(name
)
138 def get_non_used_wim_name(wim_name
, wim_id
, tenant_name
, tenant_id
):
140 if name
not in wim_threads
["names"]:
141 wim_threads
["names"].append(name
)
143 name
= wim_name
[:16] + "." + tenant_name
[:16]
144 if name
not in wim_threads
["names"]:
145 wim_threads
["names"].append(name
)
147 name
= wim_id
+ "-" + tenant_id
148 wim_threads
["names"].append(name
)
152 def start_service(mydb
, persistence
=None, wim
=None):
153 global db
, global_config
154 db
= nfvo_db
.nfvo_db()
155 db
.connect(global_config
['db_host'], global_config
['db_user'], global_config
['db_passwd'], global_config
['db_name'])
159 persistence
.lock
= db_lock
161 persistence
= WimPersistence(db
, lock
=db_lock
)
163 # Initialize openvim for SDN control
164 # TODO: Avoid static configuration by adding new parameters to openmanod.cfg
165 # TODO: review ovim.py to delete not needed configuration
166 ovim_configuration
= {
167 'logger_name': 'openmano.ovim',
168 'network_vlan_range_start': 1000,
169 'network_vlan_range_end': 4096,
170 'db_name': global_config
["db_ovim_name"],
171 'db_host': global_config
["db_ovim_host"],
172 'db_user': global_config
["db_ovim_user"],
173 'db_passwd': global_config
["db_ovim_passwd"],
176 'network_type': 'bridge',
177 #TODO: log_level_of should not be needed. To be modified in ovim
178 'log_level_of': 'DEBUG'
181 # starts ovim library
182 ovim
= ovim_module
.ovim(ovim_configuration
)
185 wim_engine
= wim
or WimEngine(persistence
)
186 wim_engine
.ovim
= ovim
190 #delete old unneeded vim_wim_actions
194 from_
= 'tenants_datacenters as td join datacenters as d on td.datacenter_id=d.uuid join '\
195 'datacenter_tenants as dt on td.datacenter_tenant_id=dt.uuid'
196 select_
= ('type', 'd.config as config', 'd.uuid as datacenter_id', 'vim_url', 'vim_url_admin',
197 'd.name as datacenter_name', 'dt.uuid as datacenter_tenant_id',
198 'dt.vim_tenant_name as vim_tenant_name', 'dt.vim_tenant_id as vim_tenant_id',
199 'user', 'passwd', 'dt.config as dt_config', 'nfvo_tenant_id')
200 vims
= mydb
.get_rows(FROM
=from_
, SELECT
=select_
)
202 extra
={'datacenter_tenant_id': vim
.get('datacenter_tenant_id'),
203 'datacenter_id': vim
.get('datacenter_id')}
205 extra
.update(yaml
.load(vim
["config"]))
206 if vim
.get('dt_config'):
207 extra
.update(yaml
.load(vim
["dt_config"]))
208 if vim
["type"] not in vimconn_imported
:
211 module
= "vimconn_" + vim
["type"]
212 pkg
= __import__("osm_ro." + module
)
213 vim_conn
= getattr(pkg
, module
)
214 # module_info = imp.find_module(module, [__file__[:__file__.rfind("/")]])
215 # vim_conn = imp.load_module(vim["type"], *module_info)
216 vimconn_imported
[vim
["type"]] = vim_conn
217 except (IOError, ImportError) as e
:
218 # if module_info and module_info[0]:
219 # file.close(module_info[0])
220 raise NfvoException("Unknown vim type '{}'. Cannot open file '{}.py'; {}: {}".format(
221 vim
["type"], module
, type(e
).__name
__, str(e
)), httperrors
.Bad_Request
)
223 thread_id
= vim
['datacenter_tenant_id']
224 vim_persistent_info
[thread_id
] = {}
227 # return -httperrors.Bad_Request, "You must provide a valid tenant name or uuid for VIM %s" % ( vim["type"])
228 myvim
= vimconn_imported
[ vim
["type"] ].vimconnector(
229 uuid
=vim
['datacenter_id'], name
=vim
['datacenter_name'],
230 tenant_id
=vim
['vim_tenant_id'], tenant_name
=vim
['vim_tenant_name'],
231 url
=vim
['vim_url'], url_admin
=vim
['vim_url_admin'],
232 user
=vim
['user'], passwd
=vim
['passwd'],
233 config
=extra
, persistent_info
=vim_persistent_info
[thread_id
]
235 except vimconn
.vimconnException
as e
:
237 logger
.error("Cannot launch thread for VIM {} '{}': {}".format(vim
['datacenter_name'],
238 vim
['datacenter_id'], e
))
239 except Exception as e
:
240 raise NfvoException("Error at VIM {}; {}: {}".format(vim
["type"], type(e
).__name
__, e
),
241 httperrors
.Internal_Server_Error
)
242 thread_name
= get_non_used_vim_name(vim
['datacenter_name'], vim
['vim_tenant_id'], vim
['vim_tenant_name'],
243 vim
['vim_tenant_id'])
244 new_thread
= vim_thread
.vim_thread(task_lock
, thread_name
, vim
['datacenter_name'],
245 vim
['datacenter_tenant_id'], db
=db
, db_lock
=db_lock
, ovim
=ovim
)
247 vim_threads
["running"][thread_id
] = new_thread
249 wim_engine
.start_threads()
250 except db_base_Exception
as e
:
251 raise NfvoException(str(e
) + " at nfvo.get_vim", e
.http_code
)
252 except ovim_module
.ovimException
as e
:
254 if message
[:22] == "DATABASE wrong version":
255 message
= "DATABASE wrong version of lib_osm_openvim {msg} -d{dbname} -u{dbuser} -p{dbpass} {ver}' "\
256 "at host {dbhost}".format(
257 msg
=message
[22:-3], dbname
=global_config
["db_ovim_name"],
258 dbuser
=global_config
["db_ovim_user"], dbpass
=global_config
["db_ovim_passwd"],
259 ver
=message
[-3:-1], dbhost
=global_config
["db_ovim_host"])
260 raise NfvoException(message
, httperrors
.Bad_Request
)
264 global ovim
, global_config
267 for thread_id
, thread
in vim_threads
["running"].items():
268 thread
.insert_task("exit")
269 vim_threads
["deleting"][thread_id
] = thread
270 vim_threads
["running"] = {}
273 wim_engine
.stop_threads()
275 if global_config
and global_config
.get("console_thread"):
276 for thread
in global_config
["console_thread"]:
277 thread
.terminate
= True
280 return ("openmanod version {} {}\n(c) Copyright Telefonica".format(global_config
["version"],
281 global_config
["version_date"] ))
285 Clean unused or old entries at database to avoid unlimited growing
286 :param mydb: database connector
289 # get and delete unused vim_wim_actions: all elements deleted, one week before, instance not present
290 now
= t
.time()-3600*24*7
291 instance_action_id
= None
294 actions_to_delete
= mydb
.get_rows(
295 SELECT
=("item", "item_id", "instance_action_id"),
296 FROM
="vim_wim_actions as va join instance_actions as ia on va.instance_action_id=ia.uuid "
297 "left join instance_scenarios as i on ia.instance_id=i.uuid",
298 WHERE
={"va.action": "DELETE", "va.modified_at<": now
, "i.uuid": None,
299 "va.status": ("DONE", "SUPERSEDED")},
302 for to_delete
in actions_to_delete
:
303 mydb
.delete_row(FROM
="vim_wim_actions", WHERE
=to_delete
)
304 if instance_action_id
!= to_delete
["instance_action_id"]:
305 instance_action_id
= to_delete
["instance_action_id"]
306 mydb
.delete_row(FROM
="instance_actions", WHERE
={"uuid": instance_action_id
})
307 nb_deleted
+= len(actions_to_delete
)
308 if len(actions_to_delete
) < 100:
311 logger
.debug("Removed {} unused vim_wim_actions".format(nb_deleted
))
314 def get_flavorlist(mydb
, vnf_id
, nfvo_tenant
=None):
316 return result, content:
317 <0, error_text upon error
318 nb_records, flavor_list on success
321 WHERE_dict
['vnf_id'] = vnf_id
322 if nfvo_tenant
is not None:
323 WHERE_dict
['nfvo_tenant_id'] = nfvo_tenant
325 #result, content = mydb.get_table(FROM='vms join vnfs on vms.vnf_id = vnfs.uuid',SELECT=('uuid'),WHERE=WHERE_dict )
326 #result, content = mydb.get_table(FROM='vms',SELECT=('vim_flavor_id',),WHERE=WHERE_dict )
327 flavors
= mydb
.get_rows(FROM
='vms join flavors on vms.flavor_id=flavors.uuid',SELECT
=('flavor_id',),WHERE
=WHERE_dict
)
328 #print "get_flavor_list result:", result
329 #print "get_flavor_list content:", content
331 for flavor
in flavors
:
332 flavorList
.append(flavor
['flavor_id'])
336 def get_imagelist(mydb
, vnf_id
, nfvo_tenant
=None):
338 Get used images of all vms belonging to this VNFD
339 :param mydb: database conector
340 :param vnf_id: vnfd uuid
341 :param nfvo_tenant: tenant, not used
342 :return: The list of image uuid used
345 vms
= mydb
.get_rows(SELECT
=('image_id','image_list'), FROM
='vms', WHERE
={'vnf_id': vnf_id
})
347 if vm
["image_id"] not in image_list
:
348 image_list
.append(vm
["image_id"])
350 vm_image_list
= yaml
.load(vm
["image_list"])
351 for image_dict
in vm_image_list
:
352 if image_dict
["image_id"] not in image_list
:
353 image_list
.append(image_dict
["image_id"])
357 def get_vim(mydb
, nfvo_tenant
=None, datacenter_id
=None, datacenter_name
=None, datacenter_tenant_id
=None,
358 vim_tenant
=None, vim_tenant_name
=None, vim_user
=None, vim_passwd
=None, ignore_errors
=False):
359 '''Obtain a dictionary of VIM (datacenter) classes with some of the input parameters
360 return dictionary with {datacenter_id: vim_class, ... }. vim_class contain:
361 'nfvo_tenant_id','datacenter_id','vim_tenant_id','vim_url','vim_url_admin','datacenter_name','type','user','passwd'
362 raise exception upon error
365 if nfvo_tenant
is not None: WHERE_dict
['nfvo_tenant_id'] = nfvo_tenant
366 if datacenter_id
is not None: WHERE_dict
['d.uuid'] = datacenter_id
367 if datacenter_tenant_id
is not None: WHERE_dict
['datacenter_tenant_id'] = datacenter_tenant_id
368 if datacenter_name
is not None: WHERE_dict
['d.name'] = datacenter_name
369 if vim_tenant
is not None: WHERE_dict
['dt.vim_tenant_id'] = vim_tenant
370 if vim_tenant_name
is not None: WHERE_dict
['vim_tenant_name'] = vim_tenant_name
371 if nfvo_tenant
or vim_tenant
or vim_tenant_name
or datacenter_tenant_id
:
372 from_
= 'tenants_datacenters as td join datacenters as d on td.datacenter_id=d.uuid join datacenter_tenants as dt on td.datacenter_tenant_id=dt.uuid'
373 select_
= ('type','d.config as config','d.uuid as datacenter_id', 'vim_url', 'vim_url_admin', 'd.name as datacenter_name',
374 'dt.uuid as datacenter_tenant_id','dt.vim_tenant_name as vim_tenant_name','dt.vim_tenant_id as vim_tenant_id',
375 'user','passwd', 'dt.config as dt_config')
377 from_
= 'datacenters as d'
378 select_
= ('type','config','d.uuid as datacenter_id', 'vim_url', 'vim_url_admin', 'd.name as datacenter_name')
380 vims
= mydb
.get_rows(FROM
=from_
, SELECT
=select_
, WHERE
=WHERE_dict
)
383 extra
={'datacenter_tenant_id': vim
.get('datacenter_tenant_id'),
384 'datacenter_id': vim
.get('datacenter_id'),
385 '_vim_type_internal': vim
.get('type')}
387 extra
.update(yaml
.load(vim
["config"]))
388 if vim
.get('dt_config'):
389 extra
.update(yaml
.load(vim
["dt_config"]))
390 if vim
["type"] not in vimconn_imported
:
393 module
= "vimconn_" + vim
["type"]
394 pkg
= __import__("osm_ro." + module
)
395 vim_conn
= getattr(pkg
, module
)
396 # module_info = imp.find_module(module, [__file__[:__file__.rfind("/")]])
397 # vim_conn = imp.load_module(vim["type"], *module_info)
398 vimconn_imported
[vim
["type"]] = vim_conn
399 except (IOError, ImportError) as e
:
400 # if module_info and module_info[0]:
401 # file.close(module_info[0])
403 logger
.error("Unknown vim type '{}'. Can not open file '{}.py'; {}: {}".format(
404 vim
["type"], module
, type(e
).__name
__, str(e
)))
406 raise NfvoException("Unknown vim type '{}'. Can not open file '{}.py'; {}: {}".format(
407 vim
["type"], module
, type(e
).__name
__, str(e
)), httperrors
.Bad_Request
)
410 if 'datacenter_tenant_id' in vim
:
411 thread_id
= vim
["datacenter_tenant_id"]
412 if thread_id
not in vim_persistent_info
:
413 vim_persistent_info
[thread_id
] = {}
414 persistent_info
= vim_persistent_info
[thread_id
]
418 # return -httperrors.Bad_Request, "You must provide a valid tenant name or uuid for VIM %s" % ( vim["type"])
419 vim_dict
[ vim
['datacenter_id'] ] = vimconn_imported
[ vim
["type"] ].vimconnector(
420 uuid
=vim
['datacenter_id'], name
=vim
['datacenter_name'],
421 tenant_id
=vim
.get('vim_tenant_id',vim_tenant
),
422 tenant_name
=vim
.get('vim_tenant_name',vim_tenant_name
),
423 url
=vim
['vim_url'], url_admin
=vim
['vim_url_admin'],
424 user
=vim
.get('user',vim_user
), passwd
=vim
.get('passwd',vim_passwd
),
425 config
=extra
, persistent_info
=persistent_info
427 except Exception as e
:
429 logger
.error("Error at VIM {}; {}: {}".format(vim
["type"], type(e
).__name
__, str(e
)))
431 http_code
= httperrors
.Internal_Server_Error
432 if isinstance(e
, vimconn
.vimconnException
):
433 http_code
= e
.http_code
434 raise NfvoException("Error at VIM {}; {}: {}".format(vim
["type"], type(e
).__name
__, str(e
)), http_code
)
436 except db_base_Exception
as e
:
437 raise NfvoException(str(e
) + " at nfvo.get_vim", e
.http_code
)
440 def rollback(mydb
, vims
, rollback_list
):
442 #delete things by reverse order
443 for i
in range(len(rollback_list
)-1, -1, -1):
444 item
= rollback_list
[i
]
445 if item
["where"]=="vim":
446 if item
["vim_id"] not in vims
:
448 if is_task_id(item
["uuid"]):
450 vim
= vims
[item
["vim_id"]]
452 if item
["what"]=="image":
453 vim
.delete_image(item
["uuid"])
454 mydb
.delete_row(FROM
="datacenters_images", WHERE
={"datacenter_vim_id": vim
["id"], "vim_id":item
["uuid"]})
455 elif item
["what"]=="flavor":
456 vim
.delete_flavor(item
["uuid"])
457 mydb
.delete_row(FROM
="datacenters_flavors", WHERE
={"datacenter_vim_id": vim
["id"], "vim_id":item
["uuid"]})
458 elif item
["what"]=="network":
459 vim
.delete_network(item
["uuid"])
460 elif item
["what"]=="vm":
461 vim
.delete_vminstance(item
["uuid"])
462 except vimconn
.vimconnException
as e
:
463 logger
.error("Error in rollback. Not possible to delete VIM %s '%s'. Message: %s", item
['what'], item
["uuid"], str(e
))
464 undeleted_items
.append("{} {} from VIM {}".format(item
['what'], item
["uuid"], vim
["name"]))
465 except db_base_Exception
as e
:
466 logger
.error("Error in rollback. Not possible to delete %s '%s' from DB.datacenters Message: %s", item
['what'], item
["uuid"], str(e
))
470 if item
["what"]=="image":
471 mydb
.delete_row(FROM
="images", WHERE
={"uuid": item
["uuid"]})
472 elif item
["what"]=="flavor":
473 mydb
.delete_row(FROM
="flavors", WHERE
={"uuid": item
["uuid"]})
474 except db_base_Exception
as e
:
475 logger
.error("Error in rollback. Not possible to delete %s '%s' from DB. Message: %s", item
['what'], item
["uuid"], str(e
))
476 undeleted_items
.append("{} '{}'".format(item
['what'], item
["uuid"]))
477 if len(undeleted_items
)==0:
478 return True," Rollback successful."
480 return False," Rollback fails to delete: " + str(undeleted_items
)
483 def check_vnf_descriptor(vnf_descriptor
, vnf_descriptor_version
=1):
485 #create a dictionary with vnfc-name: vnfc:interface-list key:values pairs
487 for vnfc
in vnf_descriptor
["vnf"]["VNFC"]:
489 #dataplane interfaces
490 for numa
in vnfc
.get("numas",() ):
491 for interface
in numa
.get("interfaces",()):
492 if interface
["name"] in name_dict
:
494 "Error at vnf:VNFC[name:'{}']:numas:interfaces:name, interface name '{}' already used in this VNFC".format(
495 vnfc
["name"], interface
["name"]),
496 httperrors
.Bad_Request
)
497 name_dict
[ interface
["name"] ] = "underlay"
499 for interface
in vnfc
.get("bridge-ifaces",() ):
500 if interface
["name"] in name_dict
:
502 "Error at vnf:VNFC[name:'{}']:bridge-ifaces:name, interface name '{}' already used in this VNFC".format(
503 vnfc
["name"], interface
["name"]),
504 httperrors
.Bad_Request
)
505 name_dict
[ interface
["name"] ] = "overlay"
506 vnfc_interfaces
[ vnfc
["name"] ] = name_dict
507 # check bood-data info
508 # if "boot-data" in vnfc:
509 # # check that user-data is incompatible with users and config-files
510 # if (vnfc["boot-data"].get("users") or vnfc["boot-data"].get("config-files")) and vnfc["boot-data"].get("user-data"):
511 # raise NfvoException(
512 # "Error at vnf:VNFC:boot-data, fields 'users' and 'config-files' are not compatible with 'user-data'",
513 # httperrors.Bad_Request)
515 #check if the info in external_connections matches with the one in the vnfcs
517 for external_connection
in vnf_descriptor
["vnf"].get("external-connections",() ):
518 if external_connection
["name"] in name_list
:
520 "Error at vnf:external-connections:name, value '{}' already used as an external-connection".format(
521 external_connection
["name"]),
522 httperrors
.Bad_Request
)
523 name_list
.append(external_connection
["name"])
524 if external_connection
["VNFC"] not in vnfc_interfaces
:
526 "Error at vnf:external-connections[name:'{}']:VNFC, value '{}' does not match any VNFC".format(
527 external_connection
["name"], external_connection
["VNFC"]),
528 httperrors
.Bad_Request
)
530 if external_connection
["local_iface_name"] not in vnfc_interfaces
[ external_connection
["VNFC"] ]:
532 "Error at vnf:external-connections[name:'{}']:local_iface_name, value '{}' does not match any interface of this VNFC".format(
533 external_connection
["name"],
534 external_connection
["local_iface_name"]),
535 httperrors
.Bad_Request
)
537 #check if the info in internal_connections matches with the one in the vnfcs
539 for internal_connection
in vnf_descriptor
["vnf"].get("internal-connections",() ):
540 if internal_connection
["name"] in name_list
:
542 "Error at vnf:internal-connections:name, value '%s' already used as an internal-connection".format(
543 internal_connection
["name"]),
544 httperrors
.Bad_Request
)
545 name_list
.append(internal_connection
["name"])
546 #We should check that internal-connections of type "ptp" have only 2 elements
548 if len(internal_connection
["elements"])>2 and (internal_connection
.get("type") == "ptp" or internal_connection
.get("type") == "e-line"):
550 "Error at 'vnf:internal-connections[name:'{}']:elements', size must be 2 for a '{}' type. Consider change it to '{}' type".format(
551 internal_connection
["name"],
552 'ptp' if vnf_descriptor_version
==1 else 'e-line',
553 'data' if vnf_descriptor_version
==1 else "e-lan"),
554 httperrors
.Bad_Request
)
555 for port
in internal_connection
["elements"]:
557 iface
= port
["local_iface_name"]
558 if vnf
not in vnfc_interfaces
:
560 "Error at vnf:internal-connections[name:'{}']:elements[]:VNFC, value '{}' does not match any VNFC".format(
561 internal_connection
["name"], vnf
),
562 httperrors
.Bad_Request
)
563 if iface
not in vnfc_interfaces
[ vnf
]:
565 "Error at vnf:internal-connections[name:'{}']:elements[]:local_iface_name, value '{}' does not match any interface of this VNFC".format(
566 internal_connection
["name"], iface
),
567 httperrors
.Bad_Request
)
568 return -httperrors
.Bad_Request
,
569 if vnf_descriptor_version
==1 and "type" not in internal_connection
:
570 if vnfc_interfaces
[vnf
][iface
] == "overlay":
571 internal_connection
["type"] = "bridge"
573 internal_connection
["type"] = "data"
574 if vnf_descriptor_version
==2 and "implementation" not in internal_connection
:
575 if vnfc_interfaces
[vnf
][iface
] == "overlay":
576 internal_connection
["implementation"] = "overlay"
578 internal_connection
["implementation"] = "underlay"
579 if (internal_connection
.get("type") == "data" or internal_connection
.get("type") == "ptp" or \
580 internal_connection
.get("implementation") == "underlay") and vnfc_interfaces
[vnf
][iface
] == "overlay":
582 "Error at vnf:internal-connections[name:'{}']:elements[]:{}, interface of type {} connected to an {} network".format(
583 internal_connection
["name"],
584 iface
, 'bridge' if vnf_descriptor_version
==1 else 'overlay',
585 'data' if vnf_descriptor_version
==1 else 'underlay'),
586 httperrors
.Bad_Request
)
587 if (internal_connection
.get("type") == "bridge" or internal_connection
.get("implementation") == "overlay") and \
588 vnfc_interfaces
[vnf
][iface
] == "underlay":
590 "Error at vnf:internal-connections[name:'{}']:elements[]:{}, interface of type {} connected to an {} network".format(
591 internal_connection
["name"], iface
,
592 'data' if vnf_descriptor_version
==1 else 'underlay',
593 'bridge' if vnf_descriptor_version
==1 else 'overlay'),
594 httperrors
.Bad_Request
)
597 def create_or_use_image(mydb
, vims
, image_dict
, rollback_list
, only_create_at_vim
=False, return_on_error
=None):
599 if only_create_at_vim
:
600 image_mano_id
= image_dict
['uuid']
601 if return_on_error
== None:
602 return_on_error
= True
604 if image_dict
['location']:
605 images
= mydb
.get_rows(FROM
="images", WHERE
={'location':image_dict
['location'], 'metadata':image_dict
['metadata']})
607 images
= mydb
.get_rows(FROM
="images", WHERE
={'universal_name':image_dict
['universal_name'], 'checksum':image_dict
['checksum']})
609 image_mano_id
= images
[0]['uuid']
611 #create image in MANO DB
612 temp_image_dict
={'name':image_dict
['name'], 'description':image_dict
.get('description',None),
613 'location':image_dict
['location'], 'metadata':image_dict
.get('metadata',None),
614 'universal_name':image_dict
['universal_name'] , 'checksum':image_dict
['checksum']
616 #temp_image_dict['location'] = image_dict.get('new_location') if image_dict['location'] is None
617 image_mano_id
= mydb
.new_row('images', temp_image_dict
, add_uuid
=True)
618 rollback_list
.append({"where":"mano", "what":"image","uuid":image_mano_id
})
619 #create image at every vim
620 for vim_id
,vim
in vims
.iteritems():
621 datacenter_vim_id
= vim
["config"]["datacenter_tenant_id"]
622 image_created
="false"
624 image_db
= mydb
.get_rows(FROM
="datacenters_images",
625 WHERE
={'datacenter_vim_id': datacenter_vim_id
, 'image_id': image_mano_id
})
626 #look at VIM if this image exist
628 if image_dict
['location'] is not None:
629 image_vim_id
= vim
.get_image_id_from_path(image_dict
['location'])
632 filter_dict
['name'] = image_dict
['universal_name']
633 if image_dict
.get('checksum') != None:
634 filter_dict
['checksum'] = image_dict
['checksum']
635 #logger.debug('>>>>>>>> Filter dict: %s', str(filter_dict))
636 vim_images
= vim
.get_image_list(filter_dict
)
637 #logger.debug('>>>>>>>> VIM images: %s', str(vim_images))
638 if len(vim_images
) > 1:
639 raise vimconn
.vimconnException("More than one candidate VIM image found for filter: {}".format(str(filter_dict
)), httperrors
.Conflict
)
640 elif len(vim_images
) == 0:
641 raise vimconn
.vimconnNotFoundException("Image not found at VIM with filter: '{}'".format(str(filter_dict
)))
643 #logger.debug('>>>>>>>> VIM image 0: %s', str(vim_images[0]))
644 image_vim_id
= vim_images
[0]['id']
646 except vimconn
.vimconnNotFoundException
as e
:
647 #Create the image in VIM only if image_dict['location'] or image_dict['new_location'] is not None
649 #image_dict['location']=image_dict.get('new_location') if image_dict['location'] is None
650 if image_dict
['location']:
651 image_vim_id
= vim
.new_image(image_dict
)
652 rollback_list
.append({"where":"vim", "vim_id": vim_id
, "what":"image","uuid":image_vim_id
})
655 #If we reach this point, then the image has image name, and optionally checksum, and could not be found
656 raise vimconn
.vimconnException(str(e
))
657 except vimconn
.vimconnException
as e
:
659 logger
.error("Error creating image at VIM '%s': %s", vim
["name"], str(e
))
662 logger
.warn("Error creating image at VIM '%s': %s", vim
["name"], str(e
))
664 except vimconn
.vimconnException
as e
:
666 logger
.error("Error contacting VIM to know if the image exists at VIM: %s", str(e
))
668 logger
.warn("Error contacting VIM to know if the image exists at VIM: %s", str(e
))
671 #if we reach here, the image has been created or existed
673 #add new vim_id at datacenters_images
674 mydb
.new_row('datacenters_images', {'datacenter_vim_id': datacenter_vim_id
,
675 'image_id':image_mano_id
,
676 'vim_id': image_vim_id
,
677 'created':image_created
})
678 elif image_db
[0]["vim_id"]!=image_vim_id
:
679 #modify existing vim_id at datacenters_images
680 mydb
.update_rows('datacenters_images', UPDATE
={'vim_id':image_vim_id
}, WHERE
={'datacenter_vim_id':vim_id
, 'image_id':image_mano_id
})
682 return image_vim_id
if only_create_at_vim
else image_mano_id
685 def create_or_use_flavor(mydb
, vims
, flavor_dict
, rollback_list
, only_create_at_vim
=False, return_on_error
= None):
686 temp_flavor_dict
= {'disk':flavor_dict
.get('disk',0),
687 'ram':flavor_dict
.get('ram'),
688 'vcpus':flavor_dict
.get('vcpus'),
690 if 'extended' in flavor_dict
and flavor_dict
['extended']==None:
691 del flavor_dict
['extended']
692 if 'extended' in flavor_dict
:
693 temp_flavor_dict
['extended']=yaml
.safe_dump(flavor_dict
['extended'],default_flow_style
=True,width
=256)
695 #look if flavor exist
696 if only_create_at_vim
:
697 flavor_mano_id
= flavor_dict
['uuid']
698 if return_on_error
== None:
699 return_on_error
= True
701 flavors
= mydb
.get_rows(FROM
="flavors", WHERE
=temp_flavor_dict
)
703 flavor_mano_id
= flavors
[0]['uuid']
706 #create one by one the images of aditional disks
707 dev_image_list
=[] #list of images
708 if 'extended' in flavor_dict
and flavor_dict
['extended']!=None:
710 for device
in flavor_dict
['extended'].get('devices',[]):
711 if "image" not in device
and "image name" not in device
:
714 image_dict
['name']=device
.get('image name',flavor_dict
['name']+str(dev_nb
)+"-img")
715 image_dict
['universal_name']=device
.get('image name')
716 image_dict
['description']=flavor_dict
['name']+str(dev_nb
)+"-img"
717 image_dict
['location']=device
.get('image')
718 #image_dict['new_location']=vnfc.get('image location')
719 image_dict
['checksum']=device
.get('image checksum')
720 image_metadata_dict
= device
.get('image metadata', None)
721 image_metadata_str
= None
722 if image_metadata_dict
!= None:
723 image_metadata_str
= yaml
.safe_dump(image_metadata_dict
,default_flow_style
=True,width
=256)
724 image_dict
['metadata']=image_metadata_str
725 image_id
= create_or_use_image(mydb
, vims
, image_dict
, rollback_list
)
726 #print "Additional disk image id for VNFC %s: %s" % (flavor_dict['name']+str(dev_nb)+"-img", image_id)
727 dev_image_list
.append(image_id
)
729 temp_flavor_dict
['name'] = flavor_dict
['name']
730 temp_flavor_dict
['description'] = flavor_dict
.get('description',None)
731 content
= mydb
.new_row('flavors', temp_flavor_dict
, add_uuid
=True)
732 flavor_mano_id
= content
733 rollback_list
.append({"where":"mano", "what":"flavor","uuid":flavor_mano_id
})
734 #create flavor at every vim
735 if 'uuid' in flavor_dict
:
736 del flavor_dict
['uuid']
738 for vim_id
,vim
in vims
.items():
739 datacenter_vim_id
= vim
["config"]["datacenter_tenant_id"]
740 flavor_created
="false"
742 flavor_db
= mydb
.get_rows(FROM
="datacenters_flavors",
743 WHERE
={'datacenter_vim_id': datacenter_vim_id
, 'flavor_id': flavor_mano_id
})
744 #look at VIM if this flavor exist SKIPPED
745 #res_vim, flavor_vim_id = vim.get_flavor_id_from_path(flavor_dict['location'])
747 # print "Error contacting VIM to know if the flavor %s existed previously." %flavor_vim_id
751 # Create the flavor in VIM
752 # Translate images at devices from MANO id to VIM id
754 if 'extended' in flavor_dict
and flavor_dict
['extended']!=None and "devices" in flavor_dict
['extended']:
755 # make a copy of original devices
758 for device
in flavor_dict
["extended"].get("devices",[]):
761 devices_original
.append(dev
)
762 if 'image' in device
:
764 if 'image metadata' in device
:
765 del device
['image metadata']
766 if 'image checksum' in device
:
767 del device
['image checksum']
769 for index
in range(0,len(devices_original
)) :
770 device
=devices_original
[index
]
771 if "image" not in device
and "image name" not in device
:
772 # if 'size' in device:
773 disk_list
.append({'size': device
.get('size', default_volume_size
), 'name': device
.get('name')})
776 image_dict
['name']=device
.get('image name',flavor_dict
['name']+str(dev_nb
)+"-img")
777 image_dict
['universal_name']=device
.get('image name')
778 image_dict
['description']=flavor_dict
['name']+str(dev_nb
)+"-img"
779 image_dict
['location']=device
.get('image')
780 # image_dict['new_location']=device.get('image location')
781 image_dict
['checksum']=device
.get('image checksum')
782 image_metadata_dict
= device
.get('image metadata', None)
783 image_metadata_str
= None
784 if image_metadata_dict
!= None:
785 image_metadata_str
= yaml
.safe_dump(image_metadata_dict
,default_flow_style
=True,width
=256)
786 image_dict
['metadata']=image_metadata_str
787 image_mano_id
=create_or_use_image(mydb
, vims
, image_dict
, rollback_list
, only_create_at_vim
=False, return_on_error
=return_on_error
)
788 image_dict
["uuid"]=image_mano_id
789 image_vim_id
=create_or_use_image(mydb
, vims
, image_dict
, rollback_list
, only_create_at_vim
=True, return_on_error
=return_on_error
)
791 #save disk information (image must be based on and size
792 disk_list
.append({'image_id': image_vim_id
, 'size': device
.get('size', default_volume_size
)})
794 flavor_dict
["extended"]["devices"][index
]['imageRef']=image_vim_id
797 #check that this vim_id exist in VIM, if not create
798 flavor_vim_id
=flavor_db
[0]["vim_id"]
800 vim
.get_flavor(flavor_vim_id
)
801 continue #flavor exist
802 except vimconn
.vimconnException
:
804 #create flavor at vim
805 logger
.debug("nfvo.create_or_use_flavor() adding flavor to VIM %s", vim
["name"])
808 flavor_vim_id
=vim
.get_flavor_id_from_data(flavor_dict
)
809 flavor_create
="false"
810 except vimconn
.vimconnException
as e
:
813 if not flavor_vim_id
:
814 flavor_vim_id
= vim
.new_flavor(flavor_dict
)
815 rollback_list
.append({"where":"vim", "vim_id": vim_id
, "what":"flavor","uuid":flavor_vim_id
})
816 flavor_created
="true"
817 except vimconn
.vimconnException
as e
:
819 logger
.error("Error creating flavor at VIM %s: %s.", vim
["name"], str(e
))
821 logger
.warn("Error creating flavor at VIM %s: %s.", vim
["name"], str(e
))
824 #if reach here the flavor has been create or exist
825 if len(flavor_db
)==0:
826 #add new vim_id at datacenters_flavors
827 extended_devices_yaml
= None
828 if len(disk_list
) > 0:
829 extended_devices
= dict()
830 extended_devices
['disks'] = disk_list
831 extended_devices_yaml
= yaml
.safe_dump(extended_devices
,default_flow_style
=True,width
=256)
832 mydb
.new_row('datacenters_flavors',
833 {'datacenter_vim_id': datacenter_vim_id
, 'flavor_id': flavor_mano_id
, 'vim_id': flavor_vim_id
,
834 'created': flavor_created
, 'extended': extended_devices_yaml
})
835 elif flavor_db
[0]["vim_id"]!=flavor_vim_id
:
836 #modify existing vim_id at datacenters_flavors
837 mydb
.update_rows('datacenters_flavors', UPDATE
={'vim_id':flavor_vim_id
},
838 WHERE
={'datacenter_vim_id': datacenter_vim_id
, 'flavor_id': flavor_mano_id
})
840 return flavor_vim_id
if only_create_at_vim
else flavor_mano_id
843 def get_str(obj
, field
, length
):
845 Obtain the str value,
850 value
= obj
.get(field
)
851 if value
is not None:
852 value
= str(value
)[:length
]
855 def _lookfor_or_create_image(db_image
, mydb
, descriptor
):
857 fill image content at db_image dictionary. Check if the image with this image and checksum exist
858 :param db_image: dictionary to insert data
859 :param mydb: database connector
860 :param descriptor: yang descriptor
861 :return: uuid if the image exist at DB, or None if a new image must be created with the data filled at db_image
864 db_image
["name"] = get_str(descriptor
, "image", 255)
865 db_image
["checksum"] = get_str(descriptor
, "image-checksum", 32)
866 if not db_image
["checksum"]: # Ensure that if empty string, None is stored
867 db_image
["checksum"] = None
868 if db_image
["name"].startswith("/"):
869 db_image
["location"] = db_image
["name"]
870 existing_images
= mydb
.get_rows(FROM
="images", WHERE
={'location': db_image
["location"]})
872 db_image
["universal_name"] = db_image
["name"]
873 existing_images
= mydb
.get_rows(FROM
="images", WHERE
={'universal_name': db_image
['universal_name'],
874 'checksum': db_image
['checksum']})
876 return existing_images
[0]["uuid"]
878 image_uuid
= str(uuid4())
879 db_image
["uuid"] = image_uuid
882 def new_vnfd_v3(mydb
, tenant_id
, vnf_descriptor
):
884 Parses an OSM IM vnfd_catalog and insert at DB
887 :param vnf_descriptor:
888 :return: The list of cretated vnf ids
891 myvnfd
= vnfd_catalog
.vnfd()
893 pybindJSONDecoder
.load_ietf_json(vnf_descriptor
, None, None, obj
=myvnfd
, path_helper
=True)
894 except Exception as e
:
895 raise NfvoException("Error. Invalid VNF descriptor format " + str(e
), httperrors
.Bad_Request
)
903 db_ip_profiles_index
= 0
907 vnfd_catalog_descriptor
= vnf_descriptor
.get("vnfd:vnfd-catalog")
908 if not vnfd_catalog_descriptor
:
909 vnfd_catalog_descriptor
= vnf_descriptor
.get("vnfd-catalog")
910 vnfd_descriptor_list
= vnfd_catalog_descriptor
.get("vnfd")
911 if not vnfd_descriptor_list
:
912 vnfd_descriptor_list
= vnfd_catalog_descriptor
.get("vnfd:vnfd")
913 for vnfd_yang
in myvnfd
.vnfd_catalog
.vnfd
.itervalues():
914 vnfd
= vnfd_yang
.get()
917 vnf_uuid
= str(uuid4())
918 uuid_list
.append(vnf_uuid
)
919 vnfd_uuid_list
.append(vnf_uuid
)
920 vnfd_id
= get_str(vnfd
, "id", 255)
924 "name": get_str(vnfd
, "name", 255),
925 "description": get_str(vnfd
, "description", 255),
926 "tenant_id": tenant_id
,
927 "vendor": get_str(vnfd
, "vendor", 255),
928 "short_name": get_str(vnfd
, "short-name", 255),
929 "descriptor": str(vnf_descriptor
)[:60000]
932 for vnfd_descriptor
in vnfd_descriptor_list
:
933 if vnfd_descriptor
["id"] == str(vnfd
["id"]):
936 # table ip_profiles (ip-profiles)
937 ip_profile_name2db_table_index
= {}
938 for ip_profile
in vnfd
.get("ip-profiles").itervalues():
940 "ip_version": str(ip_profile
["ip-profile-params"].get("ip-version", "ipv4")),
941 "subnet_address": str(ip_profile
["ip-profile-params"].get("subnet-address")),
942 "gateway_address": str(ip_profile
["ip-profile-params"].get("gateway-address")),
943 "dhcp_enabled": str(ip_profile
["ip-profile-params"]["dhcp-params"].get("enabled", True)),
944 "dhcp_start_address": str(ip_profile
["ip-profile-params"]["dhcp-params"].get("start-address")),
945 "dhcp_count": str(ip_profile
["ip-profile-params"]["dhcp-params"].get("count")),
948 for dns
in ip_profile
["ip-profile-params"]["dns-server"].itervalues():
949 dns_list
.append(str(dns
.get("address")))
950 db_ip_profile
["dns_address"] = ";".join(dns_list
)
951 if ip_profile
["ip-profile-params"].get('security-group'):
952 db_ip_profile
["security_group"] = ip_profile
["ip-profile-params"]['security-group']
953 ip_profile_name2db_table_index
[str(ip_profile
["name"])] = db_ip_profiles_index
954 db_ip_profiles_index
+= 1
955 db_ip_profiles
.append(db_ip_profile
)
957 # table nets (internal-vld)
958 net_id2uuid
= {} # for mapping interface with network
959 for vld
in vnfd
.get("internal-vld").itervalues():
960 net_uuid
= str(uuid4())
961 uuid_list
.append(net_uuid
)
963 "name": get_str(vld
, "name", 255),
966 "description": get_str(vld
, "description", 255),
967 "osm_id": get_str(vld
, "id", 255),
968 "type": "bridge", # TODO adjust depending on connection point type
970 net_id2uuid
[vld
.get("id")] = net_uuid
971 db_nets
.append(db_net
)
972 # ip-profile, link db_ip_profile with db_sce_net
973 if vld
.get("ip-profile-ref"):
974 ip_profile_name
= vld
.get("ip-profile-ref")
975 if ip_profile_name
not in ip_profile_name2db_table_index
:
976 raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{}]':'vld[{}]':'ip-profile-ref':"
977 "'{}'. Reference to a non-existing 'ip_profiles'".format(
978 str(vnfd
["id"]), str(vld
["id"]), str(vld
["ip-profile-ref"])),
979 httperrors
.Bad_Request
)
980 db_ip_profiles
[ip_profile_name2db_table_index
[ip_profile_name
]]["net_id"] = net_uuid
981 else: #check no ip-address has been defined
982 for icp
in vld
.get("internal-connection-point").itervalues():
983 if icp
.get("ip-address"):
984 raise NfvoException("Error at 'vnfd[{}]':'vld[{}]':'internal-connection-point[{}]' "
985 "contains an ip-address but no ip-profile has been defined at VLD".format(
986 str(vnfd
["id"]), str(vld
["id"]), str(icp
["id"])),
987 httperrors
.Bad_Request
)
989 # connection points vaiable declaration
990 cp_name2iface_uuid
= {}
992 cp_name2db_interface
= {}
993 vdu_id2cp_name
= {} # stored only when one external connection point is presented at this VDU
997 vdu_id2db_table_index
= {}
998 for vdu
in vnfd
.get("vdu").itervalues():
1000 for vdu_descriptor
in vnfd_descriptor
["vdu"]:
1001 if vdu_descriptor
["id"] == str(vdu
["id"]):
1003 vm_uuid
= str(uuid4())
1004 uuid_list
.append(vm_uuid
)
1005 vdu_id
= get_str(vdu
, "id", 255)
1009 "name": get_str(vdu
, "name", 255),
1010 "description": get_str(vdu
, "description", 255),
1011 "pdu_type": get_str(vdu
, "pdu-type", 255),
1014 vdu_id2uuid
[db_vm
["osm_id"]] = vm_uuid
1015 vdu_id2db_table_index
[db_vm
["osm_id"]] = db_vms_index
1016 if vdu
.get("count"):
1017 db_vm
["count"] = int(vdu
["count"])
1020 image_present
= False
1021 if vdu
.get("image"):
1022 image_present
= True
1024 image_uuid
= _lookfor_or_create_image(db_image
, mydb
, vdu
)
1026 image_uuid
= db_image
["uuid"]
1027 db_images
.append(db_image
)
1028 db_vm
["image_id"] = image_uuid
1029 if vdu
.get("alternative-images"):
1030 vm_alternative_images
= []
1031 for alt_image
in vdu
.get("alternative-images").itervalues():
1033 image_uuid
= _lookfor_or_create_image(db_image
, mydb
, alt_image
)
1035 image_uuid
= db_image
["uuid"]
1036 db_images
.append(db_image
)
1037 vm_alternative_images
.append({
1038 "image_id": image_uuid
,
1039 "vim_type": str(alt_image
["vim-type"]),
1040 # "universal_name": str(alt_image["image"]),
1041 # "checksum": str(alt_image["image-checksum"]) if alt_image.get("image-checksum") else None
1044 db_vm
["image_list"] = yaml
.safe_dump(vm_alternative_images
, default_flow_style
=True, width
=256)
1048 if vdu
.get("volumes"):
1049 for volume_key
in vdu
["volumes"]:
1050 volume
= vdu
["volumes"][volume_key
]
1051 if not image_present
:
1052 # Convert the first volume to vnfc.image
1053 image_present
= True
1055 image_uuid
= _lookfor_or_create_image(db_image
, mydb
, volume
)
1057 image_uuid
= db_image
["uuid"]
1058 db_images
.append(db_image
)
1059 db_vm
["image_id"] = image_uuid
1061 # Add Openmano devices
1062 device
= {"name": str(volume
.get("name"))}
1063 device
["type"] = str(volume
.get("device-type"))
1064 if volume
.get("size"):
1065 device
["size"] = int(volume
["size"])
1066 if volume
.get("image"):
1067 device
["image name"] = str(volume
["image"])
1068 if volume
.get("image-checksum"):
1069 device
["image checksum"] = str(volume
["image-checksum"])
1071 devices
.append(device
)
1075 if vdu
.get("cloud-init"):
1076 boot_data
["user-data"] = str(vdu
["cloud-init"])
1077 elif vdu
.get("cloud-init-file"):
1078 # TODO Where this file content is present???
1079 # boot_data["user-data"] = vnfd_yang.files[vdu["cloud-init-file"]]
1080 boot_data
["user-data"] = str(vdu
["cloud-init-file"])
1082 if vdu
.get("supplemental-boot-data"):
1083 if vdu
["supplemental-boot-data"].get('boot-data-drive'):
1084 boot_data
['boot-data-drive'] = True
1085 if vdu
["supplemental-boot-data"].get('config-file'):
1086 om_cfgfile_list
= list()
1087 for custom_config_file
in vdu
["supplemental-boot-data"]['config-file'].itervalues():
1088 # TODO Where this file content is present???
1089 cfg_source
= str(custom_config_file
["source"])
1090 om_cfgfile_list
.append({"dest": custom_config_file
["dest"],
1091 "content": cfg_source
})
1092 boot_data
['config-files'] = om_cfgfile_list
1094 db_vm
["boot_data"] = yaml
.safe_dump(boot_data
, default_flow_style
=True, width
=256)
1096 db_vms
.append(db_vm
)
1099 # table interfaces (internal/external interfaces)
1100 flavor_epa_interfaces
= []
1101 # for iface in chain(vdu.get("internal-interface").itervalues(), vdu.get("external-interface").itervalues()):
1102 for iface
in vdu
.get("interface").itervalues():
1103 flavor_epa_interface
= {}
1104 iface_uuid
= str(uuid4())
1105 uuid_list
.append(iface_uuid
)
1108 "internal_name": get_str(iface
, "name", 255),
1111 flavor_epa_interface
["name"] = db_interface
["internal_name"]
1112 if iface
.get("virtual-interface").get("vpci"):
1113 db_interface
["vpci"] = get_str(iface
.get("virtual-interface"), "vpci", 12)
1114 flavor_epa_interface
["vpci"] = db_interface
["vpci"]
1116 if iface
.get("virtual-interface").get("bandwidth"):
1117 bps
= int(iface
.get("virtual-interface").get("bandwidth"))
1118 db_interface
["bw"] = int(math
.ceil(bps
/1000000.0))
1119 flavor_epa_interface
["bandwidth"] = "{} Mbps".format(db_interface
["bw"])
1121 if iface
.get("virtual-interface").get("type") == "OM-MGMT":
1122 db_interface
["type"] = "mgmt"
1123 elif iface
.get("virtual-interface").get("type") in ("VIRTIO", "E1000", "PARAVIRT"):
1124 db_interface
["type"] = "bridge"
1125 db_interface
["model"] = get_str(iface
.get("virtual-interface"), "type", 12)
1126 elif iface
.get("virtual-interface").get("type") in ("SR-IOV", "PCI-PASSTHROUGH"):
1127 db_interface
["type"] = "data"
1128 db_interface
["model"] = get_str(iface
.get("virtual-interface"), "type", 12)
1129 flavor_epa_interface
["dedicated"] = "no" if iface
["virtual-interface"]["type"] == "SR-IOV" \
1131 flavor_epa_interfaces
.append(flavor_epa_interface
)
1133 raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{}]':'vdu[{}]':'interface':'virtual"
1134 "-interface':'type':'{}'. Interface type is not supported".format(
1135 vnfd_id
, vdu_id
, iface
.get("virtual-interface").get("type")),
1136 httperrors
.Bad_Request
)
1138 if iface
.get("mgmt-interface"):
1139 db_interface
["type"] = "mgmt"
1141 if iface
.get("external-connection-point-ref"):
1143 cp
= vnfd
.get("connection-point")[iface
.get("external-connection-point-ref")]
1144 db_interface
["external_name"] = get_str(cp
, "name", 255)
1145 cp_name2iface_uuid
[db_interface
["external_name"]] = iface_uuid
1146 cp_name2vm_uuid
[db_interface
["external_name"]] = vm_uuid
1147 cp_name2db_interface
[db_interface
["external_name"]] = db_interface
1148 for cp_descriptor
in vnfd_descriptor
["connection-point"]:
1149 if cp_descriptor
["name"] == db_interface
["external_name"]:
1154 if vdu_id
in vdu_id2cp_name
:
1155 vdu_id2cp_name
[vdu_id
] = None # more than two connecdtion point for this VDU
1157 vdu_id2cp_name
[vdu_id
] = db_interface
["external_name"]
1160 if str(cp_descriptor
.get("port-security-enabled")).lower() == "false":
1161 db_interface
["port_security"] = 0
1162 elif str(cp_descriptor
.get("port-security-enabled")).lower() == "true":
1163 db_interface
["port_security"] = 1
1165 raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{vnf}]':'vdu[{vdu}]':"
1166 "'interface[{iface}]':'vnfd-connection-point-ref':'{cp}' is not present"
1167 " at connection-point".format(
1168 vnf
=vnfd_id
, vdu
=vdu_id
, iface
=iface
["name"],
1169 cp
=iface
.get("vnfd-connection-point-ref")),
1170 httperrors
.Bad_Request
)
1171 elif iface
.get("internal-connection-point-ref"):
1173 for icp_descriptor
in vdu_descriptor
["internal-connection-point"]:
1174 if icp_descriptor
["id"] == str(iface
.get("internal-connection-point-ref")):
1177 raise KeyError("does not exist at vdu:internal-connection-point")
1180 for vld
in vnfd
.get("internal-vld").itervalues():
1181 for cp
in vld
.get("internal-connection-point").itervalues():
1182 if cp
.get("id-ref") == iface
.get("internal-connection-point-ref"):
1184 raise KeyError("is referenced by more than one 'internal-vld'")
1188 raise KeyError("is not referenced by any 'internal-vld'")
1190 db_interface
["net_id"] = net_id2uuid
[icp_vld
.get("id")]
1191 if str(icp_descriptor
.get("port-security-enabled")).lower() == "false":
1192 db_interface
["port_security"] = 0
1193 elif str(icp_descriptor
.get("port-security-enabled")).lower() == "true":
1194 db_interface
["port_security"] = 1
1195 if icp
.get("ip-address"):
1196 if not icp_vld
.get("ip-profile-ref"):
1198 db_interface
["ip_address"] = str(icp
.get("ip-address"))
1199 except KeyError as e
:
1200 raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{vnf}]':'vdu[{vdu}]':"
1201 "'interface[{iface}]':'internal-connection-point-ref':'{cp}'"
1203 vnf
=vnfd_id
, vdu
=vdu_id
, iface
=iface
["name"],
1204 cp
=iface
.get("internal-connection-point-ref"), msg
=str(e
)),
1205 httperrors
.Bad_Request
)
1206 if iface
.get("position"):
1207 db_interface
["created_at"] = int(iface
.get("position")) * 50
1208 if iface
.get("mac-address"):
1209 db_interface
["mac"] = str(iface
.get("mac-address"))
1210 db_interfaces
.append(db_interface
)
1214 "name": get_str(vdu
, "name", 250) + "-flv",
1215 "vcpus": int(vdu
["vm-flavor"].get("vcpu-count", 1)),
1216 "ram": int(vdu
["vm-flavor"].get("memory-mb", 1)),
1217 "disk": int(vdu
["vm-flavor"].get("storage-gb", 0)),
1219 # TODO revise the case of several numa-node-policy node
1223 extended
["devices"] = devices
1224 if flavor_epa_interfaces
:
1225 numa
["interfaces"] = flavor_epa_interfaces
1226 if vdu
.get("guest-epa"): # TODO or dedicated_int:
1227 epa_vcpu_set
= False
1228 if vdu
["guest-epa"].get("numa-node-policy"): # TODO or dedicated_int:
1229 numa_node_policy
= vdu
["guest-epa"].get("numa-node-policy")
1230 if numa_node_policy
.get("node"):
1231 numa_node
= numa_node_policy
["node"].values()[0]
1232 if numa_node
.get("num-cores"):
1233 numa
["cores"] = numa_node
["num-cores"]
1235 if numa_node
.get("paired-threads"):
1236 if numa_node
["paired-threads"].get("num-paired-threads"):
1237 numa
["paired-threads"] = int(numa_node
["paired-threads"]["num-paired-threads"])
1239 if len(numa_node
["paired-threads"].get("paired-thread-ids")):
1240 numa
["paired-threads-id"] = []
1241 for pair
in numa_node
["paired-threads"]["paired-thread-ids"].itervalues():
1242 numa
["paired-threads-id"].append(
1243 (str(pair
["thread-a"]), str(pair
["thread-b"]))
1245 if numa_node
.get("num-threads"):
1246 numa
["threads"] = int(numa_node
["num-threads"])
1248 if numa_node
.get("memory-mb"):
1249 numa
["memory"] = max(int(numa_node
["memory-mb"] / 1024), 1)
1250 if vdu
["guest-epa"].get("mempage-size"):
1251 if vdu
["guest-epa"]["mempage-size"] != "SMALL":
1252 numa
["memory"] = max(int(db_flavor
["ram"] / 1024), 1)
1253 if vdu
["guest-epa"].get("cpu-pinning-policy") and not epa_vcpu_set
:
1254 if vdu
["guest-epa"]["cpu-pinning-policy"] == "DEDICATED":
1255 if vdu
["guest-epa"].get("cpu-thread-pinning-policy") and \
1256 vdu
["guest-epa"]["cpu-thread-pinning-policy"] != "PREFER":
1257 numa
["cores"] = max(db_flavor
["vcpus"], 1)
1259 numa
["threads"] = max(db_flavor
["vcpus"], 1)
1261 extended
["numas"] = [numa
]
1263 extended_text
= yaml
.safe_dump(extended
, default_flow_style
=True, width
=256)
1264 db_flavor
["extended"] = extended_text
1265 # look if flavor exist
1266 temp_flavor_dict
= {'disk': db_flavor
.get('disk', 0),
1267 'ram': db_flavor
.get('ram'),
1268 'vcpus': db_flavor
.get('vcpus'),
1269 'extended': db_flavor
.get('extended')
1271 existing_flavors
= mydb
.get_rows(FROM
="flavors", WHERE
=temp_flavor_dict
)
1272 if existing_flavors
:
1273 flavor_uuid
= existing_flavors
[0]["uuid"]
1275 flavor_uuid
= str(uuid4())
1276 uuid_list
.append(flavor_uuid
)
1277 db_flavor
["uuid"] = flavor_uuid
1278 db_flavors
.append(db_flavor
)
1279 db_vm
["flavor_id"] = flavor_uuid
1281 # VNF affinity and antiaffinity
1282 for pg
in vnfd
.get("placement-groups").itervalues():
1283 pg_name
= get_str(pg
, "name", 255)
1284 for vdu
in pg
.get("member-vdus").itervalues():
1285 vdu_id
= get_str(vdu
, "member-vdu-ref", 255)
1286 if vdu_id
not in vdu_id2db_table_index
:
1287 raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{vnf}]':'placement-groups[{pg}]':"
1288 "'member-vdus':'{vdu}'. Reference to a non-existing vdu".format(
1289 vnf
=vnfd_id
, pg
=pg_name
, vdu
=vdu_id
),
1290 httperrors
.Bad_Request
)
1291 if vdu_id2db_table_index
[vdu_id
]:
1292 db_vms
[vdu_id2db_table_index
[vdu_id
]]["availability_zone"] = pg_name
1293 # TODO consider the case of isolation and not colocation
1294 # if pg.get("strategy") == "ISOLATION":
1296 # VNF mgmt configuration
1298 if vnfd
["mgmt-interface"].get("vdu-id"):
1299 mgmt_vdu_id
= get_str(vnfd
["mgmt-interface"], "vdu-id", 255)
1300 if mgmt_vdu_id
not in vdu_id2uuid
:
1301 raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{vnf}]':'mgmt-interface':'vdu-id':"
1302 "'{vdu}'. Reference to a non-existing vdu".format(
1303 vnf
=vnfd_id
, vdu
=mgmt_vdu_id
),
1304 httperrors
.Bad_Request
)
1305 mgmt_access
["vm_id"] = vdu_id2uuid
[vnfd
["mgmt-interface"]["vdu-id"]]
1306 # if only one cp is defined by this VDU, mark this interface as of type "mgmt"
1307 if vdu_id2cp_name
.get(mgmt_vdu_id
):
1308 if cp_name2db_interface
[vdu_id2cp_name
[mgmt_vdu_id
]]:
1309 cp_name2db_interface
[vdu_id2cp_name
[mgmt_vdu_id
]]["type"] = "mgmt"
1311 if vnfd
["mgmt-interface"].get("ip-address"):
1312 mgmt_access
["ip-address"] = str(vnfd
["mgmt-interface"].get("ip-address"))
1313 if vnfd
["mgmt-interface"].get("cp"):
1314 if vnfd
["mgmt-interface"]["cp"] not in cp_name2iface_uuid
:
1315 raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{vnf}]':'mgmt-interface':'cp'['{cp}']. "
1316 "Reference to a non-existing connection-point".format(
1317 vnf
=vnfd_id
, cp
=vnfd
["mgmt-interface"]["cp"]),
1318 httperrors
.Bad_Request
)
1319 mgmt_access
["vm_id"] = cp_name2vm_uuid
[vnfd
["mgmt-interface"]["cp"]]
1320 mgmt_access
["interface_id"] = cp_name2iface_uuid
[vnfd
["mgmt-interface"]["cp"]]
1321 # mark this interface as of type mgmt
1322 if cp_name2db_interface
[vnfd
["mgmt-interface"]["cp"]]:
1323 cp_name2db_interface
[vnfd
["mgmt-interface"]["cp"]]["type"] = "mgmt"
1325 default_user
= get_str(vnfd
.get("vnf-configuration", {}).get("config-access", {}).get("ssh-access", {}),
1329 mgmt_access
["default_user"] = default_user
1330 required
= get_str(vnfd
.get("vnf-configuration", {}).get("config-access", {}).get("ssh-access", {}),
1333 mgmt_access
["required"] = required
1336 db_vnf
["mgmt_access"] = yaml
.safe_dump(mgmt_access
, default_flow_style
=True, width
=256)
1338 db_vnfs
.append(db_vnf
)
1342 {"images": db_images
},
1343 {"flavors": db_flavors
},
1344 {"ip_profiles": db_ip_profiles
},
1346 {"interfaces": db_interfaces
},
1349 logger
.debug("create_vnf Deployment done vnfDict: %s",
1350 yaml
.safe_dump(db_tables
, indent
=4, default_flow_style
=False) )
1351 mydb
.new_rows(db_tables
, uuid_list
)
1352 return vnfd_uuid_list
1353 except NfvoException
:
1355 except Exception as e
:
1356 logger
.error("Exception {}".format(e
))
1357 raise # NfvoException("Exception {}".format(e), httperrors.Bad_Request)
1360 @deprecated("Use new_vnfd_v3")
1361 def new_vnf(mydb
, tenant_id
, vnf_descriptor
):
1362 global global_config
1364 # Step 1. Check the VNF descriptor
1365 check_vnf_descriptor(vnf_descriptor
, vnf_descriptor_version
=1)
1366 # Step 2. Check tenant exist
1368 if tenant_id
!= "any":
1369 check_tenant(mydb
, tenant_id
)
1370 if "tenant_id" in vnf_descriptor
["vnf"]:
1371 if vnf_descriptor
["vnf"]["tenant_id"] != tenant_id
:
1372 raise NfvoException("VNF can not have a different tenant owner '{}', must be '{}'".format(vnf_descriptor
["vnf"]["tenant_id"], tenant_id
),
1373 httperrors
.Unauthorized
)
1375 vnf_descriptor
['vnf']['tenant_id'] = tenant_id
1376 # Step 3. Get the URL of the VIM from the nfvo_tenant and the datacenter
1377 if global_config
["auto_push_VNF_to_VIMs"]:
1378 vims
= get_vim(mydb
, tenant_id
, ignore_errors
=True)
1380 # Step 4. Review the descriptor and add missing fields
1381 #print vnf_descriptor
1382 #logger.debug("Refactoring VNF descriptor with fields: description, public (default: true)")
1383 vnf_name
= vnf_descriptor
['vnf']['name']
1384 vnf_descriptor
['vnf']['description'] = vnf_descriptor
['vnf'].get("description", vnf_name
)
1385 if "physical" in vnf_descriptor
['vnf']:
1386 del vnf_descriptor
['vnf']['physical']
1387 #print vnf_descriptor
1389 # Step 6. For each VNFC in the descriptor, flavors and images are created in the VIM
1390 logger
.debug('BEGIN creation of VNF "%s"' % vnf_name
)
1391 logger
.debug("VNF %s: consisting of %d VNFC(s)" % (vnf_name
,len(vnf_descriptor
['vnf']['VNFC'])))
1393 #For each VNFC, we add it to the VNFCDict and we create a flavor.
1394 VNFCDict
= {} # Dictionary, key: VNFC name, value: dict with the relevant information to create the VNF and VMs in the MANO database
1395 rollback_list
= [] # It will contain the new images created in mano. It is used for rollback
1397 logger
.debug("Creating additional disk images and new flavors in the VIM for each VNFC")
1398 for vnfc
in vnf_descriptor
['vnf']['VNFC']:
1400 VNFCitem
["name"] = vnfc
['name']
1401 VNFCitem
["availability_zone"] = vnfc
.get('availability_zone')
1402 VNFCitem
["description"] = vnfc
.get("description", 'VM %s of the VNF %s' %(vnfc
['name'],vnf_name
))
1404 #print "Flavor name: %s. Description: %s" % (VNFCitem["name"]+"-flv", VNFCitem["description"])
1407 myflavorDict
["name"] = vnfc
['name']+"-flv" #Maybe we could rename the flavor by using the field "image name" if exists
1408 myflavorDict
["description"] = VNFCitem
["description"]
1409 myflavorDict
["ram"] = vnfc
.get("ram", 0)
1410 myflavorDict
["vcpus"] = vnfc
.get("vcpus", 0)
1411 myflavorDict
["disk"] = vnfc
.get("disk", 0)
1412 myflavorDict
["extended"] = {}
1414 devices
= vnfc
.get("devices")
1416 myflavorDict
["extended"]["devices"] = devices
1419 # Mapping from processor models to rankings should be available somehow in the NFVO. They could be taken from VIM or directly from a new database table
1420 # Another option is that the processor in the VNF descriptor specifies directly the ranking of the host
1422 # Previous code has been commented
1423 #if vnfc['processor']['model'] == "Intel(R) Xeon(R) CPU E5-4620 0 @ 2.20GHz" :
1424 # myflavorDict["flavor"]['extended']['processor_ranking'] = 200
1425 #elif vnfc['processor']['model'] == "Intel(R) Xeon(R) CPU E5-2697 v2 @ 2.70GHz" :
1426 # myflavorDict["flavor"]['extended']['processor_ranking'] = 300
1428 # result2, message = rollback(myvim, myvimURL, myvim_tenant, flavorList, imageList)
1430 # print "Error creating flavor: unknown processor model. Rollback successful."
1431 # return -httperrors.Bad_Request, "Error creating flavor: unknown processor model. Rollback successful."
1433 # return -httperrors.Bad_Request, "Error creating flavor: unknown processor model. Rollback fail: you need to access VIM and delete the following %s" % message
1434 myflavorDict
['extended']['processor_ranking'] = 100 #Hardcoded value, while we decide when the mapping is done
1436 if 'numas' in vnfc
and len(vnfc
['numas'])>0:
1437 myflavorDict
['extended']['numas'] = vnfc
['numas']
1441 # Step 6.2 New flavors are created in the VIM
1442 flavor_id
= create_or_use_flavor(mydb
, vims
, myflavorDict
, rollback_list
)
1444 #print "Flavor id for VNFC %s: %s" % (vnfc['name'],flavor_id)
1445 VNFCitem
["flavor_id"] = flavor_id
1446 VNFCDict
[vnfc
['name']] = VNFCitem
1448 logger
.debug("Creating new images in the VIM for each VNFC")
1449 # Step 6.3 New images are created in the VIM
1450 #For each VNFC, we must create the appropriate image.
1451 #This "for" loop might be integrated with the previous one
1452 #In case this integration is made, the VNFCDict might become a VNFClist.
1453 for vnfc
in vnf_descriptor
['vnf']['VNFC']:
1454 #print "Image name: %s. Description: %s" % (vnfc['name']+"-img", VNFCDict[vnfc['name']]['description'])
1456 image_dict
['name']=vnfc
.get('image name',vnf_name
+"-"+vnfc
['name']+"-img")
1457 image_dict
['universal_name']=vnfc
.get('image name')
1458 image_dict
['description']=vnfc
.get('image name', VNFCDict
[vnfc
['name']]['description'])
1459 image_dict
['location']=vnfc
.get('VNFC image')
1460 #image_dict['new_location']=vnfc.get('image location')
1461 image_dict
['checksum']=vnfc
.get('image checksum')
1462 image_metadata_dict
= vnfc
.get('image metadata', None)
1463 image_metadata_str
= None
1464 if image_metadata_dict
is not None:
1465 image_metadata_str
= yaml
.safe_dump(image_metadata_dict
,default_flow_style
=True,width
=256)
1466 image_dict
['metadata']=image_metadata_str
1467 #print "create_or_use_image", mydb, vims, image_dict, rollback_list
1468 image_id
= create_or_use_image(mydb
, vims
, image_dict
, rollback_list
)
1469 #print "Image id for VNFC %s: %s" % (vnfc['name'],image_id)
1470 VNFCDict
[vnfc
['name']]["image_id"] = image_id
1471 VNFCDict
[vnfc
['name']]["image_path"] = vnfc
.get('VNFC image')
1472 VNFCDict
[vnfc
['name']]["count"] = vnfc
.get('count', 1)
1473 if vnfc
.get("boot-data"):
1474 VNFCDict
[vnfc
['name']]["boot_data"] = yaml
.safe_dump(vnfc
["boot-data"], default_flow_style
=True, width
=256)
1477 # Step 7. Storing the VNF descriptor in the repository
1478 if "descriptor" not in vnf_descriptor
["vnf"]:
1479 vnf_descriptor
["vnf"]["descriptor"] = yaml
.safe_dump(vnf_descriptor
, indent
=4, explicit_start
=True, default_flow_style
=False)
1481 # Step 8. Adding the VNF to the NFVO DB
1482 vnf_id
= mydb
.new_vnf_as_a_whole(tenant_id
,vnf_name
,vnf_descriptor
,VNFCDict
)
1484 except (db_base_Exception
, vimconn
.vimconnException
, KeyError) as e
:
1485 _
, message
= rollback(mydb
, vims
, rollback_list
)
1486 if isinstance(e
, db_base_Exception
):
1487 error_text
= "Exception at database"
1488 elif isinstance(e
, KeyError):
1489 error_text
= "KeyError exception "
1490 e
.http_code
= httperrors
.Internal_Server_Error
1492 error_text
= "Exception at VIM"
1493 error_text
+= " {} {}. {}".format(type(e
).__name
__, str(e
), message
)
1494 #logger.error("start_scenario %s", error_text)
1495 raise NfvoException(error_text
, e
.http_code
)
1498 @deprecated("Use new_vnfd_v3")
1499 def new_vnf_v02(mydb
, tenant_id
, vnf_descriptor
):
1500 global global_config
1502 # Step 1. Check the VNF descriptor
1503 check_vnf_descriptor(vnf_descriptor
, vnf_descriptor_version
=2)
1504 # Step 2. Check tenant exist
1506 if tenant_id
!= "any":
1507 check_tenant(mydb
, tenant_id
)
1508 if "tenant_id" in vnf_descriptor
["vnf"]:
1509 if vnf_descriptor
["vnf"]["tenant_id"] != tenant_id
:
1510 raise NfvoException("VNF can not have a different tenant owner '{}', must be '{}'".format(vnf_descriptor
["vnf"]["tenant_id"], tenant_id
),
1511 httperrors
.Unauthorized
)
1513 vnf_descriptor
['vnf']['tenant_id'] = tenant_id
1514 # Step 3. Get the URL of the VIM from the nfvo_tenant and the datacenter
1515 if global_config
["auto_push_VNF_to_VIMs"]:
1516 vims
= get_vim(mydb
, tenant_id
, ignore_errors
=True)
1518 # Step 4. Review the descriptor and add missing fields
1519 #print vnf_descriptor
1520 #logger.debug("Refactoring VNF descriptor with fields: description, public (default: true)")
1521 vnf_name
= vnf_descriptor
['vnf']['name']
1522 vnf_descriptor
['vnf']['description'] = vnf_descriptor
['vnf'].get("description", vnf_name
)
1523 if "physical" in vnf_descriptor
['vnf']:
1524 del vnf_descriptor
['vnf']['physical']
1525 #print vnf_descriptor
1527 # Step 6. For each VNFC in the descriptor, flavors and images are created in the VIM
1528 logger
.debug('BEGIN creation of VNF "%s"' % vnf_name
)
1529 logger
.debug("VNF %s: consisting of %d VNFC(s)" % (vnf_name
,len(vnf_descriptor
['vnf']['VNFC'])))
1531 #For each VNFC, we add it to the VNFCDict and we create a flavor.
1532 VNFCDict
= {} # Dictionary, key: VNFC name, value: dict with the relevant information to create the VNF and VMs in the MANO database
1533 rollback_list
= [] # It will contain the new images created in mano. It is used for rollback
1535 logger
.debug("Creating additional disk images and new flavors in the VIM for each VNFC")
1536 for vnfc
in vnf_descriptor
['vnf']['VNFC']:
1538 VNFCitem
["name"] = vnfc
['name']
1539 VNFCitem
["description"] = vnfc
.get("description", 'VM %s of the VNF %s' %(vnfc
['name'],vnf_name
))
1541 #print "Flavor name: %s. Description: %s" % (VNFCitem["name"]+"-flv", VNFCitem["description"])
1544 myflavorDict
["name"] = vnfc
['name']+"-flv" #Maybe we could rename the flavor by using the field "image name" if exists
1545 myflavorDict
["description"] = VNFCitem
["description"]
1546 myflavorDict
["ram"] = vnfc
.get("ram", 0)
1547 myflavorDict
["vcpus"] = vnfc
.get("vcpus", 0)
1548 myflavorDict
["disk"] = vnfc
.get("disk", 0)
1549 myflavorDict
["extended"] = {}
1551 devices
= vnfc
.get("devices")
1553 myflavorDict
["extended"]["devices"] = devices
1556 # Mapping from processor models to rankings should be available somehow in the NFVO. They could be taken from VIM or directly from a new database table
1557 # Another option is that the processor in the VNF descriptor specifies directly the ranking of the host
1559 # Previous code has been commented
1560 #if vnfc['processor']['model'] == "Intel(R) Xeon(R) CPU E5-4620 0 @ 2.20GHz" :
1561 # myflavorDict["flavor"]['extended']['processor_ranking'] = 200
1562 #elif vnfc['processor']['model'] == "Intel(R) Xeon(R) CPU E5-2697 v2 @ 2.70GHz" :
1563 # myflavorDict["flavor"]['extended']['processor_ranking'] = 300
1565 # result2, message = rollback(myvim, myvimURL, myvim_tenant, flavorList, imageList)
1567 # print "Error creating flavor: unknown processor model. Rollback successful."
1568 # return -httperrors.Bad_Request, "Error creating flavor: unknown processor model. Rollback successful."
1570 # return -httperrors.Bad_Request, "Error creating flavor: unknown processor model. Rollback fail: you need to access VIM and delete the following %s" % message
1571 myflavorDict
['extended']['processor_ranking'] = 100 #Hardcoded value, while we decide when the mapping is done
1573 if 'numas' in vnfc
and len(vnfc
['numas'])>0:
1574 myflavorDict
['extended']['numas'] = vnfc
['numas']
1578 # Step 6.2 New flavors are created in the VIM
1579 flavor_id
= create_or_use_flavor(mydb
, vims
, myflavorDict
, rollback_list
)
1581 #print "Flavor id for VNFC %s: %s" % (vnfc['name'],flavor_id)
1582 VNFCitem
["flavor_id"] = flavor_id
1583 VNFCDict
[vnfc
['name']] = VNFCitem
1585 logger
.debug("Creating new images in the VIM for each VNFC")
1586 # Step 6.3 New images are created in the VIM
1587 #For each VNFC, we must create the appropriate image.
1588 #This "for" loop might be integrated with the previous one
1589 #In case this integration is made, the VNFCDict might become a VNFClist.
1590 for vnfc
in vnf_descriptor
['vnf']['VNFC']:
1591 #print "Image name: %s. Description: %s" % (vnfc['name']+"-img", VNFCDict[vnfc['name']]['description'])
1593 image_dict
['name']=vnfc
.get('image name',vnf_name
+"-"+vnfc
['name']+"-img")
1594 image_dict
['universal_name']=vnfc
.get('image name')
1595 image_dict
['description']=vnfc
.get('image name', VNFCDict
[vnfc
['name']]['description'])
1596 image_dict
['location']=vnfc
.get('VNFC image')
1597 #image_dict['new_location']=vnfc.get('image location')
1598 image_dict
['checksum']=vnfc
.get('image checksum')
1599 image_metadata_dict
= vnfc
.get('image metadata', None)
1600 image_metadata_str
= None
1601 if image_metadata_dict
is not None:
1602 image_metadata_str
= yaml
.safe_dump(image_metadata_dict
,default_flow_style
=True,width
=256)
1603 image_dict
['metadata']=image_metadata_str
1604 #print "create_or_use_image", mydb, vims, image_dict, rollback_list
1605 image_id
= create_or_use_image(mydb
, vims
, image_dict
, rollback_list
)
1606 #print "Image id for VNFC %s: %s" % (vnfc['name'],image_id)
1607 VNFCDict
[vnfc
['name']]["image_id"] = image_id
1608 VNFCDict
[vnfc
['name']]["image_path"] = vnfc
.get('VNFC image')
1609 VNFCDict
[vnfc
['name']]["count"] = vnfc
.get('count', 1)
1610 if vnfc
.get("boot-data"):
1611 VNFCDict
[vnfc
['name']]["boot_data"] = yaml
.safe_dump(vnfc
["boot-data"], default_flow_style
=True, width
=256)
1613 # Step 7. Storing the VNF descriptor in the repository
1614 if "descriptor" not in vnf_descriptor
["vnf"]:
1615 vnf_descriptor
["vnf"]["descriptor"] = yaml
.safe_dump(vnf_descriptor
, indent
=4, explicit_start
=True, default_flow_style
=False)
1617 # Step 8. Adding the VNF to the NFVO DB
1618 vnf_id
= mydb
.new_vnf_as_a_whole2(tenant_id
,vnf_name
,vnf_descriptor
,VNFCDict
)
1620 except (db_base_Exception
, vimconn
.vimconnException
, KeyError) as e
:
1621 _
, message
= rollback(mydb
, vims
, rollback_list
)
1622 if isinstance(e
, db_base_Exception
):
1623 error_text
= "Exception at database"
1624 elif isinstance(e
, KeyError):
1625 error_text
= "KeyError exception "
1626 e
.http_code
= httperrors
.Internal_Server_Error
1628 error_text
= "Exception at VIM"
1629 error_text
+= " {} {}. {}".format(type(e
).__name
__, str(e
), message
)
1630 #logger.error("start_scenario %s", error_text)
1631 raise NfvoException(error_text
, e
.http_code
)
1634 def get_vnf_id(mydb
, tenant_id
, vnf_id
):
1635 #check valid tenant_id
1636 check_tenant(mydb
, tenant_id
)
1639 if tenant_id
!= "any":
1640 where_or
["tenant_id"] = tenant_id
1641 where_or
["public"] = True
1642 vnf
= mydb
.get_table_by_uuid_name('vnfs', vnf_id
, "VNF", WHERE_OR
=where_or
, WHERE_AND_OR
="AND")
1644 vnf_id
= vnf
["uuid"]
1645 filter_keys
= ('uuid', 'name', 'description', 'public', "tenant_id", "osm_id", "created_at")
1646 filtered_content
= dict( (k
,v
) for k
,v
in vnf
.iteritems() if k
in filter_keys
)
1647 #change_keys_http2db(filtered_content, http2db_vnf, reverse=True)
1648 data
={'vnf' : filtered_content
}
1650 content
= mydb
.get_rows(FROM
='vnfs join vms on vnfs.uuid=vms.vnf_id',
1651 SELECT
=('vms.uuid as uuid', 'vms.osm_id as osm_id', 'vms.name as name', 'vms.description as description',
1653 WHERE
={'vnfs.uuid': vnf_id
} )
1654 if len(content
) != 0:
1655 #raise NfvoException("vnf '{}' not found".format(vnf_id), httperrors.Not_Found)
1656 # change boot_data into boot-data
1658 if vm
.get("boot_data"):
1659 vm
["boot-data"] = yaml
.safe_load(vm
["boot_data"])
1662 data
['vnf']['VNFC'] = content
1663 #TODO: GET all the information from a VNFC and include it in the output.
1666 content
= mydb
.get_rows(FROM
='vnfs join nets on vnfs.uuid=nets.vnf_id',
1667 SELECT
=('nets.uuid as uuid','nets.name as name','nets.description as description', 'nets.type as type', 'nets.multipoint as multipoint'),
1668 WHERE
={'vnfs.uuid': vnf_id
} )
1669 data
['vnf']['nets'] = content
1671 #GET ip-profile for each net
1672 for net
in data
['vnf']['nets']:
1673 ipprofiles
= mydb
.get_rows(FROM
='ip_profiles',
1674 SELECT
=('ip_version','subnet_address','gateway_address','dns_address','dhcp_enabled','dhcp_start_address','dhcp_count'),
1675 WHERE
={'net_id': net
["uuid"]} )
1676 if len(ipprofiles
)==1:
1677 net
["ip_profile"] = ipprofiles
[0]
1678 elif len(ipprofiles
)>1:
1679 raise NfvoException("More than one ip-profile found with this criteria: net_id='{}'".format(net
['uuid']), httperrors
.Bad_Request
)
1682 #TODO: For each net, GET its elements and relevant info per element (VNFC, iface, ip_address) and include them in the output.
1684 #GET External Interfaces
1685 content
= mydb
.get_rows(FROM
='vnfs join vms on vnfs.uuid=vms.vnf_id join interfaces on vms.uuid=interfaces.vm_id',\
1686 SELECT
=('interfaces.uuid as uuid','interfaces.external_name as external_name', 'vms.name as vm_name', 'interfaces.vm_id as vm_id', \
1687 'interfaces.internal_name as internal_name', 'interfaces.type as type', 'interfaces.vpci as vpci','interfaces.bw as bw'),\
1688 WHERE
={'vnfs.uuid': vnf_id
, 'interfaces.external_name<>': None} )
1690 data
['vnf']['external-connections'] = content
1695 def delete_vnf(mydb
,tenant_id
,vnf_id
,datacenter
=None,vim_tenant
=None):
1696 # Check tenant exist
1697 if tenant_id
!= "any":
1698 check_tenant(mydb
, tenant_id
)
1699 # Get the URL of the VIM from the nfvo_tenant and the datacenter
1700 vims
= get_vim(mydb
, tenant_id
, ignore_errors
=True)
1704 # Checking if it is a valid uuid and, if not, getting the uuid assuming that the name was provided"
1706 if tenant_id
!= "any":
1707 where_or
["tenant_id"] = tenant_id
1708 where_or
["public"] = True
1709 vnf
= mydb
.get_table_by_uuid_name('vnfs', vnf_id
, "VNF", WHERE_OR
=where_or
, WHERE_AND_OR
="AND")
1710 vnf_id
= vnf
["uuid"]
1712 # "Getting the list of flavors and tenants of the VNF"
1713 flavorList
= get_flavorlist(mydb
, vnf_id
)
1714 if len(flavorList
)==0:
1715 logger
.warn("delete_vnf error. No flavors found for the VNF id '%s'", vnf_id
)
1717 imageList
= get_imagelist(mydb
, vnf_id
)
1718 if len(imageList
)==0:
1719 logger
.warn( "delete_vnf error. No images found for the VNF id '%s'", vnf_id
)
1721 deleted
= mydb
.delete_row_by_id('vnfs', vnf_id
)
1723 raise NfvoException("vnf '{}' not found".format(vnf_id
), httperrors
.Not_Found
)
1726 for flavor
in flavorList
:
1727 #check if flavor is used by other vnf
1729 c
= mydb
.get_rows(FROM
='vms', WHERE
={'flavor_id':flavor
} )
1731 logger
.debug("Flavor '%s' not deleted because it is being used by another VNF", flavor
)
1733 #flavor not used, must be deleted
1735 c
= mydb
.get_rows(FROM
='datacenters_flavors', WHERE
={'flavor_id': flavor
})
1736 for flavor_vim
in c
:
1737 if not flavor_vim
['created']: # skip this flavor because not created by openmano
1741 for vim
in vims
.values():
1742 if vim
["config"]["datacenter_tenant_id"] == flavor_vim
["datacenter_vim_id"]:
1748 myvim
.delete_flavor(flavor_vim
["vim_id"])
1749 except vimconn
.vimconnNotFoundException
:
1750 logger
.warn("VIM flavor %s not exist at datacenter %s", flavor_vim
["vim_id"],
1751 flavor_vim
["datacenter_vim_id"] )
1752 except vimconn
.vimconnException
as e
:
1753 logger
.error("Not possible to delete VIM flavor %s from datacenter %s: %s %s",
1754 flavor_vim
["vim_id"], flavor_vim
["datacenter_vim_id"], type(e
).__name
__, str(e
))
1755 undeletedItems
.append("flavor {} from VIM {}".format(flavor_vim
["vim_id"],
1756 flavor_vim
["datacenter_vim_id"]))
1757 # delete flavor from Database, using table flavors and with cascade foreign key also at datacenters_flavors
1758 mydb
.delete_row_by_id('flavors', flavor
)
1759 except db_base_Exception
as e
:
1760 logger
.error("delete_vnf_error. Not possible to get flavor details and delete '%s'. %s", flavor
, str(e
))
1761 undeletedItems
.append("flavor {}".format(flavor
))
1764 for image
in imageList
:
1766 #check if image is used by other vnf
1767 c
= mydb
.get_rows(FROM
='vms', WHERE
=[{'image_id': image
}, {'image_list LIKE ': '%' + image
+ '%'}])
1769 logger
.debug("Image '%s' not deleted because it is being used by another VNF", image
)
1771 #image not used, must be deleted
1773 c
= mydb
.get_rows(FROM
='datacenters_images', WHERE
={'image_id':image
})
1775 if image_vim
["datacenter_vim_id"] not in vims
: # TODO change to datacenter_tenant_id
1777 if image_vim
['created']=='false': #skip this image because not created by openmano
1779 myvim
=vims
[ image_vim
["datacenter_id"] ]
1781 myvim
.delete_image(image_vim
["vim_id"])
1782 except vimconn
.vimconnNotFoundException
as e
:
1783 logger
.warn("VIM image %s not exist at datacenter %s", image_vim
["vim_id"], image_vim
["datacenter_id"] )
1784 except vimconn
.vimconnException
as e
:
1785 logger
.error("Not possible to delete VIM image %s from datacenter %s: %s %s",
1786 image_vim
["vim_id"], image_vim
["datacenter_id"], type(e
).__name
__, str(e
))
1787 undeletedItems
.append("image {} from VIM {}".format(image_vim
["vim_id"], image_vim
["datacenter_id"] ))
1788 #delete image from Database, using table images and with cascade foreign key also at datacenters_images
1789 mydb
.delete_row_by_id('images', image
)
1790 except db_base_Exception
as e
:
1791 logger
.error("delete_vnf_error. Not possible to get image details and delete '%s'. %s", image
, str(e
))
1792 undeletedItems
.append("image %s" % image
)
1794 return vnf_id
+ " " + vnf
["name"]
1796 # return "delete_vnf. Undeleted: %s" %(undeletedItems)
1799 @deprecated("Not used")
1800 def get_hosts_info(mydb
, nfvo_tenant_id
, datacenter_name
=None):
1801 result
, vims
= get_vim(mydb
, nfvo_tenant_id
, None, datacenter_name
)
1805 return -httperrors
.Not_Found
, "datacenter '%s' not found" % datacenter_name
1806 myvim
= vims
.values()[0]
1807 result
,servers
= myvim
.get_hosts_info()
1809 return result
, servers
1810 topology
= {'name':myvim
['name'] , 'servers': servers
}
1811 return result
, topology
1814 def get_hosts(mydb
, nfvo_tenant_id
):
1815 vims
= get_vim(mydb
, nfvo_tenant_id
)
1817 raise NfvoException("No datacenter found for tenant '{}'".format(str(nfvo_tenant_id
)), httperrors
.Not_Found
)
1819 #print "nfvo.datacenter_action() error. Several datacenters found"
1820 raise NfvoException("More than one datacenters found, try to identify with uuid", httperrors
.Conflict
)
1821 myvim
= vims
.values()[0]
1823 hosts
= myvim
.get_hosts()
1824 logger
.debug('VIM hosts response: '+ yaml
.safe_dump(hosts
, indent
=4, default_flow_style
=False))
1826 datacenter
= {'Datacenters': [ {'name':myvim
['name'],'servers':[]} ] }
1828 server
={'name':host
['name'], 'vms':[]}
1829 for vm
in host
['instances']:
1830 #get internal name and model
1832 c
= mydb
.get_rows(SELECT
=('name',), FROM
='instance_vms as iv join vms on iv.vm_id=vms.uuid',\
1833 WHERE
={'vim_vm_id':vm
['id']} )
1835 logger
.warn("nfvo.get_hosts virtual machine at VIM '{}' not found at tidnfvo".format(vm
['id']))
1837 server
['vms'].append( {'name':vm
['name'] , 'model':c
[0]['name']} )
1839 except db_base_Exception
as e
:
1840 logger
.warn("nfvo.get_hosts virtual machine at VIM '{}' error {}".format(vm
['id'], str(e
)))
1841 datacenter
['Datacenters'][0]['servers'].append(server
)
1842 #return -400, "en construccion"
1844 #print 'datacenters '+ json.dumps(datacenter, indent=4)
1846 except vimconn
.vimconnException
as e
:
1847 raise NfvoException("Not possible to get_host_list from VIM: {}".format(str(e
)), e
.http_code
)
1850 @deprecated("Use new_nsd_v3")
1851 def new_scenario(mydb
, tenant_id
, topo
):
1853 # result, vims = get_vim(mydb, tenant_id)
1855 # return result, vims
1857 if tenant_id
!= "any":
1858 check_tenant(mydb
, tenant_id
)
1859 if "tenant_id" in topo
:
1860 if topo
["tenant_id"] != tenant_id
:
1861 raise NfvoException("VNF can not have a different tenant owner '{}', must be '{}'".format(topo
["tenant_id"], tenant_id
),
1862 httperrors
.Unauthorized
)
1866 #1.1: get VNFs and external_networks (other_nets).
1868 other_nets
={} #external_networks, bridge_networks and data_networkds
1869 nodes
= topo
['topology']['nodes']
1870 for k
in nodes
.keys():
1871 if nodes
[k
]['type'] == 'VNF':
1873 vnfs
[k
]['ifaces'] = {}
1874 elif nodes
[k
]['type'] == 'other_network' or nodes
[k
]['type'] == 'external_network':
1875 other_nets
[k
] = nodes
[k
]
1876 other_nets
[k
]['external']=True
1877 elif nodes
[k
]['type'] == 'network':
1878 other_nets
[k
] = nodes
[k
]
1879 other_nets
[k
]['external']=False
1882 #1.2: Check that VNF are present at database table vnfs. Insert uuid, description and external interfaces
1883 for name
,vnf
in vnfs
.items():
1884 where
= {"OR": {"tenant_id": tenant_id
, 'public': "true"}}
1886 error_pos
= "'topology':'nodes':'" + name
+ "'"
1888 error_text
+= " 'vnf_id' " + vnf
['vnf_id']
1889 where
['uuid'] = vnf
['vnf_id']
1890 if 'VNF model' in vnf
:
1891 error_text
+= " 'VNF model' " + vnf
['VNF model']
1892 where
['name'] = vnf
['VNF model']
1894 raise NfvoException("Descriptor need a 'vnf_id' or 'VNF model' field at " + error_pos
, httperrors
.Bad_Request
)
1896 vnf_db
= mydb
.get_rows(SELECT
=('uuid','name','description'),
1900 raise NfvoException("unknown" + error_text
+ " at " + error_pos
, httperrors
.Not_Found
)
1902 raise NfvoException("more than one" + error_text
+ " at " + error_pos
+ " Concrete with 'vnf_id'", httperrors
.Conflict
)
1903 vnf
['uuid']=vnf_db
[0]['uuid']
1904 vnf
['description']=vnf_db
[0]['description']
1905 #get external interfaces
1906 ext_ifaces
= mydb
.get_rows(SELECT
=('external_name as name','i.uuid as iface_uuid', 'i.type as type'),
1907 FROM
='vnfs join vms on vnfs.uuid=vms.vnf_id join interfaces as i on vms.uuid=i.vm_id',
1908 WHERE
={'vnfs.uuid':vnf
['uuid'], 'external_name<>': None} )
1909 for ext_iface
in ext_ifaces
:
1910 vnf
['ifaces'][ ext_iface
['name'] ] = {'uuid':ext_iface
['iface_uuid'], 'type':ext_iface
['type']}
1912 #1.4 get list of connections
1913 conections
= topo
['topology']['connections']
1914 conections_list
= []
1915 conections_list_name
= []
1916 for k
in conections
.keys():
1917 if type(conections
[k
]['nodes'])==dict: #dict with node:iface pairs
1918 ifaces_list
= conections
[k
]['nodes'].items()
1919 elif type(conections
[k
]['nodes'])==list: #list with dictionary
1921 conection_pair_list
= map(lambda x
: x
.items(), conections
[k
]['nodes'] )
1922 for k2
in conection_pair_list
:
1925 con_type
= conections
[k
].get("type", "link")
1926 if con_type
!= "link":
1928 raise NfvoException("Format error. Reapeted network name at 'topology':'connections':'{}'".format(str(k
)), httperrors
.Bad_Request
)
1929 other_nets
[k
] = {'external': False}
1930 if conections
[k
].get("graph"):
1931 other_nets
[k
]["graph"] = conections
[k
]["graph"]
1932 ifaces_list
.append( (k
, None) )
1935 if con_type
== "external_network":
1936 other_nets
[k
]['external'] = True
1937 if conections
[k
].get("model"):
1938 other_nets
[k
]["model"] = conections
[k
]["model"]
1940 other_nets
[k
]["model"] = k
1941 if con_type
== "dataplane_net" or con_type
== "bridge_net":
1942 other_nets
[k
]["model"] = con_type
1944 conections_list_name
.append(k
)
1945 conections_list
.append(set(ifaces_list
)) #from list to set to operate as a set (this conversion removes elements that are repeated in a list)
1946 #print set(ifaces_list)
1947 #check valid VNF and iface names
1948 for iface
in ifaces_list
:
1949 if iface
[0] not in vnfs
and iface
[0] not in other_nets
:
1950 raise NfvoException("format error. Invalid VNF name at 'topology':'connections':'{}':'nodes':'{}'".format(
1951 str(k
), iface
[0]), httperrors
.Not_Found
)
1952 if iface
[0] in vnfs
and iface
[1] not in vnfs
[ iface
[0] ]['ifaces']:
1953 raise NfvoException("format error. Invalid interface name at 'topology':'connections':'{}':'nodes':'{}':'{}'".format(
1954 str(k
), iface
[0], iface
[1]), httperrors
.Not_Found
)
1956 #1.5 unify connections from the pair list to a consolidated list
1958 while index
< len(conections_list
):
1960 while index2
< len(conections_list
):
1961 if len(conections_list
[index
] & conections_list
[index2
])>0: #common interface, join nets
1962 conections_list
[index
] |
= conections_list
[index2
]
1963 del conections_list
[index2
]
1964 del conections_list_name
[index2
]
1967 conections_list
[index
] = list(conections_list
[index
]) # from set to list again
1969 #for k in conections_list:
1974 #1.6 Delete non external nets
1975 # for k in other_nets.keys():
1976 # if other_nets[k]['model']=='bridge' or other_nets[k]['model']=='dataplane_net' or other_nets[k]['model']=='bridge_net':
1977 # for con in conections_list:
1979 # for index in range(0,len(con)):
1980 # if con[index][0] == k: delete_indexes.insert(0,index) #order from higher to lower
1981 # for index in delete_indexes:
1984 #1.7: Check external_ports are present at database table datacenter_nets
1985 for k
,net
in other_nets
.items():
1986 error_pos
= "'topology':'nodes':'" + k
+ "'"
1987 if net
['external']==False:
1988 if 'name' not in net
:
1990 if 'model' not in net
:
1991 raise NfvoException("needed a 'model' at " + error_pos
, httperrors
.Bad_Request
)
1992 if net
['model']=='bridge_net':
1993 net
['type']='bridge';
1994 elif net
['model']=='dataplane_net':
1997 raise NfvoException("unknown 'model' '"+ net
['model'] +"' at " + error_pos
, httperrors
.Not_Found
)
1999 #IF we do not want to check that external network exist at datacenter
2004 # if 'net_id' in net:
2005 # error_text += " 'net_id' " + net['net_id']
2006 # WHERE_['uuid'] = net['net_id']
2007 # if 'model' in net:
2008 # error_text += " 'model' " + net['model']
2009 # WHERE_['name'] = net['model']
2010 # if len(WHERE_) == 0:
2011 # return -httperrors.Bad_Request, "needed a 'net_id' or 'model' at " + error_pos
2012 # r,net_db = mydb.get_table(SELECT=('uuid','name','description','type','shared'),
2013 # FROM='datacenter_nets', WHERE=WHERE_ )
2015 # print "nfvo.new_scenario Error getting datacenter_nets",r,net_db
2017 # print "nfvo.new_scenario Error" +error_text+ " is not present at database"
2018 # return -httperrors.Bad_Request, "unknown " +error_text+ " at " + error_pos
2020 # print "nfvo.new_scenario Error more than one external_network for " +error_text+ " is present at database"
2021 # return -httperrors.Bad_Request, "more than one external_network for " +error_text+ "at "+ error_pos + " Concrete with 'net_id'"
2022 # other_nets[k].update(net_db[0])
2025 net_nb
=0 #Number of nets
2026 for con
in conections_list
:
2027 #check if this is connected to a external net
2031 for index
in range(0,len(con
)):
2032 #check if this is connected to a external net
2033 for net_key
in other_nets
.keys():
2034 if con
[index
][0]==net_key
:
2035 if other_net_index
>=0:
2036 error_text
="There is some interface connected both to net '%s' and net '%s'" % (con
[other_net_index
][0], net_key
)
2037 #print "nfvo.new_scenario " + error_text
2038 raise NfvoException(error_text
, httperrors
.Bad_Request
)
2040 other_net_index
= index
2041 net_target
= net_key
2043 #print "other_net_index", other_net_index
2045 if other_net_index
>=0:
2046 del con
[other_net_index
]
2047 #IF we do not want to check that external network exist at datacenter
2048 if other_nets
[net_target
]['external'] :
2049 if "name" not in other_nets
[net_target
]:
2050 other_nets
[net_target
]['name'] = other_nets
[net_target
]['model']
2051 if other_nets
[net_target
]["type"] == "external_network":
2052 if vnfs
[ con
[0][0] ]['ifaces'][ con
[0][1] ]["type"] == "data":
2053 other_nets
[net_target
]["type"] = "data"
2055 other_nets
[net_target
]["type"] = "bridge"
2057 # if other_nets[net_target]['external'] :
2058 # type_='data' if len(con)>1 else 'ptp' #an external net is connected to a external port, so it is ptp if only one connection is done to this net
2059 # if type_=='data' and other_nets[net_target]['type']=="ptp":
2060 # error_text = "Error connecting %d nodes on a not multipoint net %s" % (len(con), net_target)
2061 # print "nfvo.new_scenario " + error_text
2062 # return -httperrors.Bad_Request, error_text
2065 vnfs
[ iface
[0] ]['ifaces'][ iface
[1] ]['net_key'] = net_target
2068 net_type_bridge
=False
2070 net_target
= "__-__net"+str(net_nb
)
2071 net_list
[net_target
] = {'name': conections_list_name
[net_nb
], #"net-"+str(net_nb),
2072 'description':"net-%s in scenario %s" %(net_nb
,topo
['name']),
2075 vnfs
[ iface
[0] ]['ifaces'][ iface
[1] ]['net_key'] = net_target
2076 iface_type
= vnfs
[ iface
[0] ]['ifaces'][ iface
[1] ]['type']
2077 if iface_type
=='mgmt' or iface_type
=='bridge':
2078 net_type_bridge
= True
2080 net_type_data
= True
2081 if net_type_bridge
and net_type_data
:
2082 error_text
= "Error connection interfaces of bridge type with data type. Firs node %s, iface %s" % (iface
[0], iface
[1])
2083 #print "nfvo.new_scenario " + error_text
2084 raise NfvoException(error_text
, httperrors
.Bad_Request
)
2085 elif net_type_bridge
:
2088 type_
='data' if len(con
)>2 else 'ptp'
2089 net_list
[net_target
]['type'] = type_
2092 error_text
= "Error connection node %s : %s does not match any VNF or interface" % (iface
[0], iface
[1])
2093 #print "nfvo.new_scenario " + error_text
2095 raise NfvoException(error_text
, httperrors
.Bad_Request
)
2097 #1.8: Connect to management net all not already connected interfaces of type 'mgmt'
2098 #1.8.1 obtain management net
2099 mgmt_net
= mydb
.get_rows(SELECT
=('uuid','name','description','type','shared'),
2100 FROM
='datacenter_nets', WHERE
={'name':'mgmt'} )
2101 #1.8.2 check all interfaces from all vnfs
2103 add_mgmt_net
= False
2104 for vnf
in vnfs
.values():
2105 for iface
in vnf
['ifaces'].values():
2106 if iface
['type']=='mgmt' and 'net_key' not in iface
:
2107 #iface not connected
2108 iface
['net_key'] = 'mgmt'
2110 if add_mgmt_net
and 'mgmt' not in net_list
:
2111 net_list
['mgmt']=mgmt_net
[0]
2112 net_list
['mgmt']['external']=True
2113 net_list
['mgmt']['graph']={'visible':False}
2115 net_list
.update(other_nets
)
2117 #print 'net_list', net_list
2122 #2: insert scenario. filling tables scenarios,sce_vnfs,sce_interfaces,sce_nets
2123 c
= mydb
.new_scenario( { 'vnfs':vnfs
, 'nets':net_list
,
2124 'tenant_id':tenant_id
, 'name':topo
['name'],
2125 'description':topo
.get('description',topo
['name']),
2126 'public': topo
.get('public', False)
2132 @deprecated("Use new_nsd_v3")
2133 def new_scenario_v02(mydb
, tenant_id
, scenario_dict
, version
):
2134 """ This creates a new scenario for version 0.2 and 0.3"""
2135 scenario
= scenario_dict
["scenario"]
2136 if tenant_id
!= "any":
2137 check_tenant(mydb
, tenant_id
)
2138 if "tenant_id" in scenario
:
2139 if scenario
["tenant_id"] != tenant_id
:
2140 # print "nfvo.new_scenario_v02() tenant '%s' not found" % tenant_id
2141 raise NfvoException("VNF can not have a different tenant owner '{}', must be '{}'".format(
2142 scenario
["tenant_id"], tenant_id
), httperrors
.Unauthorized
)
2146 # 1: Check that VNF are present at database table vnfs and update content into scenario dict
2147 for name
,vnf
in scenario
["vnfs"].iteritems():
2148 where
= {"OR": {"tenant_id": tenant_id
, 'public': "true"}}
2150 error_pos
= "'scenario':'vnfs':'" + name
+ "'"
2152 error_text
+= " 'vnf_id' " + vnf
['vnf_id']
2153 where
['uuid'] = vnf
['vnf_id']
2154 if 'vnf_name' in vnf
:
2155 error_text
+= " 'vnf_name' " + vnf
['vnf_name']
2156 where
['name'] = vnf
['vnf_name']
2158 raise NfvoException("Needed a 'vnf_id' or 'vnf_name' at " + error_pos
, httperrors
.Bad_Request
)
2159 vnf_db
= mydb
.get_rows(SELECT
=('uuid', 'name', 'description'),
2162 if len(vnf_db
) == 0:
2163 raise NfvoException("Unknown" + error_text
+ " at " + error_pos
, httperrors
.Not_Found
)
2164 elif len(vnf_db
) > 1:
2165 raise NfvoException("More than one" + error_text
+ " at " + error_pos
+ " Concrete with 'vnf_id'", httperrors
.Conflict
)
2166 vnf
['uuid'] = vnf_db
[0]['uuid']
2167 vnf
['description'] = vnf_db
[0]['description']
2169 # get external interfaces
2170 ext_ifaces
= mydb
.get_rows(SELECT
=('external_name as name', 'i.uuid as iface_uuid', 'i.type as type'),
2171 FROM
='vnfs join vms on vnfs.uuid=vms.vnf_id join interfaces as i on vms.uuid=i.vm_id',
2172 WHERE
={'vnfs.uuid':vnf
['uuid'], 'external_name<>': None} )
2173 for ext_iface
in ext_ifaces
:
2174 vnf
['ifaces'][ ext_iface
['name'] ] = {'uuid':ext_iface
['iface_uuid'], 'type': ext_iface
['type']}
2175 # TODO? get internal-connections from db.nets and their profiles, and update scenario[vnfs][internal-connections] accordingly
2177 # 2: Insert net_key and ip_address at every vnf interface
2178 for net_name
, net
in scenario
["networks"].items():
2179 net_type_bridge
= False
2180 net_type_data
= False
2181 for iface_dict
in net
["interfaces"]:
2182 if version
== "0.2":
2183 temp_dict
= iface_dict
2185 elif version
== "0.3":
2186 temp_dict
= {iface_dict
["vnf"] : iface_dict
["vnf_interface"]}
2187 ip_address
= iface_dict
.get('ip_address', None)
2188 for vnf
, iface
in temp_dict
.items():
2189 if vnf
not in scenario
["vnfs"]:
2190 error_text
= "Error at 'networks':'{}':'interfaces' VNF '{}' not match any VNF at 'vnfs'".format(
2192 # logger.debug("nfvo.new_scenario_v02 " + error_text)
2193 raise NfvoException(error_text
, httperrors
.Not_Found
)
2194 if iface
not in scenario
["vnfs"][vnf
]['ifaces']:
2195 error_text
= "Error at 'networks':'{}':'interfaces':'{}' interface not match any VNF interface"\
2196 .format(net_name
, iface
)
2197 # logger.debug("nfvo.new_scenario_v02 " + error_text)
2198 raise NfvoException(error_text
, httperrors
.Bad_Request
)
2199 if "net_key" in scenario
["vnfs"][vnf
]['ifaces'][iface
]:
2200 error_text
= "Error at 'networks':'{}':'interfaces':'{}' interface already connected at network"\
2201 "'{}'".format(net_name
, iface
,scenario
["vnfs"][vnf
]['ifaces'][iface
]['net_key'])
2202 # logger.debug("nfvo.new_scenario_v02 " + error_text)
2203 raise NfvoException(error_text
, httperrors
.Bad_Request
)
2204 scenario
["vnfs"][vnf
]['ifaces'][ iface
]['net_key'] = net_name
2205 scenario
["vnfs"][vnf
]['ifaces'][iface
]['ip_address'] = ip_address
2206 iface_type
= scenario
["vnfs"][vnf
]['ifaces'][iface
]['type']
2207 if iface_type
== 'mgmt' or iface_type
== 'bridge':
2208 net_type_bridge
= True
2210 net_type_data
= True
2212 if net_type_bridge
and net_type_data
:
2213 error_text
= "Error connection interfaces of 'bridge' type and 'data' type at 'networks':'{}':'interfaces'"\
2215 # logger.debug("nfvo.new_scenario " + error_text)
2216 raise NfvoException(error_text
, httperrors
.Bad_Request
)
2217 elif net_type_bridge
:
2220 type_
= 'data' if len(net
["interfaces"]) > 2 else 'ptp'
2222 if net
.get("implementation"): # for v0.3
2223 if type_
== "bridge" and net
["implementation"] == "underlay":
2224 error_text
= "Error connecting interfaces of data type to a network declared as 'underlay' at "\
2225 "'network':'{}'".format(net_name
)
2226 # logger.debug(error_text)
2227 raise NfvoException(error_text
, httperrors
.Bad_Request
)
2228 elif type_
!= "bridge" and net
["implementation"] == "overlay":
2229 error_text
= "Error connecting interfaces of data type to a network declared as 'overlay' at "\
2230 "'network':'{}'".format(net_name
)
2231 # logger.debug(error_text)
2232 raise NfvoException(error_text
, httperrors
.Bad_Request
)
2233 net
.pop("implementation")
2234 if "type" in net
and version
== "0.3": # for v0.3
2235 if type_
== "data" and net
["type"] == "e-line":
2236 error_text
= "Error connecting more than 2 interfaces of data type to a network declared as type "\
2237 "'e-line' at 'network':'{}'".format(net_name
)
2238 # logger.debug(error_text)
2239 raise NfvoException(error_text
, httperrors
.Bad_Request
)
2240 elif type_
== "ptp" and net
["type"] == "e-lan":
2244 net
['name'] = net_name
2245 net
['external'] = net
.get('external', False)
2247 # 3: insert at database
2248 scenario
["nets"] = scenario
["networks"]
2249 scenario
['tenant_id'] = tenant_id
2250 scenario_id
= mydb
.new_scenario(scenario
)
2254 def new_nsd_v3(mydb
, tenant_id
, nsd_descriptor
):
2256 Parses an OSM IM nsd_catalog and insert at DB
2259 :param nsd_descriptor:
2260 :return: The list of created NSD ids
2263 mynsd
= nsd_catalog
.nsd()
2265 pybindJSONDecoder
.load_ietf_json(nsd_descriptor
, None, None, obj
=mynsd
)
2266 except Exception as e
:
2267 raise NfvoException("Error. Invalid NS descriptor format: " + str(e
), httperrors
.Bad_Request
)
2271 db_sce_interfaces
= []
2274 db_sce_rsp_hops
= []
2275 db_sce_classifiers
= []
2276 db_sce_classifier_matches
= []
2278 db_ip_profiles_index
= 0
2281 for nsd_yang
in mynsd
.nsd_catalog
.nsd
.itervalues():
2282 nsd
= nsd_yang
.get()
2285 scenario_uuid
= str(uuid4())
2286 uuid_list
.append(scenario_uuid
)
2287 nsd_uuid_list
.append(scenario_uuid
)
2289 "uuid": scenario_uuid
,
2290 "osm_id": get_str(nsd
, "id", 255),
2291 "name": get_str(nsd
, "name", 255),
2292 "description": get_str(nsd
, "description", 255),
2293 "tenant_id": tenant_id
,
2294 "vendor": get_str(nsd
, "vendor", 255),
2295 "short_name": get_str(nsd
, "short-name", 255),
2296 "descriptor": str(nsd_descriptor
)[:60000],
2298 db_scenarios
.append(db_scenario
)
2300 # table sce_vnfs (constituent-vnfd)
2301 vnf_index2scevnf_uuid
= {}
2302 vnf_index2vnf_uuid
= {}
2303 for vnf
in nsd
.get("constituent-vnfd").itervalues():
2304 existing_vnf
= mydb
.get_rows(FROM
="vnfs", WHERE
={'osm_id': str(vnf
["vnfd-id-ref"])[:255],
2305 'tenant_id': tenant_id
})
2306 if not existing_vnf
:
2307 raise NfvoException("Error. Invalid NS descriptor at 'nsd[{}]':'constituent-vnfd':'vnfd-id-ref':"
2308 "'{}'. Reference to a non-existing VNFD in the catalog".format(
2309 str(nsd
["id"]), str(vnf
["vnfd-id-ref"])[:255]),
2310 httperrors
.Bad_Request
)
2311 sce_vnf_uuid
= str(uuid4())
2312 uuid_list
.append(sce_vnf_uuid
)
2314 "uuid": sce_vnf_uuid
,
2315 "scenario_id": scenario_uuid
,
2316 # "name": get_str(vnf, "member-vnf-index", 255),
2317 "name": existing_vnf
[0]["name"][:200] + "." + get_str(vnf
, "member-vnf-index", 50),
2318 "vnf_id": existing_vnf
[0]["uuid"],
2319 "member_vnf_index": str(vnf
["member-vnf-index"]),
2320 # TODO 'start-by-default': True
2322 vnf_index2scevnf_uuid
[str(vnf
['member-vnf-index'])] = sce_vnf_uuid
2323 vnf_index2vnf_uuid
[str(vnf
['member-vnf-index'])] = existing_vnf
[0]["uuid"]
2324 db_sce_vnfs
.append(db_sce_vnf
)
2326 # table ip_profiles (ip-profiles)
2327 ip_profile_name2db_table_index
= {}
2328 for ip_profile
in nsd
.get("ip-profiles").itervalues():
2330 "ip_version": str(ip_profile
["ip-profile-params"].get("ip-version", "ipv4")),
2331 "subnet_address": str(ip_profile
["ip-profile-params"].get("subnet-address")),
2332 "gateway_address": str(ip_profile
["ip-profile-params"].get("gateway-address")),
2333 "dhcp_enabled": str(ip_profile
["ip-profile-params"]["dhcp-params"].get("enabled", True)),
2334 "dhcp_start_address": str(ip_profile
["ip-profile-params"]["dhcp-params"].get("start-address")),
2335 "dhcp_count": str(ip_profile
["ip-profile-params"]["dhcp-params"].get("count")),
2338 for dns
in ip_profile
["ip-profile-params"]["dns-server"].itervalues():
2339 dns_list
.append(str(dns
.get("address")))
2340 db_ip_profile
["dns_address"] = ";".join(dns_list
)
2341 if ip_profile
["ip-profile-params"].get('security-group'):
2342 db_ip_profile
["security_group"] = ip_profile
["ip-profile-params"]['security-group']
2343 ip_profile_name2db_table_index
[str(ip_profile
["name"])] = db_ip_profiles_index
2344 db_ip_profiles_index
+= 1
2345 db_ip_profiles
.append(db_ip_profile
)
2347 # table sce_nets (internal-vld)
2348 for vld
in nsd
.get("vld").itervalues():
2349 sce_net_uuid
= str(uuid4())
2350 uuid_list
.append(sce_net_uuid
)
2352 "uuid": sce_net_uuid
,
2353 "name": get_str(vld
, "name", 255),
2354 "scenario_id": scenario_uuid
,
2356 "multipoint": not vld
.get("type") == "ELINE",
2357 "osm_id": get_str(vld
, "id", 255),
2359 "description": get_str(vld
, "description", 255),
2361 # guess type of network
2362 if vld
.get("mgmt-network"):
2363 db_sce_net
["type"] = "bridge"
2364 db_sce_net
["external"] = True
2365 elif vld
.get("provider-network").get("overlay-type") == "VLAN":
2366 db_sce_net
["type"] = "data"
2368 # later on it will be fixed to bridge or data depending on the type of interfaces attached to it
2369 db_sce_net
["type"] = None
2370 db_sce_nets
.append(db_sce_net
)
2372 # ip-profile, link db_ip_profile with db_sce_net
2373 if vld
.get("ip-profile-ref"):
2374 ip_profile_name
= vld
.get("ip-profile-ref")
2375 if ip_profile_name
not in ip_profile_name2db_table_index
:
2376 raise NfvoException("Error. Invalid NS descriptor at 'nsd[{}]':'vld[{}]':'ip-profile-ref':'{}'."
2377 " Reference to a non-existing 'ip_profiles'".format(
2378 str(nsd
["id"]), str(vld
["id"]), str(vld
["ip-profile-ref"])),
2379 httperrors
.Bad_Request
)
2380 db_ip_profiles
[ip_profile_name2db_table_index
[ip_profile_name
]]["sce_net_id"] = sce_net_uuid
2381 elif vld
.get("vim-network-name"):
2382 db_sce_net
["vim_network_name"] = get_str(vld
, "vim-network-name", 255)
2384 # table sce_interfaces (vld:vnfd-connection-point-ref)
2385 for iface
in vld
.get("vnfd-connection-point-ref").itervalues():
2386 vnf_index
= str(iface
['member-vnf-index-ref'])
2387 # check correct parameters
2388 if vnf_index
not in vnf_index2vnf_uuid
:
2389 raise NfvoException("Error. Invalid NS descriptor at 'nsd[{}]':'vld[{}]':'vnfd-connection-point"
2390 "-ref':'member-vnf-index-ref':'{}'. Reference to a non-existing index at "
2391 "'nsd':'constituent-vnfd'".format(
2392 str(nsd
["id"]), str(vld
["id"]), str(iface
["member-vnf-index-ref"])),
2393 httperrors
.Bad_Request
)
2395 existing_ifaces
= mydb
.get_rows(SELECT
=('i.uuid as uuid', 'i.type as iface_type'),
2396 FROM
="interfaces as i join vms on i.vm_id=vms.uuid",
2397 WHERE
={'vnf_id': vnf_index2vnf_uuid
[vnf_index
],
2398 'external_name': get_str(iface
, "vnfd-connection-point-ref",
2400 if not existing_ifaces
:
2401 raise NfvoException("Error. Invalid NS descriptor at 'nsd[{}]':'vld[{}]':'vnfd-connection-point"
2402 "-ref':'vnfd-connection-point-ref':'{}'. Reference to a non-existing "
2403 "connection-point name at VNFD '{}'".format(
2404 str(nsd
["id"]), str(vld
["id"]), str(iface
["vnfd-connection-point-ref"]),
2405 str(iface
.get("vnfd-id-ref"))[:255]),
2406 httperrors
.Bad_Request
)
2407 interface_uuid
= existing_ifaces
[0]["uuid"]
2408 if existing_ifaces
[0]["iface_type"] == "data" and not db_sce_net
["type"]:
2409 db_sce_net
["type"] = "data"
2410 sce_interface_uuid
= str(uuid4())
2411 uuid_list
.append(sce_net_uuid
)
2412 iface_ip_address
= None
2413 if iface
.get("ip-address"):
2414 iface_ip_address
= str(iface
.get("ip-address"))
2415 db_sce_interface
= {
2416 "uuid": sce_interface_uuid
,
2417 "sce_vnf_id": vnf_index2scevnf_uuid
[vnf_index
],
2418 "sce_net_id": sce_net_uuid
,
2419 "interface_id": interface_uuid
,
2420 "ip_address": iface_ip_address
,
2422 db_sce_interfaces
.append(db_sce_interface
)
2423 if not db_sce_net
["type"]:
2424 db_sce_net
["type"] = "bridge"
2426 # table sce_vnffgs (vnffgd)
2427 for vnffg
in nsd
.get("vnffgd").itervalues():
2428 sce_vnffg_uuid
= str(uuid4())
2429 uuid_list
.append(sce_vnffg_uuid
)
2431 "uuid": sce_vnffg_uuid
,
2432 "name": get_str(vnffg
, "name", 255),
2433 "scenario_id": scenario_uuid
,
2434 "vendor": get_str(vnffg
, "vendor", 255),
2435 "description": get_str(vld
, "description", 255),
2437 db_sce_vnffgs
.append(db_sce_vnffg
)
2441 for rsp
in vnffg
.get("rsp").itervalues():
2442 sce_rsp_uuid
= str(uuid4())
2443 uuid_list
.append(sce_rsp_uuid
)
2445 "uuid": sce_rsp_uuid
,
2446 "name": get_str(rsp
, "name", 255),
2447 "sce_vnffg_id": sce_vnffg_uuid
,
2448 "id": get_str(rsp
, "id", 255), # only useful to link with classifiers; will be removed later in the code
2450 db_sce_rsps
.append(db_sce_rsp
)
2451 db_sce_rsp_hops
= []
2452 for iface
in rsp
.get("vnfd-connection-point-ref").itervalues():
2453 vnf_index
= str(iface
['member-vnf-index-ref'])
2454 if_order
= int(iface
['order'])
2455 # check correct parameters
2456 if vnf_index
not in vnf_index2vnf_uuid
:
2457 raise NfvoException("Error. Invalid NS descriptor at 'nsd[{}]':'rsp[{}]':'vnfd-connection-point"
2458 "-ref':'member-vnf-index-ref':'{}'. Reference to a non-existing index at "
2459 "'nsd':'constituent-vnfd'".format(
2460 str(nsd
["id"]), str(rsp
["id"]), str(iface
["member-vnf-index-ref"])),
2461 httperrors
.Bad_Request
)
2463 existing_ifaces
= mydb
.get_rows(SELECT
=('i.uuid as uuid',),
2464 FROM
="interfaces as i join vms on i.vm_id=vms.uuid",
2465 WHERE
={'vnf_id': vnf_index2vnf_uuid
[vnf_index
],
2466 'external_name': get_str(iface
, "vnfd-connection-point-ref",
2468 if not existing_ifaces
:
2469 raise NfvoException("Error. Invalid NS descriptor at 'nsd[{}]':'rsp[{}]':'vnfd-connection-point"
2470 "-ref':'vnfd-connection-point-ref':'{}'. Reference to a non-existing "
2471 "connection-point name at VNFD '{}'".format(
2472 str(nsd
["id"]), str(rsp
["id"]), str(iface
["vnfd-connection-point-ref"]),
2473 str(iface
.get("vnfd-id-ref"))[:255]),
2474 httperrors
.Bad_Request
)
2475 interface_uuid
= existing_ifaces
[0]["uuid"]
2476 sce_rsp_hop_uuid
= str(uuid4())
2477 uuid_list
.append(sce_rsp_hop_uuid
)
2479 "uuid": sce_rsp_hop_uuid
,
2480 "if_order": if_order
,
2481 "interface_id": interface_uuid
,
2482 "sce_vnf_id": vnf_index2scevnf_uuid
[vnf_index
],
2483 "sce_rsp_id": sce_rsp_uuid
,
2485 db_sce_rsp_hops
.append(db_sce_rsp_hop
)
2487 # deal with classifiers
2488 db_sce_classifiers
= []
2489 for classifier
in vnffg
.get("classifier").itervalues():
2490 sce_classifier_uuid
= str(uuid4())
2491 uuid_list
.append(sce_classifier_uuid
)
2494 vnf_index
= str(classifier
['member-vnf-index-ref'])
2495 if vnf_index
not in vnf_index2vnf_uuid
:
2496 raise NfvoException("Error. Invalid NS descriptor at 'nsd[{}]':'classifier[{}]':'vnfd-connection-point"
2497 "-ref':'member-vnf-index-ref':'{}'. Reference to a non-existing index at "
2498 "'nsd':'constituent-vnfd'".format(
2499 str(nsd
["id"]), str(classifier
["id"]), str(classifier
["member-vnf-index-ref"])),
2500 httperrors
.Bad_Request
)
2501 existing_ifaces
= mydb
.get_rows(SELECT
=('i.uuid as uuid',),
2502 FROM
="interfaces as i join vms on i.vm_id=vms.uuid",
2503 WHERE
={'vnf_id': vnf_index2vnf_uuid
[vnf_index
],
2504 'external_name': get_str(classifier
, "vnfd-connection-point-ref",
2506 if not existing_ifaces
:
2507 raise NfvoException("Error. Invalid NS descriptor at 'nsd[{}]':'rsp[{}]':'vnfd-connection-point"
2508 "-ref':'vnfd-connection-point-ref':'{}'. Reference to a non-existing "
2509 "connection-point name at VNFD '{}'".format(
2510 str(nsd
["id"]), str(rsp
["id"]), str(iface
["vnfd-connection-point-ref"]),
2511 str(iface
.get("vnfd-id-ref"))[:255]),
2512 httperrors
.Bad_Request
)
2513 interface_uuid
= existing_ifaces
[0]["uuid"]
2515 db_sce_classifier
= {
2516 "uuid": sce_classifier_uuid
,
2517 "name": get_str(classifier
, "name", 255),
2518 "sce_vnffg_id": sce_vnffg_uuid
,
2519 "sce_vnf_id": vnf_index2scevnf_uuid
[vnf_index
],
2520 "interface_id": interface_uuid
,
2522 rsp_id
= get_str(classifier
, "rsp-id-ref", 255)
2523 rsp
= next((item
for item
in db_sce_rsps
if item
["id"] == rsp_id
), None)
2524 db_sce_classifier
["sce_rsp_id"] = rsp
["uuid"]
2525 db_sce_classifiers
.append(db_sce_classifier
)
2527 db_sce_classifier_matches
= []
2528 for match
in classifier
.get("match-attributes").itervalues():
2529 sce_classifier_match_uuid
= str(uuid4())
2530 uuid_list
.append(sce_classifier_match_uuid
)
2531 db_sce_classifier_match
= {
2532 "uuid": sce_classifier_match_uuid
,
2533 "ip_proto": get_str(match
, "ip-proto", 2),
2534 "source_ip": get_str(match
, "source-ip-address", 16),
2535 "destination_ip": get_str(match
, "destination-ip-address", 16),
2536 "source_port": get_str(match
, "source-port", 5),
2537 "destination_port": get_str(match
, "destination-port", 5),
2538 "sce_classifier_id": sce_classifier_uuid
,
2540 db_sce_classifier_matches
.append(db_sce_classifier_match
)
2543 # remove unneeded id's in sce_rsps
2544 for rsp
in db_sce_rsps
:
2548 {"scenarios": db_scenarios
},
2549 {"sce_nets": db_sce_nets
},
2550 {"ip_profiles": db_ip_profiles
},
2551 {"sce_vnfs": db_sce_vnfs
},
2552 {"sce_interfaces": db_sce_interfaces
},
2553 {"sce_vnffgs": db_sce_vnffgs
},
2554 {"sce_rsps": db_sce_rsps
},
2555 {"sce_rsp_hops": db_sce_rsp_hops
},
2556 {"sce_classifiers": db_sce_classifiers
},
2557 {"sce_classifier_matches": db_sce_classifier_matches
},
2560 logger
.debug("new_nsd_v3 done: %s",
2561 yaml
.safe_dump(db_tables
, indent
=4, default_flow_style
=False) )
2562 mydb
.new_rows(db_tables
, uuid_list
)
2563 return nsd_uuid_list
2564 except NfvoException
:
2566 except Exception as e
:
2567 logger
.error("Exception {}".format(e
))
2568 raise # NfvoException("Exception {}".format(e), httperrors.Bad_Request)
2571 def edit_scenario(mydb
, tenant_id
, scenario_id
, data
):
2572 data
["uuid"] = scenario_id
2573 data
["tenant_id"] = tenant_id
2574 c
= mydb
.edit_scenario( data
)
2578 @deprecated("Use create_instance")
2579 def start_scenario(mydb
, tenant_id
, scenario_id
, instance_scenario_name
, instance_scenario_description
, datacenter
=None,vim_tenant
=None, startvms
=True):
2580 #print "Checking that nfvo_tenant_id exists and getting the VIM URI and the VIM tenant_id"
2581 datacenter_id
, myvim
= get_datacenter_by_name_uuid(mydb
, tenant_id
, datacenter
, vim_tenant
=vim_tenant
)
2582 vims
= {datacenter_id
: myvim
}
2583 myvim_tenant
= myvim
['tenant_id']
2584 datacenter_name
= myvim
['name']
2588 #print "Checking that the scenario_id exists and getting the scenario dictionary"
2589 scenarioDict
= mydb
.get_scenario(scenario_id
, tenant_id
, datacenter_id
=datacenter_id
)
2590 scenarioDict
['datacenter2tenant'] = { datacenter_id
: myvim
['config']['datacenter_tenant_id'] }
2591 scenarioDict
['datacenter_id'] = datacenter_id
2592 #print '================scenarioDict======================='
2593 #print json.dumps(scenarioDict, indent=4)
2594 #print 'BEGIN launching instance scenario "%s" based on "%s"' % (instance_scenario_name,scenarioDict['name'])
2596 logger
.debug("start_scenario Scenario %s: consisting of %d VNF(s)", scenarioDict
['name'],len(scenarioDict
['vnfs']))
2597 #print yaml.safe_dump(scenarioDict, indent=4, default_flow_style=False)
2599 auxNetDict
= {} #Auxiliar dictionary. First key:'scenario' or sce_vnf uuid. Second Key: uuid of the net/sce_net. Value: vim_net_id
2600 auxNetDict
['scenario'] = {}
2602 logger
.debug("start_scenario 1. Creating new nets (sce_nets) in the VIM")
2603 for sce_net
in scenarioDict
['nets']:
2604 #print "Net name: %s. Description: %s" % (sce_net["name"], sce_net["description"])
2606 myNetName
= "%s.%s" % (instance_scenario_name
, sce_net
['name'])
2607 myNetName
= myNetName
[0:255] #limit length
2608 myNetType
= sce_net
['type']
2610 myNetDict
["name"] = myNetName
2611 myNetDict
["type"] = myNetType
2612 myNetDict
["tenant_id"] = myvim_tenant
2613 myNetIPProfile
= sce_net
.get('ip_profile', None)
2615 #We should use the dictionary as input parameter for new_network
2617 if not sce_net
["external"]:
2618 network_id
= myvim
.new_network(myNetName
, myNetType
, myNetIPProfile
)
2619 #print "New VIM network created for scenario %s. Network id: %s" % (scenarioDict['name'],network_id)
2620 sce_net
['vim_id'] = network_id
2621 auxNetDict
['scenario'][sce_net
['uuid']] = network_id
2622 rollbackList
.append({'what':'network','where':'vim','vim_id':datacenter_id
,'uuid':network_id
})
2623 sce_net
["created"] = True
2625 if sce_net
['vim_id'] == None:
2626 error_text
= "Error, datacenter '%s' does not have external network '%s'." % (datacenter_name
, sce_net
['name'])
2627 _
, message
= rollback(mydb
, vims
, rollbackList
)
2628 logger
.error("nfvo.start_scenario: %s", error_text
)
2629 raise NfvoException(error_text
, httperrors
.Bad_Request
)
2630 logger
.debug("Using existent VIM network for scenario %s. Network id %s", scenarioDict
['name'],sce_net
['vim_id'])
2631 auxNetDict
['scenario'][sce_net
['uuid']] = sce_net
['vim_id']
2633 logger
.debug("start_scenario 2. Creating new nets (vnf internal nets) in the VIM")
2634 #For each vnf net, we create it and we add it to instanceNetlist.
2636 for sce_vnf
in scenarioDict
['vnfs']:
2637 for net
in sce_vnf
['nets']:
2638 #print "Net name: %s. Description: %s" % (net["name"], net["description"])
2640 myNetName
= "%s.%s" % (instance_scenario_name
,net
['name'])
2641 myNetName
= myNetName
[0:255] #limit length
2642 myNetType
= net
['type']
2644 myNetDict
["name"] = myNetName
2645 myNetDict
["type"] = myNetType
2646 myNetDict
["tenant_id"] = myvim_tenant
2647 myNetIPProfile
= net
.get('ip_profile', None)
2650 #We should use the dictionary as input parameter for new_network
2651 network_id
= myvim
.new_network(myNetName
, myNetType
, myNetIPProfile
)
2652 #print "VIM network id for scenario %s: %s" % (scenarioDict['name'],network_id)
2653 net
['vim_id'] = network_id
2654 if sce_vnf
['uuid'] not in auxNetDict
:
2655 auxNetDict
[sce_vnf
['uuid']] = {}
2656 auxNetDict
[sce_vnf
['uuid']][net
['uuid']] = network_id
2657 rollbackList
.append({'what':'network','where':'vim','vim_id':datacenter_id
,'uuid':network_id
})
2658 net
["created"] = True
2660 #print "auxNetDict:"
2661 #print yaml.safe_dump(auxNetDict, indent=4, default_flow_style=False)
2663 logger
.debug("start_scenario 3. Creating new vm instances in the VIM")
2664 #myvim.new_vminstance(self,vimURI,tenant_id,name,description,image_id,flavor_id,net_dict)
2666 for sce_vnf
in scenarioDict
['vnfs']:
2667 vnf_availability_zones
= []
2668 for vm
in sce_vnf
['vms']:
2669 vm_av
= vm
.get('availability_zone')
2670 if vm_av
and vm_av
not in vnf_availability_zones
:
2671 vnf_availability_zones
.append(vm_av
)
2673 # check if there is enough availability zones available at vim level.
2674 if myvims
[datacenter_id
].availability_zone
and vnf_availability_zones
:
2675 if len(vnf_availability_zones
) > len(myvims
[datacenter_id
].availability_zone
):
2676 raise NfvoException('No enough availability zones at VIM for this deployment', httperrors
.Bad_Request
)
2678 for vm
in sce_vnf
['vms']:
2681 #myVMDict['name'] = "%s-%s-%s" % (scenarioDict['name'],sce_vnf['name'], vm['name'])
2682 myVMDict
['name'] = "{}.{}.{}".format(instance_scenario_name
,sce_vnf
['name'],chr(96+i
))
2683 #myVMDict['description'] = vm['description']
2684 myVMDict
['description'] = myVMDict
['name'][0:99]
2686 myVMDict
['start'] = "no"
2687 myVMDict
['name'] = myVMDict
['name'][0:255] #limit name length
2688 #print "VM name: %s. Description: %s" % (myVMDict['name'], myVMDict['name'])
2690 #create image at vim in case it not exist
2691 image_dict
= mydb
.get_table_by_uuid_name("images", vm
['image_id'])
2692 image_id
= create_or_use_image(mydb
, vims
, image_dict
, [], True)
2693 vm
['vim_image_id'] = image_id
2695 #create flavor at vim in case it not exist
2696 flavor_dict
= mydb
.get_table_by_uuid_name("flavors", vm
['flavor_id'])
2697 if flavor_dict
['extended']!=None:
2698 flavor_dict
['extended']= yaml
.load(flavor_dict
['extended'])
2699 flavor_id
= create_or_use_flavor(mydb
, vims
, flavor_dict
, [], True)
2700 vm
['vim_flavor_id'] = flavor_id
2703 myVMDict
['imageRef'] = vm
['vim_image_id']
2704 myVMDict
['flavorRef'] = vm
['vim_flavor_id']
2705 myVMDict
['networks'] = []
2706 for iface
in vm
['interfaces']:
2708 if iface
['type']=="data":
2709 netDict
['type'] = iface
['model']
2710 elif "model" in iface
and iface
["model"]!=None:
2711 netDict
['model']=iface
['model']
2712 #TODO in future, remove this because mac_address will not be set, and the type of PV,VF is obtained from iterface table model
2713 #discover type of interface looking at flavor
2714 for numa
in flavor_dict
.get('extended',{}).get('numas',[]):
2715 for flavor_iface
in numa
.get('interfaces',[]):
2716 if flavor_iface
.get('name') == iface
['internal_name']:
2717 if flavor_iface
['dedicated'] == 'yes':
2718 netDict
['type']="PF" #passthrough
2719 elif flavor_iface
['dedicated'] == 'no':
2720 netDict
['type']="VF" #siov
2721 elif flavor_iface
['dedicated'] == 'yes:sriov':
2722 netDict
['type']="VFnotShared" #sriov but only one sriov on the PF
2723 netDict
["mac_address"] = flavor_iface
.get("mac_address")
2725 netDict
["use"]=iface
['type']
2726 if netDict
["use"]=="data" and not netDict
.get("type"):
2727 #print "netDict", netDict
2728 #print "iface", iface
2729 e_text
= "Cannot determine the interface type PF or VF of VNF '%s' VM '%s' iface '%s'" %(sce_vnf
['name'], vm
['name'], iface
['internal_name'])
2730 if flavor_dict
.get('extended')==None:
2731 raise NfvoException(e_text
+ "After database migration some information is not available. \
2732 Try to delete and create the scenarios and VNFs again", httperrors
.Conflict
)
2734 raise NfvoException(e_text
, httperrors
.Internal_Server_Error
)
2735 if netDict
["use"]=="mgmt" or netDict
["use"]=="bridge":
2736 netDict
["type"]="virtual"
2737 if "vpci" in iface
and iface
["vpci"] is not None:
2738 netDict
['vpci'] = iface
['vpci']
2739 if "mac" in iface
and iface
["mac"] is not None:
2740 netDict
['mac_address'] = iface
['mac']
2741 if "port-security" in iface
and iface
["port-security"] is not None:
2742 netDict
['port_security'] = iface
['port-security']
2743 if "floating-ip" in iface
and iface
["floating-ip"] is not None:
2744 netDict
['floating_ip'] = iface
['floating-ip']
2745 netDict
['name'] = iface
['internal_name']
2746 if iface
['net_id'] is None:
2747 for vnf_iface
in sce_vnf
["interfaces"]:
2750 if vnf_iface
['interface_id']==iface
['uuid']:
2751 netDict
['net_id'] = auxNetDict
['scenario'][ vnf_iface
['sce_net_id'] ]
2754 netDict
['net_id'] = auxNetDict
[ sce_vnf
['uuid'] ][ iface
['net_id'] ]
2755 #skip bridge ifaces not connected to any net
2756 #if 'net_id' not in netDict or netDict['net_id']==None:
2758 myVMDict
['networks'].append(netDict
)
2759 #print ">>>>>>>>>>>>>>>>>>>>>>>>>>>"
2760 #print myVMDict['name']
2761 #print "networks", yaml.safe_dump(myVMDict['networks'], indent=4, default_flow_style=False)
2762 #print "interfaces", yaml.safe_dump(vm['interfaces'], indent=4, default_flow_style=False)
2763 #print ">>>>>>>>>>>>>>>>>>>>>>>>>>>"
2765 if 'availability_zone' in myVMDict
:
2766 av_index
= vnf_availability_zones
.index(myVMDict
['availability_zone'])
2770 vm_id
, _
= myvim
.new_vminstance(myVMDict
['name'], myVMDict
['description'], myVMDict
.get('start', None),
2771 myVMDict
['imageRef'], myVMDict
['flavorRef'], myVMDict
['networks'],
2772 availability_zone_index
=av_index
,
2773 availability_zone_list
=vnf_availability_zones
)
2774 #print "VIM vm instance id (server id) for scenario %s: %s" % (scenarioDict['name'],vm_id)
2775 vm
['vim_id'] = vm_id
2776 rollbackList
.append({'what':'vm','where':'vim','vim_id':datacenter_id
,'uuid':vm_id
})
2777 #put interface uuid back to scenario[vnfs][vms[[interfaces]
2778 for net
in myVMDict
['networks']:
2780 for iface
in vm
['interfaces']:
2781 if net
["name"]==iface
["internal_name"]:
2782 iface
["vim_id"]=net
["vim_id"]
2785 logger
.debug("start scenario Deployment done")
2786 #print yaml.safe_dump(scenarioDict, indent=4, default_flow_style=False)
2787 #r,c = mydb.new_instance_scenario_as_a_whole(nfvo_tenant,scenarioDict['name'],scenarioDict)
2788 instance_id
= mydb
.new_instance_scenario_as_a_whole(tenant_id
,instance_scenario_name
, instance_scenario_description
, scenarioDict
)
2789 return mydb
.get_instance_scenario(instance_id
)
2791 except (db_base_Exception
, vimconn
.vimconnException
) as e
:
2792 _
, message
= rollback(mydb
, vims
, rollbackList
)
2793 if isinstance(e
, db_base_Exception
):
2794 error_text
= "Exception at database"
2796 error_text
= "Exception at VIM"
2797 error_text
+= " {} {}. {}".format(type(e
).__name
__, str(e
), message
)
2798 #logger.error("start_scenario %s", error_text)
2799 raise NfvoException(error_text
, e
.http_code
)
2801 def unify_cloud_config(cloud_config_preserve
, cloud_config
):
2802 """ join the cloud config information into cloud_config_preserve.
2803 In case of conflict cloud_config_preserve preserves
2806 if not cloud_config_preserve
and not cloud_config
:
2809 new_cloud_config
= {"key-pairs":[], "users":[]}
2811 if cloud_config_preserve
:
2812 for key
in cloud_config_preserve
.get("key-pairs", () ):
2813 if key
not in new_cloud_config
["key-pairs"]:
2814 new_cloud_config
["key-pairs"].append(key
)
2816 for key
in cloud_config
.get("key-pairs", () ):
2817 if key
not in new_cloud_config
["key-pairs"]:
2818 new_cloud_config
["key-pairs"].append(key
)
2819 if not new_cloud_config
["key-pairs"]:
2820 del new_cloud_config
["key-pairs"]
2824 new_cloud_config
["users"] += cloud_config
.get("users", () )
2825 if cloud_config_preserve
:
2826 new_cloud_config
["users"] += cloud_config_preserve
.get("users", () )
2827 index_to_delete
= []
2828 users
= new_cloud_config
.get("users", [])
2829 for index0
in range(0,len(users
)):
2830 if index0
in index_to_delete
:
2832 for index1
in range(index0
+1,len(users
)):
2833 if index1
in index_to_delete
:
2835 if users
[index0
]["name"] == users
[index1
]["name"]:
2836 index_to_delete
.append(index1
)
2837 for key
in users
[index1
].get("key-pairs",()):
2838 if "key-pairs" not in users
[index0
]:
2839 users
[index0
]["key-pairs"] = [key
]
2840 elif key
not in users
[index0
]["key-pairs"]:
2841 users
[index0
]["key-pairs"].append(key
)
2842 index_to_delete
.sort(reverse
=True)
2843 for index
in index_to_delete
:
2845 if not new_cloud_config
["users"]:
2846 del new_cloud_config
["users"]
2849 if cloud_config
and cloud_config
.get("boot-data-drive") != None:
2850 new_cloud_config
["boot-data-drive"] = cloud_config
["boot-data-drive"]
2851 if cloud_config_preserve
and cloud_config_preserve
.get("boot-data-drive") != None:
2852 new_cloud_config
["boot-data-drive"] = cloud_config_preserve
["boot-data-drive"]
2855 new_cloud_config
["user-data"] = []
2856 if cloud_config
and cloud_config
.get("user-data"):
2857 if isinstance(cloud_config
["user-data"], list):
2858 new_cloud_config
["user-data"] += cloud_config
["user-data"]
2860 new_cloud_config
["user-data"].append(cloud_config
["user-data"])
2861 if cloud_config_preserve
and cloud_config_preserve
.get("user-data"):
2862 if isinstance(cloud_config_preserve
["user-data"], list):
2863 new_cloud_config
["user-data"] += cloud_config_preserve
["user-data"]
2865 new_cloud_config
["user-data"].append(cloud_config_preserve
["user-data"])
2866 if not new_cloud_config
["user-data"]:
2867 del new_cloud_config
["user-data"]
2870 new_cloud_config
["config-files"] = []
2871 if cloud_config
and cloud_config
.get("config-files") != None:
2872 new_cloud_config
["config-files"] += cloud_config
["config-files"]
2873 if cloud_config_preserve
:
2874 for file in cloud_config_preserve
.get("config-files", ()):
2875 for index
in range(0, len(new_cloud_config
["config-files"])):
2876 if new_cloud_config
["config-files"][index
]["dest"] == file["dest"]:
2877 new_cloud_config
["config-files"][index
] = file
2880 new_cloud_config
["config-files"].append(file)
2881 if not new_cloud_config
["config-files"]:
2882 del new_cloud_config
["config-files"]
2883 return new_cloud_config
2886 def get_vim_thread(mydb
, tenant_id
, datacenter_id_name
=None, datacenter_tenant_id
=None):
2887 datacenter_id
= None
2888 datacenter_name
= None
2891 if datacenter_tenant_id
:
2892 thread_id
= datacenter_tenant_id
2893 thread
= vim_threads
["running"].get(datacenter_tenant_id
)
2895 where_
={"td.nfvo_tenant_id": tenant_id
}
2896 if datacenter_id_name
:
2897 if utils
.check_valid_uuid(datacenter_id_name
):
2898 datacenter_id
= datacenter_id_name
2899 where_
["dt.datacenter_id"] = datacenter_id
2901 datacenter_name
= datacenter_id_name
2902 where_
["d.name"] = datacenter_name
2903 if datacenter_tenant_id
:
2904 where_
["dt.uuid"] = datacenter_tenant_id
2905 datacenters
= mydb
.get_rows(
2906 SELECT
=("dt.uuid as datacenter_tenant_id",),
2907 FROM
="datacenter_tenants as dt join tenants_datacenters as td on dt.uuid=td.datacenter_tenant_id "
2908 "join datacenters as d on d.uuid=dt.datacenter_id",
2910 if len(datacenters
) > 1:
2911 raise NfvoException("More than one datacenters found, try to identify with uuid", httperrors
.Conflict
)
2913 thread_id
= datacenters
[0]["datacenter_tenant_id"]
2914 thread
= vim_threads
["running"].get(thread_id
)
2916 raise NfvoException("datacenter '{}' not found".format(str(datacenter_id_name
)), httperrors
.Not_Found
)
2917 return thread_id
, thread
2918 except db_base_Exception
as e
:
2919 raise NfvoException("{} {}".format(type(e
).__name
__ , str(e
)), e
.http_code
)
2922 def get_datacenter_uuid(mydb
, tenant_id
, datacenter_id_name
):
2924 if utils
.check_valid_uuid(datacenter_id_name
):
2925 WHERE_dict
['d.uuid'] = datacenter_id_name
2927 WHERE_dict
['d.name'] = datacenter_id_name
2930 WHERE_dict
['nfvo_tenant_id'] = tenant_id
2931 from_
= "tenants_datacenters as td join datacenters as d on td.datacenter_id=d.uuid join datacenter_tenants as" \
2932 " dt on td.datacenter_tenant_id=dt.uuid"
2934 from_
= 'datacenters as d'
2935 vimaccounts
= mydb
.get_rows(FROM
=from_
, SELECT
=("d.uuid as uuid, d.name as name",), WHERE
=WHERE_dict
)
2936 if len(vimaccounts
) == 0:
2937 raise NfvoException("datacenter '{}' not found".format(str(datacenter_id_name
)), httperrors
.Not_Found
)
2938 elif len(vimaccounts
)>1:
2939 #print "nfvo.datacenter_action() error. Several datacenters found"
2940 raise NfvoException("More than one datacenters found, try to identify with uuid", httperrors
.Conflict
)
2941 return vimaccounts
[0]["uuid"], vimaccounts
[0]["name"]
2944 def get_datacenter_by_name_uuid(mydb
, tenant_id
, datacenter_id_name
=None, **extra_filter
):
2945 datacenter_id
= None
2946 datacenter_name
= None
2947 if datacenter_id_name
:
2948 if utils
.check_valid_uuid(datacenter_id_name
):
2949 datacenter_id
= datacenter_id_name
2951 datacenter_name
= datacenter_id_name
2952 vims
= get_vim(mydb
, tenant_id
, datacenter_id
, datacenter_name
, **extra_filter
)
2954 raise NfvoException("datacenter '{}' not found".format(str(datacenter_id_name
)), httperrors
.Not_Found
)
2956 #print "nfvo.datacenter_action() error. Several datacenters found"
2957 raise NfvoException("More than one datacenters found, try to identify with uuid", httperrors
.Conflict
)
2958 return vims
.keys()[0], vims
.values()[0]
2962 '''Takes dict d and updates it with the values in dict u.'''
2963 '''It merges all depth levels'''
2964 for k
, v
in u
.iteritems():
2965 if isinstance(v
, collections
.Mapping
):
2966 r
= update(d
.get(k
, {}), v
)
2973 def create_instance(mydb
, tenant_id
, instance_dict
):
2974 # print "Checking that nfvo_tenant_id exists and getting the VIM URI and the VIM tenant_id"
2975 # logger.debug("Creating instance...")
2976 scenario
= instance_dict
["scenario"]
2978 # find main datacenter
2980 myvim_threads_id
= {}
2981 datacenter
= instance_dict
.get("datacenter")
2982 default_datacenter_id
, vim
= get_datacenter_by_name_uuid(mydb
, tenant_id
, datacenter
)
2983 myvims
[default_datacenter_id
] = vim
2984 myvim_threads_id
[default_datacenter_id
], _
= get_vim_thread(mydb
, tenant_id
, default_datacenter_id
)
2985 tenant
= mydb
.get_rows_by_id('nfvo_tenants', tenant_id
)
2986 # myvim_tenant = myvim['tenant_id']
2989 # print "Checking that the scenario exists and getting the scenario dictionary"
2990 if isinstance(scenario
, str):
2991 scenarioDict
= mydb
.get_scenario(scenario
, tenant_id
, datacenter_vim_id
=myvim_threads_id
[default_datacenter_id
],
2992 datacenter_id
=default_datacenter_id
)
2994 scenarioDict
= scenario
2995 scenarioDict
["uuid"] = None
2997 # logger.debug(">>>>>> Dictionaries before merging")
2998 # logger.debug(">>>>>> InstanceDict:\n{}".format(yaml.safe_dump(instance_dict,default_flow_style=False, width=256)))
2999 # logger.debug(">>>>>> ScenarioDict:\n{}".format(yaml.safe_dump(scenarioDict,default_flow_style=False, width=256)))
3001 db_instance_vnfs
= []
3002 db_instance_vms
= []
3003 db_instance_interfaces
= []
3004 db_instance_sfis
= []
3005 db_instance_sfs
= []
3006 db_instance_classifications
= []
3007 db_instance_sfps
= []
3012 instance_name
= instance_dict
["name"]
3013 instance_uuid
= str(uuid4())
3014 uuid_list
.append(instance_uuid
)
3015 db_instance_scenario
= {
3016 "uuid": instance_uuid
,
3017 "name": instance_name
,
3018 "tenant_id": tenant_id
,
3019 "scenario_id": scenarioDict
['uuid'],
3020 "datacenter_id": default_datacenter_id
,
3021 # filled bellow 'datacenter_tenant_id'
3022 "description": instance_dict
.get("description"),
3024 if scenarioDict
.get("cloud-config"):
3025 db_instance_scenario
["cloud_config"] = yaml
.safe_dump(scenarioDict
["cloud-config"],
3026 default_flow_style
=True, width
=256)
3027 instance_action_id
= get_task_id()
3028 db_instance_action
= {
3029 "uuid": instance_action_id
, # same uuid for the instance and the action on create
3030 "tenant_id": tenant_id
,
3031 "instance_id": instance_uuid
,
3032 "description": "CREATE",
3035 # Auxiliary dictionaries from x to y
3036 sce_net2instance
= {}
3037 net2task_id
= {'scenario': {}}
3038 # Mapping between local networks and WIMs
3041 def ip_profile_IM2RO(ip_profile_im
):
3042 # translate from input format to database format
3044 if 'subnet-address' in ip_profile_im
:
3045 ip_profile_ro
['subnet_address'] = ip_profile_im
['subnet-address']
3046 if 'ip-version' in ip_profile_im
:
3047 ip_profile_ro
['ip_version'] = ip_profile_im
['ip-version']
3048 if 'gateway-address' in ip_profile_im
:
3049 ip_profile_ro
['gateway_address'] = ip_profile_im
['gateway-address']
3050 if 'dns-address' in ip_profile_im
:
3051 ip_profile_ro
['dns_address'] = ip_profile_im
['dns-address']
3052 if isinstance(ip_profile_ro
['dns_address'], (list, tuple)):
3053 ip_profile_ro
['dns_address'] = ";".join(ip_profile_ro
['dns_address'])
3054 if 'dhcp' in ip_profile_im
:
3055 ip_profile_ro
['dhcp_start_address'] = ip_profile_im
['dhcp'].get('start-address')
3056 ip_profile_ro
['dhcp_enabled'] = ip_profile_im
['dhcp'].get('enabled', True)
3057 ip_profile_ro
['dhcp_count'] = ip_profile_im
['dhcp'].get('count')
3058 return ip_profile_ro
3060 # logger.debug("Creating instance from scenario-dict:\n%s",
3061 # yaml.safe_dump(scenarioDict, indent=4, default_flow_style=False))
3063 # 0 check correct parameters
3064 for net_name
, net_instance_desc
in instance_dict
.get("networks", {}).iteritems():
3065 for scenario_net
in scenarioDict
['nets']:
3066 if net_name
== scenario_net
.get("name") or net_name
== scenario_net
.get("osm_id") or net_name
== scenario_net
.get("uuid"):
3069 raise NfvoException("Invalid scenario network name or id '{}' at instance:networks".format(net_name
),
3070 httperrors
.Bad_Request
)
3071 if "sites" not in net_instance_desc
:
3072 net_instance_desc
["sites"] = [ {} ]
3073 site_without_datacenter_field
= False
3074 for site
in net_instance_desc
["sites"]:
3075 if site
.get("datacenter"):
3076 site
["datacenter"], _
= get_datacenter_uuid(mydb
, tenant_id
, site
["datacenter"])
3077 if site
["datacenter"] not in myvims
:
3078 # Add this datacenter to myvims
3079 d
, v
= get_datacenter_by_name_uuid(mydb
, tenant_id
, site
["datacenter"])
3081 myvim_threads_id
[d
], _
= get_vim_thread(mydb
, tenant_id
, site
["datacenter"])
3082 site
["datacenter"] = d
# change name to id
3084 if site_without_datacenter_field
:
3085 raise NfvoException("Found more than one entries without datacenter field at "
3086 "instance:networks:{}:sites".format(net_name
), httperrors
.Bad_Request
)
3087 site_without_datacenter_field
= True
3088 site
["datacenter"] = default_datacenter_id
# change name to id
3090 for vnf_name
, vnf_instance_desc
in instance_dict
.get("vnfs",{}).iteritems():
3091 for scenario_vnf
in scenarioDict
['vnfs']:
3092 if vnf_name
== scenario_vnf
['member_vnf_index'] or vnf_name
== scenario_vnf
['uuid'] or vnf_name
== scenario_vnf
['name']:
3095 raise NfvoException("Invalid vnf name '{}' at instance:vnfs".format(vnf_name
), httperrors
.Bad_Request
)
3096 if "datacenter" in vnf_instance_desc
:
3097 # Add this datacenter to myvims
3098 vnf_instance_desc
["datacenter"], _
= get_datacenter_uuid(mydb
, tenant_id
, vnf_instance_desc
["datacenter"])
3099 if vnf_instance_desc
["datacenter"] not in myvims
:
3100 d
, v
= get_datacenter_by_name_uuid(mydb
, tenant_id
, vnf_instance_desc
["datacenter"])
3102 myvim_threads_id
[d
], _
= get_vim_thread(mydb
, tenant_id
, vnf_instance_desc
["datacenter"])
3103 scenario_vnf
["datacenter"] = vnf_instance_desc
["datacenter"]
3105 for net_id
, net_instance_desc
in vnf_instance_desc
.get("networks", {}).iteritems():
3106 for scenario_net
in scenario_vnf
['nets']:
3107 if net_id
== scenario_net
['osm_id'] or net_id
== scenario_net
['uuid'] or net_id
== scenario_net
["name"]:
3110 raise NfvoException("Invalid net id or name '{}' at instance:vnfs:networks".format(net_id
), httperrors
.Bad_Request
)
3111 if net_instance_desc
.get("vim-network-name"):
3112 scenario_net
["vim-network-name"] = net_instance_desc
["vim-network-name"]
3113 if net_instance_desc
.get("name"):
3114 scenario_net
["name"] = net_instance_desc
["name"]
3115 if 'ip-profile' in net_instance_desc
:
3116 ipprofile_db
= ip_profile_IM2RO(net_instance_desc
['ip-profile'])
3117 if 'ip_profile' not in scenario_net
:
3118 scenario_net
['ip_profile'] = ipprofile_db
3120 update(scenario_net
['ip_profile'], ipprofile_db
)
3122 for vdu_id
, vdu_instance_desc
in vnf_instance_desc
.get("vdus", {}).iteritems():
3123 for scenario_vm
in scenario_vnf
['vms']:
3124 if vdu_id
== scenario_vm
['osm_id'] or vdu_id
== scenario_vm
["name"]:
3127 raise NfvoException("Invalid vdu id or name '{}' at instance:vnfs:vdus".format(vdu_id
), httperrors
.Bad_Request
)
3128 scenario_vm
["instance_parameters"] = vdu_instance_desc
3129 for iface_id
, iface_instance_desc
in vdu_instance_desc
.get("interfaces", {}).iteritems():
3130 for scenario_interface
in scenario_vm
['interfaces']:
3131 if iface_id
== scenario_interface
['internal_name'] or iface_id
== scenario_interface
["external_name"]:
3132 scenario_interface
.update(iface_instance_desc
)
3135 raise NfvoException("Invalid vdu id or name '{}' at instance:vnfs:vdus".format(vdu_id
), httperrors
.Bad_Request
)
3137 # 0.1 parse cloud-config parameters
3138 cloud_config
= unify_cloud_config(instance_dict
.get("cloud-config"), scenarioDict
.get("cloud-config"))
3140 # 0.2 merge instance information into scenario
3141 # Ideally, the operation should be as simple as: update(scenarioDict,instance_dict)
3142 # However, this is not possible yet.
3143 for net_name
, net_instance_desc
in instance_dict
.get("networks", {}).iteritems():
3144 for scenario_net
in scenarioDict
['nets']:
3145 if net_name
== scenario_net
["name"]:
3146 if 'ip-profile' in net_instance_desc
:
3147 ipprofile_db
= ip_profile_IM2RO(net_instance_desc
['ip-profile'])
3148 if 'ip_profile' not in scenario_net
:
3149 scenario_net
['ip_profile'] = ipprofile_db
3151 update(scenario_net
['ip_profile'], ipprofile_db
)
3152 for interface
in net_instance_desc
.get('interfaces', ()):
3153 if 'ip_address' in interface
:
3154 for vnf
in scenarioDict
['vnfs']:
3155 if interface
['vnf'] == vnf
['name']:
3156 for vnf_interface
in vnf
['interfaces']:
3157 if interface
['vnf_interface'] == vnf_interface
['external_name']:
3158 vnf_interface
['ip_address'] = interface
['ip_address']
3160 # logger.debug(">>>>>>>> Merged dictionary")
3161 # logger.debug("Creating instance scenario-dict MERGED:\n%s",
3162 # yaml.safe_dump(scenarioDict, indent=4, default_flow_style=False))
3164 # 1. Creating new nets (sce_nets) in the VIM"
3165 number_mgmt_networks
= 0
3166 db_instance_nets
= []
3167 for sce_net
in scenarioDict
['nets']:
3168 sce_net_uuid
= sce_net
.get('uuid', sce_net
["name"])
3169 # get involved datacenters where this network need to be created
3170 involved_datacenters
= []
3171 for sce_vnf
in scenarioDict
.get("vnfs", ()):
3172 vnf_datacenter
= sce_vnf
.get("datacenter", default_datacenter_id
)
3173 if vnf_datacenter
in involved_datacenters
:
3175 if sce_vnf
.get("interfaces"):
3176 for sce_vnf_ifaces
in sce_vnf
["interfaces"]:
3177 if sce_vnf_ifaces
.get("sce_net_id") == sce_net
["uuid"]:
3178 involved_datacenters
.append(vnf_datacenter
)
3180 if not involved_datacenters
:
3181 involved_datacenters
.append(default_datacenter_id
)
3184 # TODO: use this information during network creation
3185 wim_account_id
= None
3186 if len(involved_datacenters
) > 1 and 'uuid' in sce_net
:
3187 # OBS: sce_net without uuid are used internally to VNFs
3188 # and the assumption is that VNFs will not be split among
3189 # different datacenters
3190 wim_account_id
= wim_engine
.find_suitable_wim_account(
3191 involved_datacenters
, tenant_id
)
3192 wim_usage
[sce_net
['uuid']] = wim_account_id
3196 if instance_dict
.get("networks") and instance_dict
["networks"].get(sce_net
["name"]):
3197 descriptor_net
= instance_dict
["networks"][sce_net
["name"]]
3198 net_name
= descriptor_net
.get("vim-network-name")
3199 # add datacenters from instantiation parameters
3200 if descriptor_net
.get("sites"):
3201 for site
in descriptor_net
["sites"]:
3202 if site
.get("datacenter") and site
["datacenter"] not in involved_datacenters
:
3203 involved_datacenters
.append(site
["datacenter"])
3204 sce_net2instance
[sce_net_uuid
] = {}
3205 net2task_id
['scenario'][sce_net_uuid
] = {}
3207 if sce_net
["external"]:
3208 number_mgmt_networks
+= 1
3210 for datacenter_id
in involved_datacenters
:
3212 netmap_create
= None
3213 if descriptor_net
.get("sites"):
3214 for site
in descriptor_net
["sites"]:
3215 if site
.get("datacenter") == datacenter_id
:
3216 netmap_use
= site
.get("netmap-use")
3217 netmap_create
= site
.get("netmap-create")
3220 vim
= myvims
[datacenter_id
]
3221 myvim_thread_id
= myvim_threads_id
[datacenter_id
]
3223 net_type
= sce_net
['type']
3225 lookfor_filter
= {'admin_state_up': True, 'status': 'ACTIVE'} # 'shared': True
3228 if sce_net
["external"]:
3229 net_name
= sce_net
["name"]
3231 net_name
= "{}-{}".format(instance_name
, sce_net
["name"])
3232 net_name
= net_name
[:255] # limit length
3234 if netmap_use
or netmap_create
:
3235 create_network
= False
3236 lookfor_network
= False
3238 lookfor_network
= True
3239 if utils
.check_valid_uuid(netmap_use
):
3240 lookfor_filter
["id"] = netmap_use
3242 lookfor_filter
["name"] = netmap_use
3244 create_network
= True
3245 net_vim_name
= net_name
3246 if isinstance(netmap_create
, str):
3247 net_vim_name
= netmap_create
3248 elif sce_net
.get("vim_network_name"):
3249 create_network
= False
3250 lookfor_network
= True
3251 lookfor_filter
["name"] = sce_net
.get("vim_network_name")
3252 elif sce_net
["external"]:
3253 if sce_net
['vim_id'] is not None:
3254 # there is a netmap at datacenter_nets database # TODO REVISE!!!!
3255 create_network
= False
3256 lookfor_network
= True
3257 lookfor_filter
["id"] = sce_net
['vim_id']
3258 elif vim
["config"].get("management_network_id") or vim
["config"].get("management_network_name"):
3259 if number_mgmt_networks
> 1:
3260 raise NfvoException("Found several VLD of type mgmt. "
3261 "You must concrete what vim-network must be use for each one",
3262 httperrors
.Bad_Request
)
3263 create_network
= False
3264 lookfor_network
= True
3265 if vim
["config"].get("management_network_id"):
3266 lookfor_filter
["id"] = vim
["config"]["management_network_id"]
3268 lookfor_filter
["name"] = vim
["config"]["management_network_name"]
3270 # There is not a netmap, look at datacenter for a net with this name and create if not found
3271 create_network
= True
3272 lookfor_network
= True
3273 lookfor_filter
["name"] = sce_net
["name"]
3274 net_vim_name
= sce_net
["name"]
3276 net_vim_name
= net_name
3277 create_network
= True
3278 lookfor_network
= False
3282 task_action
= "CREATE"
3283 task_extra
["params"] = (net_vim_name
, net_type
, sce_net
.get('ip_profile', None))
3285 task_extra
["find"] = (lookfor_filter
,)
3286 elif lookfor_network
:
3287 task_action
= "FIND"
3288 task_extra
["params"] = (lookfor_filter
,)
3290 # fill database content
3291 net_uuid
= str(uuid4())
3292 uuid_list
.append(net_uuid
)
3293 sce_net2instance
[sce_net_uuid
][datacenter_id
] = net_uuid
3297 "vim_name": net_vim_name
,
3298 "instance_scenario_id": instance_uuid
,
3299 "sce_net_id": sce_net
.get("uuid"),
3300 "created": create_network
,
3301 'datacenter_id': datacenter_id
,
3302 'datacenter_tenant_id': myvim_thread_id
,
3303 'status': 'BUILD' # if create_network else "ACTIVE"
3305 db_instance_nets
.append(db_net
)
3307 "instance_action_id": instance_action_id
,
3308 "status": "SCHEDULED",
3309 "task_index": task_index
,
3310 "datacenter_vim_id": myvim_thread_id
,
3311 "action": task_action
,
3312 "item": "instance_nets",
3313 "item_id": net_uuid
,
3314 "extra": yaml
.safe_dump(task_extra
, default_flow_style
=True, width
=256)
3316 net2task_id
['scenario'][sce_net_uuid
][datacenter_id
] = task_index
3318 db_vim_actions
.append(db_vim_action
)
3320 if 'ip_profile' in sce_net
:
3322 'instance_net_id': net_uuid
,
3323 'ip_version': sce_net
['ip_profile']['ip_version'],
3324 'subnet_address': sce_net
['ip_profile']['subnet_address'],
3325 'gateway_address': sce_net
['ip_profile']['gateway_address'],
3326 'dns_address': sce_net
['ip_profile']['dns_address'],
3327 'dhcp_enabled': sce_net
['ip_profile']['dhcp_enabled'],
3328 'dhcp_start_address': sce_net
['ip_profile']['dhcp_start_address'],
3329 'dhcp_count': sce_net
['ip_profile']['dhcp_count'],
3331 db_ip_profiles
.append(db_ip_profile
)
3335 "default_datacenter_id": default_datacenter_id
,
3336 "myvim_threads_id": myvim_threads_id
,
3337 "instance_uuid": instance_uuid
,
3338 "instance_name": instance_name
,
3339 "instance_action_id": instance_action_id
,
3341 "cloud_config": cloud_config
,
3342 "RO_pub_key": tenant
[0].get('RO_pub_key'),
3343 "instance_parameters": instance_dict
,
3346 "task_index": task_index
,
3347 "uuid_list": uuid_list
,
3348 "db_instance_nets": db_instance_nets
,
3349 "db_vim_actions": db_vim_actions
,
3350 "db_ip_profiles": db_ip_profiles
,
3351 "db_instance_vnfs": db_instance_vnfs
,
3352 "db_instance_vms": db_instance_vms
,
3353 "db_instance_interfaces": db_instance_interfaces
,
3354 "net2task_id": net2task_id
,
3355 "sce_net2instance": sce_net2instance
,
3357 # sce_vnf_list = sorted(scenarioDict['vnfs'], key=lambda k: k['name'])
3358 for sce_vnf
in scenarioDict
.get('vnfs', ()): # sce_vnf_list:
3359 instantiate_vnf(mydb
, sce_vnf
, vnf_params
, vnf_params_out
, rollbackList
)
3360 task_index
= vnf_params_out
["task_index"]
3361 uuid_list
= vnf_params_out
["uuid_list"]
3364 # task_depends_on = []
3365 for vnffg
in scenarioDict
.get('vnffgs', ()):
3366 for rsp
in vnffg
['rsps']:
3368 for cp
in rsp
['connection_points']:
3369 count
= mydb
.get_rows(
3370 SELECT
=('vms.count'),
3371 FROM
="vms join interfaces on vms.uuid=interfaces.vm_id join sce_rsp_hops as h on interfaces.uuid=h.interface_id",
3372 WHERE
={'h.uuid': cp
['uuid']})[0]['count']
3373 instance_vnf
= next((item
for item
in db_instance_vnfs
if item
['sce_vnf_id'] == cp
['sce_vnf_id']), None)
3374 instance_vms
= [item
for item
in db_instance_vms
if item
['instance_vnf_id'] == instance_vnf
['uuid']]
3376 for instance_vm
in instance_vms
:
3377 action
= next((item
for item
in db_vim_actions
if item
['item_id'] == instance_vm
['uuid']), None)
3379 dependencies
.append(action
['task_index'])
3380 # TODO: throw exception if count != len(instance_vms)
3381 # TODO: and action shouldn't ever be None
3383 for i
in range(count
):
3385 sfi_uuid
= str(uuid4())
3386 uuid_list
.append(sfi_uuid
)
3389 "instance_scenario_id": instance_uuid
,
3390 'sce_rsp_hop_id': cp
['uuid'],
3391 'datacenter_id': datacenter_id
,
3392 'datacenter_tenant_id': myvim_thread_id
,
3393 "vim_sfi_id": None, # vim thread will populate
3395 db_instance_sfis
.append(db_sfi
)
3397 "instance_action_id": instance_action_id
,
3398 "task_index": task_index
,
3399 "datacenter_vim_id": myvim_thread_id
,
3401 "status": "SCHEDULED",
3402 "item": "instance_sfis",
3403 "item_id": sfi_uuid
,
3404 "extra": yaml
.safe_dump({"params": "", "depends_on": [dependencies
[i
]]},
3405 default_flow_style
=True, width
=256)
3407 sfis_created
.append(task_index
)
3409 db_vim_actions
.append(db_vim_action
)
3411 sf_uuid
= str(uuid4())
3412 uuid_list
.append(sf_uuid
)
3415 "instance_scenario_id": instance_uuid
,
3416 'sce_rsp_hop_id': cp
['uuid'],
3417 'datacenter_id': datacenter_id
,
3418 'datacenter_tenant_id': myvim_thread_id
,
3419 "vim_sf_id": None, # vim thread will populate
3421 db_instance_sfs
.append(db_sf
)
3423 "instance_action_id": instance_action_id
,
3424 "task_index": task_index
,
3425 "datacenter_vim_id": myvim_thread_id
,
3427 "status": "SCHEDULED",
3428 "item": "instance_sfs",
3430 "extra": yaml
.safe_dump({"params": "", "depends_on": sfis_created
},
3431 default_flow_style
=True, width
=256)
3433 sfs_created
.append(task_index
)
3435 db_vim_actions
.append(db_vim_action
)
3436 classifier
= rsp
['classifier']
3438 # TODO the following ~13 lines can be reused for the sfi case
3439 count
= mydb
.get_rows(
3440 SELECT
=('vms.count'),
3441 FROM
="vms join interfaces on vms.uuid=interfaces.vm_id join sce_classifiers as c on interfaces.uuid=c.interface_id",
3442 WHERE
={'c.uuid': classifier
['uuid']})[0]['count']
3443 instance_vnf
= next((item
for item
in db_instance_vnfs
if item
['sce_vnf_id'] == classifier
['sce_vnf_id']), None)
3444 instance_vms
= [item
for item
in db_instance_vms
if item
['instance_vnf_id'] == instance_vnf
['uuid']]
3446 for instance_vm
in instance_vms
:
3447 action
= next((item
for item
in db_vim_actions
if item
['item_id'] == instance_vm
['uuid']), None)
3449 dependencies
.append(action
['task_index'])
3450 # TODO: throw exception if count != len(instance_vms)
3451 # TODO: and action shouldn't ever be None
3452 classifications_created
= []
3453 for i
in range(count
):
3454 for match
in classifier
['matches']:
3455 # create classifications
3456 classification_uuid
= str(uuid4())
3457 uuid_list
.append(classification_uuid
)
3458 db_classification
= {
3459 "uuid": classification_uuid
,
3460 "instance_scenario_id": instance_uuid
,
3461 'sce_classifier_match_id': match
['uuid'],
3462 'datacenter_id': datacenter_id
,
3463 'datacenter_tenant_id': myvim_thread_id
,
3464 "vim_classification_id": None, # vim thread will populate
3466 db_instance_classifications
.append(db_classification
)
3467 classification_params
= {
3468 "ip_proto": match
["ip_proto"],
3469 "source_ip": match
["source_ip"],
3470 "destination_ip": match
["destination_ip"],
3471 "source_port": match
["source_port"],
3472 "destination_port": match
["destination_port"]
3475 "instance_action_id": instance_action_id
,
3476 "task_index": task_index
,
3477 "datacenter_vim_id": myvim_thread_id
,
3479 "status": "SCHEDULED",
3480 "item": "instance_classifications",
3481 "item_id": classification_uuid
,
3482 "extra": yaml
.safe_dump({"params": classification_params
, "depends_on": [dependencies
[i
]]},
3483 default_flow_style
=True, width
=256)
3485 classifications_created
.append(task_index
)
3487 db_vim_actions
.append(db_vim_action
)
3490 sfp_uuid
= str(uuid4())
3491 uuid_list
.append(sfp_uuid
)
3494 "instance_scenario_id": instance_uuid
,
3495 'sce_rsp_id': rsp
['uuid'],
3496 'datacenter_id': datacenter_id
,
3497 'datacenter_tenant_id': myvim_thread_id
,
3498 "vim_sfp_id": None, # vim thread will populate
3500 db_instance_sfps
.append(db_sfp
)
3502 "instance_action_id": instance_action_id
,
3503 "task_index": task_index
,
3504 "datacenter_vim_id": myvim_thread_id
,
3506 "status": "SCHEDULED",
3507 "item": "instance_sfps",
3508 "item_id": sfp_uuid
,
3509 "extra": yaml
.safe_dump({"params": "", "depends_on": sfs_created
+ classifications_created
},
3510 default_flow_style
=True, width
=256)
3513 db_vim_actions
.append(db_vim_action
)
3514 db_instance_action
["number_tasks"] = task_index
3517 logger
.debug('wim_usage:\n%s\n\n', pformat(wim_usage
))
3518 wan_links
= wim_engine
.derive_wan_links(wim_usage
, db_instance_nets
, tenant_id
)
3519 wim_actions
= wim_engine
.create_actions(wan_links
)
3520 wim_actions
, db_instance_action
= (
3521 wim_engine
.incorporate_actions(wim_actions
, db_instance_action
))
3524 scenarioDict
["datacenter2tenant"] = myvim_threads_id
3526 db_instance_scenario
['datacenter_tenant_id'] = myvim_threads_id
[default_datacenter_id
]
3527 db_instance_scenario
['datacenter_id'] = default_datacenter_id
3529 {"instance_scenarios": db_instance_scenario
},
3530 {"instance_vnfs": db_instance_vnfs
},
3531 {"instance_nets": db_instance_nets
},
3532 {"ip_profiles": db_ip_profiles
},
3533 {"instance_vms": db_instance_vms
},
3534 {"instance_interfaces": db_instance_interfaces
},
3535 {"instance_actions": db_instance_action
},
3536 {"instance_sfis": db_instance_sfis
},
3537 {"instance_sfs": db_instance_sfs
},
3538 {"instance_classifications": db_instance_classifications
},
3539 {"instance_sfps": db_instance_sfps
},
3540 {"instance_wim_nets": wan_links
},
3541 {"vim_wim_actions": db_vim_actions
+ wim_actions
}
3544 logger
.debug("create_instance done DB tables: %s",
3545 yaml
.safe_dump(db_tables
, indent
=4, default_flow_style
=False) )
3546 mydb
.new_rows(db_tables
, uuid_list
)
3547 for myvim_thread_id
in myvim_threads_id
.values():
3548 vim_threads
["running"][myvim_thread_id
].insert_task(db_vim_actions
)
3550 wim_engine
.dispatch(wim_actions
)
3552 returned_instance
= mydb
.get_instance_scenario(instance_uuid
)
3553 returned_instance
["action_id"] = instance_action_id
3554 return returned_instance
3555 except (NfvoException
, vimconn
.vimconnException
, db_base_Exception
) as e
:
3556 message
= rollback(mydb
, myvims
, rollbackList
)
3557 if isinstance(e
, db_base_Exception
):
3558 error_text
= "database Exception"
3559 elif isinstance(e
, vimconn
.vimconnException
):
3560 error_text
= "VIM Exception"
3562 error_text
= "Exception"
3563 error_text
+= " {} {}. {}".format(type(e
).__name
__, str(e
), message
)
3564 # logger.error("create_instance: %s", error_text)
3566 raise NfvoException(error_text
, e
.http_code
)
3569 def instantiate_vnf(mydb
, sce_vnf
, params
, params_out
, rollbackList
):
3570 default_datacenter_id
= params
["default_datacenter_id"]
3571 myvim_threads_id
= params
["myvim_threads_id"]
3572 instance_uuid
= params
["instance_uuid"]
3573 instance_name
= params
["instance_name"]
3574 instance_action_id
= params
["instance_action_id"]
3575 myvims
= params
["myvims"]
3576 cloud_config
= params
["cloud_config"]
3577 RO_pub_key
= params
["RO_pub_key"]
3579 task_index
= params_out
["task_index"]
3580 uuid_list
= params_out
["uuid_list"]
3581 db_instance_nets
= params_out
["db_instance_nets"]
3582 db_vim_actions
= params_out
["db_vim_actions"]
3583 db_ip_profiles
= params_out
["db_ip_profiles"]
3584 db_instance_vnfs
= params_out
["db_instance_vnfs"]
3585 db_instance_vms
= params_out
["db_instance_vms"]
3586 db_instance_interfaces
= params_out
["db_instance_interfaces"]
3587 net2task_id
= params_out
["net2task_id"]
3588 sce_net2instance
= params_out
["sce_net2instance"]
3590 vnf_net2instance
= {}
3592 # 2. Creating new nets (vnf internal nets) in the VIM"
3593 # For each vnf net, we create it and we add it to instanceNetlist.
3594 if sce_vnf
.get("datacenter"):
3595 datacenter_id
= sce_vnf
["datacenter"]
3596 myvim_thread_id
= myvim_threads_id
[sce_vnf
["datacenter"]]
3598 datacenter_id
= default_datacenter_id
3599 myvim_thread_id
= myvim_threads_id
[default_datacenter_id
]
3600 for net
in sce_vnf
['nets']:
3602 # descriptor_net = instance_dict.get("vnfs", {}).get(sce_vnf["name"], {})
3603 # net_name = descriptor_net.get("name")
3606 net_name
= "{}-{}".format(instance_name
, net
["name"])
3607 net_name
= net_name
[:255] # limit length
3608 net_type
= net
['type']
3610 if sce_vnf
['uuid'] not in vnf_net2instance
:
3611 vnf_net2instance
[sce_vnf
['uuid']] = {}
3612 if sce_vnf
['uuid'] not in net2task_id
:
3613 net2task_id
[sce_vnf
['uuid']] = {}
3614 net2task_id
[sce_vnf
['uuid']][net
['uuid']] = task_index
3616 # fill database content
3617 net_uuid
= str(uuid4())
3618 uuid_list
.append(net_uuid
)
3619 vnf_net2instance
[sce_vnf
['uuid']][net
['uuid']] = net_uuid
3623 "vim_name": net_name
,
3624 "instance_scenario_id": instance_uuid
,
3625 "net_id": net
["uuid"],
3627 'datacenter_id': datacenter_id
,
3628 'datacenter_tenant_id': myvim_thread_id
,
3630 db_instance_nets
.append(db_net
)
3632 if net
.get("vim-network-name"):
3633 lookfor_filter
= {"name": net
["vim-network-name"]}
3634 task_action
= "FIND"
3635 task_extra
= {"params": (lookfor_filter
,)}
3637 task_action
= "CREATE"
3638 task_extra
= {"params": (net_name
, net_type
, net
.get('ip_profile', None))}
3641 "instance_action_id": instance_action_id
,
3642 "task_index": task_index
,
3643 "datacenter_vim_id": myvim_thread_id
,
3644 "status": "SCHEDULED",
3645 "action": task_action
,
3646 "item": "instance_nets",
3647 "item_id": net_uuid
,
3648 "extra": yaml
.safe_dump(task_extra
, default_flow_style
=True, width
=256)
3651 db_vim_actions
.append(db_vim_action
)
3653 if 'ip_profile' in net
:
3655 'instance_net_id': net_uuid
,
3656 'ip_version': net
['ip_profile']['ip_version'],
3657 'subnet_address': net
['ip_profile']['subnet_address'],
3658 'gateway_address': net
['ip_profile']['gateway_address'],
3659 'dns_address': net
['ip_profile']['dns_address'],
3660 'dhcp_enabled': net
['ip_profile']['dhcp_enabled'],
3661 'dhcp_start_address': net
['ip_profile']['dhcp_start_address'],
3662 'dhcp_count': net
['ip_profile']['dhcp_count'],
3664 db_ip_profiles
.append(db_ip_profile
)
3666 # print "vnf_net2instance:"
3667 # print yaml.safe_dump(vnf_net2instance, indent=4, default_flow_style=False)
3669 # 3. Creating new vm instances in the VIM
3670 # myvim.new_vminstance(self,vimURI,tenant_id,name,description,image_id,flavor_id,net_dict)
3672 if sce_vnf
.get('mgmt_access'):
3673 ssh_access
= sce_vnf
['mgmt_access'].get('config-access', {}).get('ssh-access')
3674 vnf_availability_zones
= []
3675 for vm
in sce_vnf
.get('vms'):
3676 vm_av
= vm
.get('availability_zone')
3677 if vm_av
and vm_av
not in vnf_availability_zones
:
3678 vnf_availability_zones
.append(vm_av
)
3680 # check if there is enough availability zones available at vim level.
3681 if myvims
[datacenter_id
].availability_zone
and vnf_availability_zones
:
3682 if len(vnf_availability_zones
) > len(myvims
[datacenter_id
].availability_zone
):
3683 raise NfvoException('No enough availability zones at VIM for this deployment', httperrors
.Bad_Request
)
3685 if sce_vnf
.get("datacenter"):
3686 vim
= myvims
[sce_vnf
["datacenter"]]
3687 myvim_thread_id
= myvim_threads_id
[sce_vnf
["datacenter"]]
3688 datacenter_id
= sce_vnf
["datacenter"]
3690 vim
= myvims
[default_datacenter_id
]
3691 myvim_thread_id
= myvim_threads_id
[default_datacenter_id
]
3692 datacenter_id
= default_datacenter_id
3693 sce_vnf
["datacenter_id"] = datacenter_id
3696 vnf_uuid
= str(uuid4())
3697 uuid_list
.append(vnf_uuid
)
3700 'instance_scenario_id': instance_uuid
,
3701 'vnf_id': sce_vnf
['vnf_id'],
3702 'sce_vnf_id': sce_vnf
['uuid'],
3703 'datacenter_id': datacenter_id
,
3704 'datacenter_tenant_id': myvim_thread_id
,
3706 db_instance_vnfs
.append(db_instance_vnf
)
3708 for vm
in sce_vnf
['vms']:
3710 if vm
.get("pdu_type"):
3714 sce_vnf_name
= sce_vnf
['member_vnf_index'] if sce_vnf
['member_vnf_index'] else sce_vnf
['name']
3715 myVMDict
['name'] = "{}-{}-{}".format(instance_name
[:64], sce_vnf_name
[:64], vm
["name"][:64])
3716 myVMDict
['description'] = myVMDict
['name'][0:99]
3718 # myVMDict['start'] = "no"
3719 if vm
.get("instance_parameters") and vm
["instance_parameters"].get("name"):
3720 myVMDict
['name'] = vm
["instance_parameters"].get("name")
3721 myVMDict
['name'] = myVMDict
['name'][0:255] # limit name length
3722 # create image at vim in case it not exist
3723 image_uuid
= vm
['image_id']
3724 if vm
.get("image_list"):
3725 for alternative_image
in vm
["image_list"]:
3726 if alternative_image
["vim_type"] == vim
["config"]["_vim_type_internal"]:
3727 image_uuid
= alternative_image
['image_id']
3729 image_dict
= mydb
.get_table_by_uuid_name("images", image_uuid
)
3730 image_id
= create_or_use_image(mydb
, {datacenter_id
: vim
}, image_dict
, [], True)
3731 vm
['vim_image_id'] = image_id
3733 # create flavor at vim in case it not exist
3734 flavor_dict
= mydb
.get_table_by_uuid_name("flavors", vm
['flavor_id'])
3735 if flavor_dict
['extended'] != None:
3736 flavor_dict
['extended'] = yaml
.load(flavor_dict
['extended'])
3737 flavor_id
= create_or_use_flavor(mydb
, {datacenter_id
: vim
}, flavor_dict
, rollbackList
, True)
3739 # Obtain information for additional disks
3740 extended_flavor_dict
= mydb
.get_rows(FROM
='datacenters_flavors', SELECT
=('extended',),
3741 WHERE
={'vim_id': flavor_id
})
3742 if not extended_flavor_dict
:
3743 raise NfvoException("flavor '{}' not found".format(flavor_id
), httperrors
.Not_Found
)
3745 # extended_flavor_dict_yaml = yaml.load(extended_flavor_dict[0])
3746 myVMDict
['disks'] = None
3747 extended_info
= extended_flavor_dict
[0]['extended']
3748 if extended_info
!= None:
3749 extended_flavor_dict_yaml
= yaml
.load(extended_info
)
3750 if 'disks' in extended_flavor_dict_yaml
:
3751 myVMDict
['disks'] = extended_flavor_dict_yaml
['disks']
3752 if vm
.get("instance_parameters") and vm
["instance_parameters"].get("devices"):
3753 for disk
in myVMDict
['disks']:
3754 if disk
.get("name") in vm
["instance_parameters"]["devices"]:
3755 disk
.update(vm
["instance_parameters"]["devices"][disk
.get("name")])
3757 vm
['vim_flavor_id'] = flavor_id
3758 myVMDict
['imageRef'] = vm
['vim_image_id']
3759 myVMDict
['flavorRef'] = vm
['vim_flavor_id']
3760 myVMDict
['availability_zone'] = vm
.get('availability_zone')
3761 myVMDict
['networks'] = []
3762 task_depends_on
= []
3763 # TODO ALF. connect_mgmt_interfaces. Connect management interfaces if this is true
3764 is_management_vm
= False
3766 for iface
in vm
['interfaces']:
3768 if iface
['type'] == "data":
3769 netDict
['type'] = iface
['model']
3770 elif "model" in iface
and iface
["model"] != None:
3771 netDict
['model'] = iface
['model']
3772 # TODO in future, remove this because mac_address will not be set, and the type of PV,VF
3773 # is obtained from iterface table model
3774 # discover type of interface looking at flavor
3775 for numa
in flavor_dict
.get('extended', {}).get('numas', []):
3776 for flavor_iface
in numa
.get('interfaces', []):
3777 if flavor_iface
.get('name') == iface
['internal_name']:
3778 if flavor_iface
['dedicated'] == 'yes':
3779 netDict
['type'] = "PF" # passthrough
3780 elif flavor_iface
['dedicated'] == 'no':
3781 netDict
['type'] = "VF" # siov
3782 elif flavor_iface
['dedicated'] == 'yes:sriov':
3783 netDict
['type'] = "VFnotShared" # sriov but only one sriov on the PF
3784 netDict
["mac_address"] = flavor_iface
.get("mac_address")
3786 netDict
["use"] = iface
['type']
3787 if netDict
["use"] == "data" and not netDict
.get("type"):
3788 # print "netDict", netDict
3789 # print "iface", iface
3790 e_text
= "Cannot determine the interface type PF or VF of VNF '{}' VM '{}' iface '{}'".fromat(
3791 sce_vnf
['name'], vm
['name'], iface
['internal_name'])
3792 if flavor_dict
.get('extended') == None:
3793 raise NfvoException(e_text
+ "After database migration some information is not available. \
3794 Try to delete and create the scenarios and VNFs again", httperrors
.Conflict
)
3796 raise NfvoException(e_text
, httperrors
.Internal_Server_Error
)
3797 if netDict
["use"] == "mgmt":
3798 is_management_vm
= True
3799 netDict
["type"] = "virtual"
3800 if netDict
["use"] == "bridge":
3801 netDict
["type"] = "virtual"
3802 if iface
.get("vpci"):
3803 netDict
['vpci'] = iface
['vpci']
3804 if iface
.get("mac"):
3805 netDict
['mac_address'] = iface
['mac']
3806 if iface
.get("mac_address"):
3807 netDict
['mac_address'] = iface
['mac_address']
3808 if iface
.get("ip_address"):
3809 netDict
['ip_address'] = iface
['ip_address']
3810 if iface
.get("port-security") is not None:
3811 netDict
['port_security'] = iface
['port-security']
3812 if iface
.get("floating-ip") is not None:
3813 netDict
['floating_ip'] = iface
['floating-ip']
3814 netDict
['name'] = iface
['internal_name']
3815 if iface
['net_id'] is None:
3816 for vnf_iface
in sce_vnf
["interfaces"]:
3819 if vnf_iface
['interface_id'] == iface
['uuid']:
3820 netDict
['net_id'] = "TASK-{}".format(
3821 net2task_id
['scenario'][vnf_iface
['sce_net_id']][datacenter_id
])
3822 instance_net_id
= sce_net2instance
[vnf_iface
['sce_net_id']][datacenter_id
]
3823 task_depends_on
.append(net2task_id
['scenario'][vnf_iface
['sce_net_id']][datacenter_id
])
3826 netDict
['net_id'] = "TASK-{}".format(net2task_id
[sce_vnf
['uuid']][iface
['net_id']])
3827 instance_net_id
= vnf_net2instance
[sce_vnf
['uuid']][iface
['net_id']]
3828 task_depends_on
.append(net2task_id
[sce_vnf
['uuid']][iface
['net_id']])
3829 # skip bridge ifaces not connected to any net
3830 if 'net_id' not in netDict
or netDict
['net_id'] == None:
3832 myVMDict
['networks'].append(netDict
)
3835 # 'instance_vm_id': instance_vm_uuid,
3836 "instance_net_id": instance_net_id
,
3837 'interface_id': iface
['uuid'],
3838 # 'vim_interface_id': ,
3839 'type': 'external' if iface
['external_name'] is not None else 'internal',
3840 'ip_address': iface
.get('ip_address'),
3841 'mac_address': iface
.get('mac'),
3842 'floating_ip': int(iface
.get('floating-ip', False)),
3843 'port_security': int(iface
.get('port-security', True))
3845 db_vm_ifaces
.append(db_vm_iface
)
3846 # print ">>>>>>>>>>>>>>>>>>>>>>>>>>>"
3847 # print myVMDict['name']
3848 # print "networks", yaml.safe_dump(myVMDict['networks'], indent=4, default_flow_style=False)
3849 # print "interfaces", yaml.safe_dump(vm['interfaces'], indent=4, default_flow_style=False)
3850 # print ">>>>>>>>>>>>>>>>>>>>>>>>>>>"
3852 # We add the RO key to cloud_config if vnf will need ssh access
3853 cloud_config_vm
= cloud_config
3854 if is_management_vm
and params
["instance_parameters"].get("mgmt_keys"):
3855 cloud_config_vm
= unify_cloud_config({"key-pairs": params
["instance_parameters"]["mgmt_keys"]},
3858 if vm
.get("instance_parameters") and vm
["instance_parameters"].get("mgmt_keys"):
3859 cloud_config_vm
= unify_cloud_config({"key-pairs": vm
["instance_parameters"]["mgmt_keys"]},
3861 # if ssh_access and ssh_access['required'] and ssh_access['default-user'] and tenant[0].get('RO_pub_key'):
3862 # RO_key = {"key-pairs": [tenant[0]['RO_pub_key']]}
3863 # cloud_config_vm = unify_cloud_config(cloud_config_vm, RO_key)
3864 if vm
.get("boot_data"):
3865 cloud_config_vm
= unify_cloud_config(vm
["boot_data"], cloud_config_vm
)
3867 if myVMDict
.get('availability_zone'):
3868 av_index
= vnf_availability_zones
.index(myVMDict
['availability_zone'])
3871 for vm_index
in range(0, vm
.get('count', 1)):
3872 vm_name
= myVMDict
['name'] + "-" + str(vm_index
+1)
3873 task_params
= (vm_name
, myVMDict
['description'], myVMDict
.get('start', None),
3874 myVMDict
['imageRef'], myVMDict
['flavorRef'], myVMDict
['networks'], cloud_config_vm
,
3875 myVMDict
['disks'], av_index
, vnf_availability_zones
)
3876 # put interface uuid back to scenario[vnfs][vms[[interfaces]
3877 for net
in myVMDict
['networks']:
3879 for iface
in vm
['interfaces']:
3880 if net
["name"] == iface
["internal_name"]:
3881 iface
["vim_id"] = net
["vim_id"]
3883 vm_uuid
= str(uuid4())
3884 uuid_list
.append(vm_uuid
)
3887 'instance_vnf_id': vnf_uuid
,
3888 # TODO delete "vim_vm_id": vm_id,
3889 "vm_id": vm
["uuid"],
3890 "vim_name": vm_name
,
3893 db_instance_vms
.append(db_vm
)
3896 for db_vm_iface
in db_vm_ifaces
:
3897 iface_uuid
= str(uuid4())
3898 uuid_list
.append(iface_uuid
)
3899 db_vm_iface_instance
= {
3901 "instance_vm_id": vm_uuid
3903 db_vm_iface_instance
.update(db_vm_iface
)
3904 if db_vm_iface_instance
.get("ip_address"): # increment ip_address
3905 ip
= db_vm_iface_instance
.get("ip_address")
3910 ip
= ip
[i
:] + str(int(ip
[:i
]) + 1)
3911 db_vm_iface_instance
["ip_address"] = ip
3913 db_vm_iface_instance
["ip_address"] = None
3914 db_instance_interfaces
.append(db_vm_iface_instance
)
3915 myVMDict
['networks'][iface_index
]["uuid"] = iface_uuid
3919 "instance_action_id": instance_action_id
,
3920 "task_index": task_index
,
3921 "datacenter_vim_id": myvim_thread_id
,
3923 "status": "SCHEDULED",
3924 "item": "instance_vms",
3926 "extra": yaml
.safe_dump({"params": task_params
, "depends_on": task_depends_on
},
3927 default_flow_style
=True, width
=256)
3930 db_vim_actions
.append(db_vim_action
)
3931 params_out
["task_index"] = task_index
3932 params_out
["uuid_list"] = uuid_list
3935 def delete_instance(mydb
, tenant_id
, instance_id
):
3936 # print "Checking that the instance_id exists and getting the instance dictionary"
3937 instanceDict
= mydb
.get_instance_scenario(instance_id
, tenant_id
)
3938 # print yaml.safe_dump(instanceDict, indent=4, default_flow_style=False)
3939 tenant_id
= instanceDict
["tenant_id"]
3942 # We need to retrieve the WIM Actions now, before the instance_scenario is
3943 # deleted. The reason for that is that: ON CASCADE rules will delete the
3944 # instance_wim_nets record in the database
3945 wim_actions
= wim_engine
.delete_actions(instance_scenario_id
=instance_id
)
3948 # print "Checking that nfvo_tenant_id exists and getting the VIM URI and the VIM tenant_id"
3949 # 1. Delete from Database
3950 message
= mydb
.delete_instance_scenario(instance_id
, tenant_id
)
3952 # 2. delete from VIM
3956 vimthread_affected
= {}
3957 net2vm_dependencies
= {}
3960 instance_action_id
= get_task_id()
3962 db_instance_action
= {
3963 "uuid": instance_action_id
, # same uuid for the instance and the action on create
3964 "tenant_id": tenant_id
,
3965 "instance_id": instance_id
,
3966 "description": "DELETE",
3967 # "number_tasks": 0 # filled bellow
3970 # 2.1 deleting VNFFGs
3971 for sfp
in instanceDict
.get('sfps', ()):
3972 vimthread_affected
[sfp
["datacenter_tenant_id"]] = None
3973 datacenter_key
= (sfp
["datacenter_id"], sfp
["datacenter_tenant_id"])
3974 if datacenter_key
not in myvims
:
3976 _
, myvim_thread
= get_vim_thread(mydb
, tenant_id
, sfp
["datacenter_id"], sfp
["datacenter_tenant_id"])
3977 except NfvoException
as e
:
3978 logger
.error(str(e
))
3980 myvim_threads
[datacenter_key
] = myvim_thread
3981 vims
= get_vim(mydb
, tenant_id
, datacenter_id
=sfp
["datacenter_id"],
3982 datacenter_tenant_id
=sfp
["datacenter_tenant_id"])
3984 logger
.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(sfp
["datacenter_id"], sfp
["datacenter_tenant_id"]))
3985 myvims
[datacenter_key
] = None
3987 myvims
[datacenter_key
] = vims
.values()[0]
3988 myvim
= myvims
[datacenter_key
]
3989 myvim_thread
= myvim_threads
[datacenter_key
]
3992 error_msg
+= "\n vim_sfp_id={} cannot be deleted because datacenter={} not found".format(sfp
['vim_sfp_id'], sfp
["datacenter_id"])
3994 extra
= {"params": (sfp
['vim_sfp_id'])}
3996 "instance_action_id": instance_action_id
,
3997 "task_index": task_index
,
3998 "datacenter_vim_id": sfp
["datacenter_tenant_id"],
4000 "status": "SCHEDULED",
4001 "item": "instance_sfps",
4002 "item_id": sfp
["uuid"],
4003 "extra": yaml
.safe_dump(extra
, default_flow_style
=True, width
=256)
4006 db_vim_actions
.append(db_vim_action
)
4008 for classification
in instanceDict
['classifications']:
4009 vimthread_affected
[classification
["datacenter_tenant_id"]] = None
4010 datacenter_key
= (classification
["datacenter_id"], classification
["datacenter_tenant_id"])
4011 if datacenter_key
not in myvims
:
4013 _
, myvim_thread
= get_vim_thread(mydb
, tenant_id
, classification
["datacenter_id"], classification
["datacenter_tenant_id"])
4014 except NfvoException
as e
:
4015 logger
.error(str(e
))
4017 myvim_threads
[datacenter_key
] = myvim_thread
4018 vims
= get_vim(mydb
, tenant_id
, datacenter_id
=classification
["datacenter_id"],
4019 datacenter_tenant_id
=classification
["datacenter_tenant_id"])
4021 logger
.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(classification
["datacenter_id"],
4022 classification
["datacenter_tenant_id"]))
4023 myvims
[datacenter_key
] = None
4025 myvims
[datacenter_key
] = vims
.values()[0]
4026 myvim
= myvims
[datacenter_key
]
4027 myvim_thread
= myvim_threads
[datacenter_key
]
4030 error_msg
+= "\n vim_classification_id={} cannot be deleted because datacenter={} not found".format(classification
['vim_classification_id'],
4031 classification
["datacenter_id"])
4033 depends_on
= [action
["task_index"] for action
in db_vim_actions
if action
["item"] == "instance_sfps"]
4034 extra
= {"params": (classification
['vim_classification_id']), "depends_on": depends_on
}
4036 "instance_action_id": instance_action_id
,
4037 "task_index": task_index
,
4038 "datacenter_vim_id": classification
["datacenter_tenant_id"],
4040 "status": "SCHEDULED",
4041 "item": "instance_classifications",
4042 "item_id": classification
["uuid"],
4043 "extra": yaml
.safe_dump(extra
, default_flow_style
=True, width
=256)
4046 db_vim_actions
.append(db_vim_action
)
4048 for sf
in instanceDict
.get('sfs', ()):
4049 vimthread_affected
[sf
["datacenter_tenant_id"]] = None
4050 datacenter_key
= (sf
["datacenter_id"], sf
["datacenter_tenant_id"])
4051 if datacenter_key
not in myvims
:
4053 _
, myvim_thread
= get_vim_thread(mydb
, tenant_id
, sf
["datacenter_id"], sf
["datacenter_tenant_id"])
4054 except NfvoException
as e
:
4055 logger
.error(str(e
))
4057 myvim_threads
[datacenter_key
] = myvim_thread
4058 vims
= get_vim(mydb
, tenant_id
, datacenter_id
=sf
["datacenter_id"],
4059 datacenter_tenant_id
=sf
["datacenter_tenant_id"])
4061 logger
.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(sf
["datacenter_id"], sf
["datacenter_tenant_id"]))
4062 myvims
[datacenter_key
] = None
4064 myvims
[datacenter_key
] = vims
.values()[0]
4065 myvim
= myvims
[datacenter_key
]
4066 myvim_thread
= myvim_threads
[datacenter_key
]
4069 error_msg
+= "\n vim_sf_id={} cannot be deleted because datacenter={} not found".format(sf
['vim_sf_id'], sf
["datacenter_id"])
4071 depends_on
= [action
["task_index"] for action
in db_vim_actions
if action
["item"] == "instance_sfps"]
4072 extra
= {"params": (sf
['vim_sf_id']), "depends_on": depends_on
}
4074 "instance_action_id": instance_action_id
,
4075 "task_index": task_index
,
4076 "datacenter_vim_id": sf
["datacenter_tenant_id"],
4078 "status": "SCHEDULED",
4079 "item": "instance_sfs",
4080 "item_id": sf
["uuid"],
4081 "extra": yaml
.safe_dump(extra
, default_flow_style
=True, width
=256)
4084 db_vim_actions
.append(db_vim_action
)
4086 for sfi
in instanceDict
.get('sfis', ()):
4087 vimthread_affected
[sfi
["datacenter_tenant_id"]] = None
4088 datacenter_key
= (sfi
["datacenter_id"], sfi
["datacenter_tenant_id"])
4089 if datacenter_key
not in myvims
:
4091 _
, myvim_thread
= get_vim_thread(mydb
, tenant_id
, sfi
["datacenter_id"], sfi
["datacenter_tenant_id"])
4092 except NfvoException
as e
:
4093 logger
.error(str(e
))
4095 myvim_threads
[datacenter_key
] = myvim_thread
4096 vims
= get_vim(mydb
, tenant_id
, datacenter_id
=sfi
["datacenter_id"],
4097 datacenter_tenant_id
=sfi
["datacenter_tenant_id"])
4099 logger
.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(sfi
["datacenter_id"], sfi
["datacenter_tenant_id"]))
4100 myvims
[datacenter_key
] = None
4102 myvims
[datacenter_key
] = vims
.values()[0]
4103 myvim
= myvims
[datacenter_key
]
4104 myvim_thread
= myvim_threads
[datacenter_key
]
4107 error_msg
+= "\n vim_sfi_id={} cannot be deleted because datacenter={} not found".format(sfi
['vim_sfi_id'], sfi
["datacenter_id"])
4109 depends_on
= [action
["task_index"] for action
in db_vim_actions
if action
["item"] == "instance_sfs"]
4110 extra
= {"params": (sfi
['vim_sfi_id']), "depends_on": depends_on
}
4112 "instance_action_id": instance_action_id
,
4113 "task_index": task_index
,
4114 "datacenter_vim_id": sfi
["datacenter_tenant_id"],
4116 "status": "SCHEDULED",
4117 "item": "instance_sfis",
4118 "item_id": sfi
["uuid"],
4119 "extra": yaml
.safe_dump(extra
, default_flow_style
=True, width
=256)
4122 db_vim_actions
.append(db_vim_action
)
4126 for sce_vnf
in instanceDict
.get('vnfs', ()):
4127 datacenter_key
= (sce_vnf
["datacenter_id"], sce_vnf
["datacenter_tenant_id"])
4128 vimthread_affected
[sce_vnf
["datacenter_tenant_id"]] = None
4129 if datacenter_key
not in myvims
:
4131 _
, myvim_thread
= get_vim_thread(mydb
, tenant_id
, sce_vnf
["datacenter_id"], sce_vnf
["datacenter_tenant_id"])
4132 except NfvoException
as e
:
4133 logger
.error(str(e
))
4135 myvim_threads
[datacenter_key
] = myvim_thread
4136 vims
= get_vim(mydb
, tenant_id
, datacenter_id
=sce_vnf
["datacenter_id"],
4137 datacenter_tenant_id
=sce_vnf
["datacenter_tenant_id"])
4139 logger
.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(sce_vnf
["datacenter_id"],
4140 sce_vnf
["datacenter_tenant_id"]))
4141 myvims
[datacenter_key
] = None
4143 myvims
[datacenter_key
] = vims
.values()[0]
4144 myvim
= myvims
[datacenter_key
]
4145 myvim_thread
= myvim_threads
[datacenter_key
]
4147 for vm
in sce_vnf
['vms']:
4149 error_msg
+= "\n VM id={} cannot be deleted because datacenter={} not found".format(vm
['vim_vm_id'], sce_vnf
["datacenter_id"])
4151 sfi_dependencies
= [action
["task_index"] for action
in db_vim_actions
if action
["item"] == "instance_sfis"]
4153 "instance_action_id": instance_action_id
,
4154 "task_index": task_index
,
4155 "datacenter_vim_id": sce_vnf
["datacenter_tenant_id"],
4157 "status": "SCHEDULED",
4158 "item": "instance_vms",
4159 "item_id": vm
["uuid"],
4160 "extra": yaml
.safe_dump({"params": vm
["interfaces"], "depends_on": sfi_dependencies
},
4161 default_flow_style
=True, width
=256)
4163 db_vim_actions
.append(db_vim_action
)
4164 for interface
in vm
["interfaces"]:
4165 if not interface
.get("instance_net_id"):
4167 if interface
["instance_net_id"] not in net2vm_dependencies
:
4168 net2vm_dependencies
[interface
["instance_net_id"]] = []
4169 net2vm_dependencies
[interface
["instance_net_id"]].append(task_index
)
4174 for net
in instanceDict
['nets']:
4175 vimthread_affected
[net
["datacenter_tenant_id"]] = None
4176 datacenter_key
= (net
["datacenter_id"], net
["datacenter_tenant_id"])
4177 if datacenter_key
not in myvims
:
4179 _
,myvim_thread
= get_vim_thread(mydb
, tenant_id
, net
["datacenter_id"], net
["datacenter_tenant_id"])
4180 except NfvoException
as e
:
4181 logger
.error(str(e
))
4183 myvim_threads
[datacenter_key
] = myvim_thread
4184 vims
= get_vim(mydb
, tenant_id
, datacenter_id
=net
["datacenter_id"],
4185 datacenter_tenant_id
=net
["datacenter_tenant_id"])
4187 logger
.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(net
["datacenter_id"], net
["datacenter_tenant_id"]))
4188 myvims
[datacenter_key
] = None
4190 myvims
[datacenter_key
] = vims
.values()[0]
4191 myvim
= myvims
[datacenter_key
]
4192 myvim_thread
= myvim_threads
[datacenter_key
]
4195 error_msg
+= "\n Net VIM_id={} cannot be deleted because datacenter={} not found".format(net
['vim_net_id'], net
["datacenter_id"])
4197 extra
= {"params": (net
['vim_net_id'], net
['sdn_net_id'])}
4198 if net2vm_dependencies
.get(net
["uuid"]):
4199 extra
["depends_on"] = net2vm_dependencies
[net
["uuid"]]
4200 sfi_dependencies
= [action
["task_index"] for action
in db_vim_actions
if action
["item"] == "instance_sfis"]
4201 if len(sfi_dependencies
) > 0:
4202 if "depends_on" in extra
:
4203 extra
["depends_on"] += sfi_dependencies
4205 extra
["depends_on"] = sfi_dependencies
4207 "instance_action_id": instance_action_id
,
4208 "task_index": task_index
,
4209 "datacenter_vim_id": net
["datacenter_tenant_id"],
4211 "status": "SCHEDULED",
4212 "item": "instance_nets",
4213 "item_id": net
["uuid"],
4214 "extra": yaml
.safe_dump(extra
, default_flow_style
=True, width
=256)
4217 db_vim_actions
.append(db_vim_action
)
4219 db_instance_action
["number_tasks"] = task_index
4222 wim_actions
, db_instance_action
= (
4223 wim_engine
.incorporate_actions(wim_actions
, db_instance_action
))
4227 {"instance_actions": db_instance_action
},
4228 {"vim_wim_actions": db_vim_actions
+ wim_actions
}
4231 logger
.debug("delete_instance done DB tables: %s",
4232 yaml
.safe_dump(db_tables
, indent
=4, default_flow_style
=False))
4233 mydb
.new_rows(db_tables
, ())
4234 for myvim_thread_id
in vimthread_affected
.keys():
4235 vim_threads
["running"][myvim_thread_id
].insert_task(db_vim_actions
)
4237 wim_engine
.dispatch(wim_actions
)
4239 if len(error_msg
) > 0:
4240 return 'action_id={} instance {} deleted but some elements could not be deleted, or already deleted '\
4241 '(error: 404) from VIM: {}'.format(instance_action_id
, message
, error_msg
)
4243 return "action_id={} instance {} deleted".format(instance_action_id
, message
)
4245 def get_instance_id(mydb
, tenant_id
, instance_id
):
4247 #check valid tenant_id
4248 check_tenant(mydb
, tenant_id
)
4251 instance_dict
= mydb
.get_instance_scenario(instance_id
, tenant_id
, verbose
=True)
4252 for net
in instance_dict
["nets"]:
4253 if net
.get("sdn_net_id"):
4254 net_sdn
= ovim
.show_network(net
["sdn_net_id"])
4256 "admin_state_up": net_sdn
.get("admin_state_up"),
4257 "flows": net_sdn
.get("flows"),
4258 "last_error": net_sdn
.get("last_error"),
4259 "ports": net_sdn
.get("ports"),
4260 "type": net_sdn
.get("type"),
4261 "status": net_sdn
.get("status"),
4262 "vlan": net_sdn
.get("vlan"),
4264 return instance_dict
4266 @deprecated("Instance is automatically refreshed by vim_threads")
4267 def refresh_instance(mydb
, nfvo_tenant
, instanceDict
, datacenter
=None, vim_tenant
=None):
4268 '''Refreshes a scenario instance. It modifies instanceDict'''
4270 - result: <0 if there is any unexpected error, n>=0 if no errors where n is the number of vms and nets that couldn't be updated in the database
4273 # # Assumption: nfvo_tenant and instance_id were checked before entering into this function
4274 # #print "nfvo.refresh_instance begins"
4275 # #print json.dumps(instanceDict, indent=4)
4277 # #print "Getting the VIM URL and the VIM tenant_id"
4280 # # 1. Getting VIM vm and net list
4281 # vms_updated = [] #List of VM instance uuids in openmano that were updated
4284 # for sce_vnf in instanceDict['vnfs']:
4285 # datacenter_key = (sce_vnf["datacenter_id"], sce_vnf["datacenter_tenant_id"])
4286 # if datacenter_key not in vm_list:
4287 # vm_list[datacenter_key] = []
4288 # if datacenter_key not in myvims:
4289 # vims = get_vim(mydb, nfvo_tenant, datacenter_id=sce_vnf["datacenter_id"],
4290 # datacenter_tenant_id=sce_vnf["datacenter_tenant_id"])
4291 # if len(vims) == 0:
4292 # logger.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(sce_vnf["datacenter_id"], sce_vnf["datacenter_tenant_id"]))
4293 # myvims[datacenter_key] = None
4295 # myvims[datacenter_key] = vims.values()[0]
4296 # for vm in sce_vnf['vms']:
4297 # vm_list[datacenter_key].append(vm['vim_vm_id'])
4298 # vms_notupdated.append(vm["uuid"])
4300 # nets_updated = [] #List of VM instance uuids in openmano that were updated
4301 # nets_notupdated=[]
4303 # for net in instanceDict['nets']:
4304 # datacenter_key = (net["datacenter_id"], net["datacenter_tenant_id"])
4305 # if datacenter_key not in net_list:
4306 # net_list[datacenter_key] = []
4307 # if datacenter_key not in myvims:
4308 # vims = get_vim(mydb, nfvo_tenant, datacenter_id=net["datacenter_id"],
4309 # datacenter_tenant_id=net["datacenter_tenant_id"])
4310 # if len(vims) == 0:
4311 # logger.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(net["datacenter_id"], net["datacenter_tenant_id"]))
4312 # myvims[datacenter_key] = None
4314 # myvims[datacenter_key] = vims.values()[0]
4316 # net_list[datacenter_key].append(net['vim_net_id'])
4317 # nets_notupdated.append(net["uuid"])
4319 # # 1. Getting the status of all VMs
4321 # for datacenter_key in myvims:
4322 # if not vm_list.get(datacenter_key):
4326 # if not myvims[datacenter_key]:
4327 # failed_message = "datacenter '{}' with datacenter_tenant_id '{}' not found".format(net["datacenter_id"], net["datacenter_tenant_id"])
4330 # vm_dict.update(myvims[datacenter_key].refresh_vms_status(vm_list[datacenter_key]) )
4332 # except vimconn.vimconnException as e:
4333 # logger.error("VIM exception %s %s", type(e).__name__, str(e))
4334 # failed_message = str(e)
4336 # for vm in vm_list[datacenter_key]:
4337 # vm_dict[vm] = {'status': "VIM_ERROR", 'error_msg': failed_message}
4339 # # 2. Update the status of VMs in the instanceDict, while collects the VMs whose status changed
4340 # for sce_vnf in instanceDict['vnfs']:
4341 # for vm in sce_vnf['vms']:
4342 # vm_id = vm['vim_vm_id']
4343 # interfaces = vm_dict[vm_id].pop('interfaces', [])
4344 # #2.0 look if contain manamgement interface, and if not change status from ACTIVE:NoMgmtIP to ACTIVE
4345 # has_mgmt_iface = False
4346 # for iface in vm["interfaces"]:
4347 # if iface["type"]=="mgmt":
4348 # has_mgmt_iface = True
4349 # if vm_dict[vm_id]['status'] == "ACTIVE:NoMgmtIP" and not has_mgmt_iface:
4350 # vm_dict[vm_id]['status'] = "ACTIVE"
4351 # if vm_dict[vm_id].get('error_msg') and len(vm_dict[vm_id]['error_msg']) >= 1024:
4352 # vm_dict[vm_id]['error_msg'] = vm_dict[vm_id]['error_msg'][:516] + " ... " + vm_dict[vm_id]['error_msg'][-500:]
4353 # if vm['status'] != vm_dict[vm_id]['status'] or vm.get('error_msg')!=vm_dict[vm_id].get('error_msg') or vm.get('vim_info')!=vm_dict[vm_id].get('vim_info'):
4354 # vm['status'] = vm_dict[vm_id]['status']
4355 # vm['error_msg'] = vm_dict[vm_id].get('error_msg')
4356 # vm['vim_info'] = vm_dict[vm_id].get('vim_info')
4357 # # 2.1. Update in openmano DB the VMs whose status changed
4359 # updates = mydb.update_rows('instance_vms', UPDATE=vm_dict[vm_id], WHERE={'uuid':vm["uuid"]})
4360 # vms_notupdated.remove(vm["uuid"])
4362 # vms_updated.append(vm["uuid"])
4363 # except db_base_Exception as e:
4364 # logger.error("nfvo.refresh_instance error database update: %s", str(e))
4365 # # 2.2. Update in openmano DB the interface VMs
4366 # for interface in interfaces:
4367 # #translate from vim_net_id to instance_net_id
4368 # network_id_list=[]
4369 # for net in instanceDict['nets']:
4370 # if net["vim_net_id"] == interface["vim_net_id"]:
4371 # network_id_list.append(net["uuid"])
4372 # if not network_id_list:
4374 # del interface["vim_net_id"]
4376 # for network_id in network_id_list:
4377 # mydb.update_rows('instance_interfaces', UPDATE=interface, WHERE={'instance_vm_id':vm["uuid"], "instance_net_id":network_id})
4378 # except db_base_Exception as e:
4379 # logger.error( "nfvo.refresh_instance error with vm=%s, interface_net_id=%s", vm["uuid"], network_id)
4381 # # 3. Getting the status of all nets
4383 # for datacenter_key in myvims:
4384 # if not net_list.get(datacenter_key):
4387 # failed_message = ""
4388 # if not myvims[datacenter_key]:
4389 # failed_message = "datacenter '{}' with datacenter_tenant_id '{}' not found".format(net["datacenter_id"], net["datacenter_tenant_id"])
4392 # net_dict.update(myvims[datacenter_key].refresh_nets_status(net_list[datacenter_key]) )
4394 # except vimconn.vimconnException as e:
4395 # logger.error("VIM exception %s %s", type(e).__name__, str(e))
4396 # failed_message = str(e)
4398 # for net in net_list[datacenter_key]:
4399 # net_dict[net] = {'status': "VIM_ERROR", 'error_msg': failed_message}
4401 # # 4. Update the status of nets in the instanceDict, while collects the nets whose status changed
4402 # # TODO: update nets inside a vnf
4403 # for net in instanceDict['nets']:
4404 # net_id = net['vim_net_id']
4405 # if net_dict[net_id].get('error_msg') and len(net_dict[net_id]['error_msg']) >= 1024:
4406 # net_dict[net_id]['error_msg'] = net_dict[net_id]['error_msg'][:516] + " ... " + net_dict[vm_id]['error_msg'][-500:]
4407 # if net['status'] != net_dict[net_id]['status'] or net.get('error_msg')!=net_dict[net_id].get('error_msg') or net.get('vim_info')!=net_dict[net_id].get('vim_info'):
4408 # net['status'] = net_dict[net_id]['status']
4409 # net['error_msg'] = net_dict[net_id].get('error_msg')
4410 # net['vim_info'] = net_dict[net_id].get('vim_info')
4411 # # 5.1. Update in openmano DB the nets whose status changed
4413 # updated = mydb.update_rows('instance_nets', UPDATE=net_dict[net_id], WHERE={'uuid':net["uuid"]})
4414 # nets_notupdated.remove(net["uuid"])
4416 # nets_updated.append(net["uuid"])
4417 # except db_base_Exception as e:
4418 # logger.error("nfvo.refresh_instance error database update: %s", str(e))
4420 # # Returns appropriate output
4421 # #print "nfvo.refresh_instance finishes"
4422 # logger.debug("VMs updated in the database: %s; nets updated in the database %s; VMs not updated: %s; nets not updated: %s",
4423 # str(vms_updated), str(nets_updated), str(vms_notupdated), str(nets_notupdated))
4424 instance_id
= instanceDict
['uuid']
4425 # if len(vms_notupdated)+len(nets_notupdated)>0:
4426 # error_msg = "VMs not updated: " + str(vms_notupdated) + "; nets not updated: " + str(nets_notupdated)
4427 # return len(vms_notupdated)+len(nets_notupdated), 'Scenario instance ' + instance_id + ' refreshed but some elements could not be updated in the database: ' + error_msg
4429 return 0, 'Scenario instance ' + instance_id
+ ' refreshed.'
4431 def instance_action(mydb
,nfvo_tenant
,instance_id
, action_dict
):
4432 #print "Checking that the instance_id exists and getting the instance dictionary"
4433 instanceDict
= mydb
.get_instance_scenario(instance_id
, nfvo_tenant
)
4434 #print yaml.safe_dump(instanceDict, indent=4, default_flow_style=False)
4436 #print "Checking that nfvo_tenant_id exists and getting the VIM URI and the VIM tenant_id"
4437 vims
= get_vim(mydb
, nfvo_tenant
, instanceDict
['datacenter_id'])
4439 raise NfvoException("datacenter '{}' not found".format(str(instanceDict
['datacenter_id'])), httperrors
.Not_Found
)
4440 myvim
= vims
.values()[0]
4445 myvim_threads_id
= {}
4446 if action_dict
.get("vdu-scaling"):
4447 db_instance_vms
= []
4449 db_instance_interfaces
= []
4450 instance_action_id
= get_task_id()
4451 db_instance_action
= {
4452 "uuid": instance_action_id
, # same uuid for the instance and the action on create
4453 "tenant_id": nfvo_tenant
,
4454 "instance_id": instance_id
,
4455 "description": "SCALE",
4457 vm_result
["instance_action_id"] = instance_action_id
4458 vm_result
["created"] = []
4459 vm_result
["deleted"] = []
4461 for vdu
in action_dict
["vdu-scaling"]:
4462 vdu_id
= vdu
.get("vdu-id")
4463 osm_vdu_id
= vdu
.get("osm_vdu_id")
4464 member_vnf_index
= vdu
.get("member-vnf-index")
4465 vdu_count
= vdu
.get("count", 1)
4467 target_vms
= mydb
.get_rows(
4468 FROM
="instance_vms as vms join instance_vnfs as vnfs on vms.instance_vnf_id=vnfs.uuid",
4469 WHERE
={"vms.uuid": vdu_id
},
4470 ORDER_BY
="vms.created_at"
4473 raise NfvoException("Cannot find the vdu with id {}".format(vdu_id
), httperrors
.Not_Found
)
4475 if not osm_vdu_id
and not member_vnf_index
:
4476 raise NfvoException("Invalid input vdu parameters. Must supply either 'vdu-id' of 'osm_vdu_id','member-vnf-index'")
4477 target_vms
= mydb
.get_rows(
4478 # SELECT=("ivms.uuid", "ivnfs.datacenter_id", "ivnfs.datacenter_tenant_id"),
4479 FROM
="instance_vms as ivms join instance_vnfs as ivnfs on ivms.instance_vnf_id=ivnfs.uuid"\
4480 " join sce_vnfs as svnfs on ivnfs.sce_vnf_id=svnfs.uuid"\
4481 " join vms on ivms.vm_id=vms.uuid",
4482 WHERE
={"vms.osm_id": osm_vdu_id
, "svnfs.member_vnf_index": member_vnf_index
,
4483 "ivnfs.instance_scenario_id": instance_id
},
4484 ORDER_BY
="ivms.created_at"
4487 raise NfvoException("Cannot find the vdu with osm_vdu_id {} and member-vnf-index {}".format(osm_vdu_id
, member_vnf_index
), httperrors
.Not_Found
)
4488 vdu_id
= target_vms
[-1]["uuid"]
4489 target_vm
= target_vms
[-1]
4490 datacenter
= target_vm
["datacenter_id"]
4491 myvim_threads_id
[datacenter
], _
= get_vim_thread(mydb
, nfvo_tenant
, datacenter
)
4493 if vdu
["type"] == "delete":
4494 for index
in range(0, vdu_count
):
4495 target_vm
= target_vms
[-1-index
]
4496 vdu_id
= target_vm
["uuid"]
4498 vm_interfaces
= None
4499 for sce_vnf
in instanceDict
['vnfs']:
4500 for vm
in sce_vnf
['vms']:
4501 if vm
["uuid"] == vdu_id
:
4502 vm_interfaces
= vm
["interfaces"]
4506 "instance_action_id": instance_action_id
,
4507 "task_index": task_index
,
4508 "datacenter_vim_id": target_vm
["datacenter_tenant_id"],
4510 "status": "SCHEDULED",
4511 "item": "instance_vms",
4513 "extra": yaml
.safe_dump({"params": vm_interfaces
},
4514 default_flow_style
=True, width
=256)
4517 db_vim_actions
.append(db_vim_action
)
4518 vm_result
["deleted"].append(vdu_id
)
4519 # delete from database
4520 db_instance_vms
.append({"TO-DELETE": vdu_id
})
4522 else: # vdu["type"] == "create":
4524 where
= {"item": "instance_vms", "item_id": target_vm
["uuid"], "action": "CREATE"}
4526 vim_action_to_clone
= mydb
.get_rows(FROM
="vim_actions", WHERE
=where
)
4527 if not vim_action_to_clone
:
4528 raise NfvoException("Cannot find the vim_action at database with {}".format(where
), httperrors
.Internal_Server_Error
)
4529 vim_action_to_clone
= vim_action_to_clone
[0]
4530 extra
= yaml
.safe_load(vim_action_to_clone
["extra"])
4532 # generate a new depends_on. Convert format TASK-Y into new format TASK-ACTION-XXXX.XXXX.Y
4533 # TODO do the same for flavor and image when available
4534 task_depends_on
= []
4535 task_params
= extra
["params"]
4536 task_params_networks
= deepcopy(task_params
[5])
4537 for iface
in task_params
[5]:
4538 if iface
["net_id"].startswith("TASK-"):
4539 if "." not in iface
["net_id"]:
4540 task_depends_on
.append("{}.{}".format(vim_action_to_clone
["instance_action_id"],
4541 iface
["net_id"][5:]))
4542 iface
["net_id"] = "TASK-{}.{}".format(vim_action_to_clone
["instance_action_id"],
4543 iface
["net_id"][5:])
4545 task_depends_on
.append(iface
["net_id"][5:])
4546 if "mac_address" in iface
:
4547 del iface
["mac_address"]
4549 vm_ifaces_to_clone
= mydb
.get_rows(FROM
="instance_interfaces", WHERE
={"instance_vm_id": target_vm
["uuid"]})
4550 for index
in range(0, vdu_count
):
4551 vm_uuid
= str(uuid4())
4552 vm_name
= target_vm
.get('vim_name')
4554 suffix
= vm_name
.rfind("-")
4555 vm_name
= vm_name
[:suffix
+1] + str(index
+ 1 + int(vm_name
[suffix
+1:]))
4560 'instance_vnf_id': target_vm
['instance_vnf_id'],
4561 'vm_id': target_vm
['vm_id'],
4564 db_instance_vms
.append(db_instance_vm
)
4566 for vm_iface
in vm_ifaces_to_clone
:
4567 iface_uuid
= str(uuid4())
4568 iface2iface
[vm_iface
["uuid"]] = iface_uuid
4571 'instance_vm_id': vm_uuid
,
4572 "instance_net_id": vm_iface
["instance_net_id"],
4573 'interface_id': vm_iface
['interface_id'],
4574 'type': vm_iface
['type'],
4575 'floating_ip': vm_iface
['floating_ip'],
4576 'port_security': vm_iface
['port_security']
4578 db_instance_interfaces
.append(db_vm_iface
)
4579 task_params_copy
= deepcopy(task_params
)
4580 for iface
in task_params_copy
[5]:
4581 iface
["uuid"] = iface2iface
[iface
["uuid"]]
4582 # increment ip_address
4583 if "ip_address" in iface
:
4584 ip
= iface
.get("ip_address")
4589 ip
= ip
[i
:] + str(int(ip
[:i
]) + 1)
4590 iface
["ip_address"] = ip
4592 iface
["ip_address"] = None
4594 task_params_copy
[0] = vm_name
4596 "instance_action_id": instance_action_id
,
4597 "task_index": task_index
,
4598 "datacenter_vim_id": vim_action_to_clone
["datacenter_vim_id"],
4600 "status": "SCHEDULED",
4601 "item": "instance_vms",
4605 # TODO examinar parametros, quitar MAC o incrementar. Incrementar IP y colocar las dependencias con ACTION-asdfasd.
4608 "extra": yaml
.safe_dump({"params": task_params_copy
, "depends_on": task_depends_on
}, default_flow_style
=True, width
=256)
4611 db_vim_actions
.append(db_vim_action
)
4612 vm_result
["created"].append(vm_uuid
)
4614 db_instance_action
["number_tasks"] = task_index
4616 {"instance_vms": db_instance_vms
},
4617 {"instance_interfaces": db_instance_interfaces
},
4618 {"instance_actions": db_instance_action
},
4620 # {"instance_sfis": db_instance_sfis},
4621 # {"instance_sfs": db_instance_sfs},
4622 # {"instance_classifications": db_instance_classifications},
4623 # {"instance_sfps": db_instance_sfps},
4624 {"vim_actions": db_vim_actions
}
4626 logger
.debug("create_vdu done DB tables: %s",
4627 yaml
.safe_dump(db_tables
, indent
=4, default_flow_style
=False))
4628 mydb
.new_rows(db_tables
, [])
4629 for myvim_thread
in myvim_threads_id
.values():
4630 vim_threads
["running"][myvim_thread
].insert_task(db_vim_actions
)
4634 input_vnfs
= action_dict
.pop("vnfs", [])
4635 input_vms
= action_dict
.pop("vms", [])
4636 action_over_all
= True if not input_vnfs
and not input_vms
else False
4637 for sce_vnf
in instanceDict
['vnfs']:
4638 for vm
in sce_vnf
['vms']:
4639 if not action_over_all
and sce_vnf
['uuid'] not in input_vnfs
and sce_vnf
['vnf_name'] not in input_vnfs
and \
4640 sce_vnf
['member_vnf_index'] not in input_vnfs
and \
4641 vm
['uuid'] not in input_vms
and vm
['name'] not in input_vms
:
4644 if "add_public_key" in action_dict
:
4646 if sce_vnf
.get('mgmt_access'):
4647 mgmt_access
= yaml
.load(sce_vnf
['mgmt_access'])
4648 ssh_access
= mgmt_access
['config-access']['ssh-access']
4649 tenant
= mydb
.get_rows_by_id('nfvo_tenants', nfvo_tenant
)
4651 if ssh_access
['required'] and ssh_access
['default-user']:
4652 if 'ip_address' in vm
:
4653 mgmt_ip
= vm
['ip_address'].split(';')
4654 password
= mgmt_access
['config-access'].get('password')
4655 priv_RO_key
= decrypt_key(tenant
[0]['encrypted_RO_priv_key'], tenant
[0]['uuid'])
4656 myvim
.inject_user_key(mgmt_ip
[0], ssh_access
['default-user'],
4657 action_dict
['add_public_key'],
4658 password
=password
, ro_key
=priv_RO_key
)
4660 raise NfvoException("Unable to inject ssh key in vm: {} - Aborting".format(vm
['uuid']),
4661 httperrors
.Internal_Server_Error
)
4663 raise NfvoException("Unable to inject ssh key in vm: {} - Aborting".format(vm
['uuid']),
4664 httperrors
.Internal_Server_Error
)
4666 raise NfvoException("Unable to inject ssh key in vm: {} - Aborting".format(vm
['uuid']),
4667 httperrors
.Internal_Server_Error
)
4669 data
= myvim
.action_vminstance(vm
['vim_vm_id'], action_dict
)
4670 if "console" in action_dict
:
4671 if not global_config
["http_console_proxy"]:
4672 vm_result
[ vm
['uuid'] ] = {"vim_result": 200,
4673 "description": "{protocol}//{ip}:{port}/{suffix}".format(
4674 protocol
=data
["protocol"],
4675 ip
= data
["server"],
4676 port
= data
["port"],
4677 suffix
= data
["suffix"]),
4681 elif data
["server"]=="127.0.0.1" or data
["server"]=="localhost":
4682 vm_result
[ vm
['uuid'] ] = {"vim_result": -httperrors
.Unauthorized
,
4683 "description": "this console is only reachable by local interface",
4688 #print "console data", data
4690 console_thread
= create_or_use_console_proxy_thread(data
["server"], data
["port"])
4691 vm_result
[ vm
['uuid'] ] = {"vim_result": 200,
4692 "description": "{protocol}//{ip}:{port}/{suffix}".format(
4693 protocol
=data
["protocol"],
4694 ip
= global_config
["http_console_host"],
4695 port
= console_thread
.port
,
4696 suffix
= data
["suffix"]),
4700 except NfvoException
as e
:
4701 vm_result
[ vm
['uuid'] ] = {"vim_result": e
.http_code
, "name":vm
['name'], "description": str(e
)}
4705 vm_result
[ vm
['uuid'] ] = {"vim_result": 200, "description": "ok", "name":vm
['name']}
4707 except vimconn
.vimconnException
as e
:
4708 vm_result
[ vm
['uuid'] ] = {"vim_result": e
.http_code
, "name":vm
['name'], "description": str(e
)}
4711 if vm_ok
==0: #all goes wrong
4716 def instance_action_get(mydb
, nfvo_tenant
, instance_id
, action_id
):
4718 if nfvo_tenant
and nfvo_tenant
!= "any":
4719 filter["tenant_id"] = nfvo_tenant
4720 if instance_id
and instance_id
!= "any":
4721 filter["instance_id"] = instance_id
4723 filter["uuid"] = action_id
4724 rows
= mydb
.get_rows(FROM
="instance_actions", WHERE
=filter)
4727 raise NfvoException("Not found any action with this criteria", httperrors
.Not_Found
)
4728 vim_wim_actions
= mydb
.get_rows(FROM
="vim_wim_actions", WHERE
={"instance_action_id": action_id
})
4729 rows
[0]["vim_wim_actions"] = vim_wim_actions
4730 # for backward compatibility set vim_actions = vim_wim_actions
4731 rows
[0]["vim_actions"] = vim_wim_actions
4732 return {"actions": rows
}
4735 def create_or_use_console_proxy_thread(console_server
, console_port
):
4736 #look for a non-used port
4737 console_thread_key
= console_server
+ ":" + str(console_port
)
4738 if console_thread_key
in global_config
["console_thread"]:
4739 #global_config["console_thread"][console_thread_key].start_timeout()
4740 return global_config
["console_thread"][console_thread_key
]
4742 for port
in global_config
["console_port_iterator"]():
4743 #print "create_or_use_console_proxy_thread() port:", port
4744 if port
in global_config
["console_ports"]:
4747 clithread
= cli
.ConsoleProxyThread(global_config
['http_host'], port
, console_server
, console_port
)
4749 global_config
["console_thread"][console_thread_key
] = clithread
4750 global_config
["console_ports"][port
] = console_thread_key
4752 except cli
.ConsoleProxyExceptionPortUsed
as e
:
4753 #port used, try with onoher
4755 except cli
.ConsoleProxyException
as e
:
4756 raise NfvoException(str(e
), httperrors
.Bad_Request
)
4757 raise NfvoException("Not found any free 'http_console_ports'", httperrors
.Conflict
)
4760 def check_tenant(mydb
, tenant_id
):
4761 '''check that tenant exists at database'''
4762 tenant
= mydb
.get_rows(FROM
='nfvo_tenants', SELECT
=('uuid',), WHERE
={'uuid': tenant_id
})
4764 raise NfvoException("tenant '{}' not found".format(tenant_id
), httperrors
.Not_Found
)
4767 def new_tenant(mydb
, tenant_dict
):
4769 tenant_uuid
= str(uuid4())
4770 tenant_dict
['uuid'] = tenant_uuid
4772 pub_key
, priv_key
= create_RO_keypair(tenant_uuid
)
4773 tenant_dict
['RO_pub_key'] = pub_key
4774 tenant_dict
['encrypted_RO_priv_key'] = priv_key
4775 mydb
.new_row("nfvo_tenants", tenant_dict
, confidential_data
=True)
4776 except db_base_Exception
as e
:
4777 raise NfvoException("Error creating the new tenant: {} ".format(tenant_dict
['name']) + str(e
), e
.http_code
)
4780 def delete_tenant(mydb
, tenant
):
4781 #get nfvo_tenant info
4783 tenant_dict
= mydb
.get_table_by_uuid_name('nfvo_tenants', tenant
, 'tenant')
4784 mydb
.delete_row_by_id("nfvo_tenants", tenant_dict
['uuid'])
4785 return tenant_dict
['uuid'] + " " + tenant_dict
["name"]
4788 def new_datacenter(mydb
, datacenter_descriptor
):
4789 sdn_port_mapping
= None
4790 if "config" in datacenter_descriptor
:
4791 sdn_port_mapping
= datacenter_descriptor
["config"].pop("sdn-port-mapping", None)
4792 datacenter_descriptor
["config"] = yaml
.safe_dump(datacenter_descriptor
["config"], default_flow_style
=True,
4794 # Check that datacenter-type is correct
4795 datacenter_type
= datacenter_descriptor
.get("type", "openvim");
4796 # module_info = None
4798 module
= "vimconn_" + datacenter_type
4799 pkg
= __import__("osm_ro." + module
)
4800 # vim_conn = getattr(pkg, module)
4801 # module_info = imp.find_module(module, [__file__[:__file__.rfind("/")]])
4802 except (IOError, ImportError):
4803 # if module_info and module_info[0]:
4804 # file.close(module_info[0])
4805 raise NfvoException("Incorrect datacenter type '{}'. Plugin '{}.py' not installed".format(datacenter_type
,
4807 httperrors
.Bad_Request
)
4809 datacenter_id
= mydb
.new_row("datacenters", datacenter_descriptor
, add_uuid
=True, confidential_data
=True)
4810 if sdn_port_mapping
:
4812 datacenter_sdn_port_mapping_set(mydb
, None, datacenter_id
, sdn_port_mapping
)
4813 except Exception as e
:
4814 mydb
.delete_row_by_id("datacenters", datacenter_id
) # Rollback
4816 return datacenter_id
4819 def edit_datacenter(mydb
, datacenter_id_name
, datacenter_descriptor
):
4820 # obtain data, check that only one exist
4821 datacenter
= mydb
.get_table_by_uuid_name('datacenters', datacenter_id_name
)
4824 datacenter_id
= datacenter
['uuid']
4825 where
= {'uuid': datacenter
['uuid']}
4826 remove_port_mapping
= False
4827 new_sdn_port_mapping
= None
4828 if "config" in datacenter_descriptor
:
4829 if datacenter_descriptor
['config'] != None:
4831 new_config_dict
= datacenter_descriptor
["config"]
4832 if "sdn-port-mapping" in new_config_dict
:
4833 remove_port_mapping
= True
4834 new_sdn_port_mapping
= new_config_dict
.pop("sdn-port-mapping")
4835 # delete null fields
4837 for k
in new_config_dict
:
4838 if new_config_dict
[k
] is None:
4840 if k
== 'sdn-controller':
4841 remove_port_mapping
= True
4843 config_text
= datacenter
.get("config")
4846 config_dict
= yaml
.load(config_text
)
4847 config_dict
.update(new_config_dict
)
4848 # delete null fields
4851 except Exception as e
:
4852 raise NfvoException("Bad format at datacenter:config " + str(e
), httperrors
.Bad_Request
)
4854 datacenter_descriptor
["config"] = yaml
.safe_dump(config_dict
, default_flow_style
=True, width
=256)
4856 datacenter_descriptor
["config"] = None
4857 if remove_port_mapping
:
4859 datacenter_sdn_port_mapping_delete(mydb
, None, datacenter_id
)
4860 except ovimException
as e
:
4861 raise NfvoException("Error deleting datacenter-port-mapping " + str(e
), httperrors
.Conflict
)
4863 mydb
.update_rows('datacenters', datacenter_descriptor
, where
)
4864 if new_sdn_port_mapping
:
4866 datacenter_sdn_port_mapping_set(mydb
, None, datacenter_id
, new_sdn_port_mapping
)
4867 except ovimException
as e
:
4869 mydb
.update_rows('datacenters', datacenter
, where
)
4870 raise NfvoException("Error adding datacenter-port-mapping " + str(e
), httperrors
.Conflict
)
4871 return datacenter_id
4874 def delete_datacenter(mydb
, datacenter
):
4875 #get nfvo_tenant info
4876 datacenter_dict
= mydb
.get_table_by_uuid_name('datacenters', datacenter
, 'datacenter')
4877 mydb
.delete_row_by_id("datacenters", datacenter_dict
['uuid'])
4879 datacenter_sdn_port_mapping_delete(mydb
, None, datacenter_dict
['uuid'])
4880 except ovimException
as e
:
4881 raise NfvoException("Error deleting datacenter-port-mapping " + str(e
))
4882 return datacenter_dict
['uuid'] + " " + datacenter_dict
['name']
4885 def create_vim_account(mydb
, nfvo_tenant
, datacenter_id
, name
=None, vim_id
=None, vim_tenant
=None, vim_tenant_name
=None,
4886 vim_username
=None, vim_password
=None, config
=None):
4887 # get datacenter info
4889 if not datacenter_id
:
4891 raise NfvoException("You must provide 'vim_id", http_code
=httperrors
.Bad_Request
)
4892 datacenter_id
= vim_id
4893 datacenter_id
, datacenter_name
= get_datacenter_uuid(mydb
, None, datacenter_id
)
4895 create_vim_tenant
= True if not vim_tenant
and not vim_tenant_name
else False
4897 # get nfvo_tenant info
4898 tenant_dict
= mydb
.get_table_by_uuid_name('nfvo_tenants', nfvo_tenant
)
4899 if vim_tenant_name
==None:
4900 vim_tenant_name
=tenant_dict
['name']
4902 tenants_datacenter_dict
={"nfvo_tenant_id":tenant_dict
['uuid'], "datacenter_id":datacenter_id
}
4903 # #check that this association does not exist before
4904 # tenants_datacenters = mydb.get_rows(FROM='tenants_datacenters', WHERE=tenants_datacenter_dict)
4905 # if len(tenants_datacenters)>0:
4906 # raise NfvoException("datacenter '{}' and tenant'{}' are already attached".format(datacenter_id, tenant_dict['uuid']), httperrors.Conflict)
4908 vim_tenant_id_exist_atdb
=False
4909 if not create_vim_tenant
:
4910 where_
={"datacenter_id": datacenter_id
}
4911 if vim_tenant
!=None:
4912 where_
["vim_tenant_id"] = vim_tenant
4913 if vim_tenant_name
!=None:
4914 where_
["vim_tenant_name"] = vim_tenant_name
4915 #check if vim_tenant_id is already at database
4916 datacenter_tenants_dict
= mydb
.get_rows(FROM
='datacenter_tenants', WHERE
=where_
)
4917 if len(datacenter_tenants_dict
)>=1:
4918 datacenter_tenants_dict
= datacenter_tenants_dict
[0]
4919 vim_tenant_id_exist_atdb
=True
4920 #TODO check if a field has changed and edit entry at datacenter_tenants at DB
4922 datacenter_tenants_dict
= {}
4923 #insert at table datacenter_tenants
4924 else: #if vim_tenant==None:
4925 #create tenant at VIM if not provided
4927 _
, myvim
= get_datacenter_by_name_uuid(mydb
, None, datacenter
, vim_user
=vim_username
,
4928 vim_passwd
=vim_password
)
4929 datacenter_name
= myvim
["name"]
4930 vim_tenant
= myvim
.new_tenant(vim_tenant_name
, "created by openmano for datacenter "+datacenter_name
)
4931 except vimconn
.vimconnException
as e
:
4932 raise NfvoException("Not possible to create vim_tenant {} at VIM: {}".format(vim_tenant_id
, str(e
)), httperrors
.Internal_Server_Error
)
4933 datacenter_tenants_dict
= {}
4934 datacenter_tenants_dict
["created"]="true"
4936 #fill datacenter_tenants table
4937 if not vim_tenant_id_exist_atdb
:
4938 datacenter_tenants_dict
["vim_tenant_id"] = vim_tenant
4939 datacenter_tenants_dict
["vim_tenant_name"] = vim_tenant_name
4940 datacenter_tenants_dict
["user"] = vim_username
4941 datacenter_tenants_dict
["passwd"] = vim_password
4942 datacenter_tenants_dict
["datacenter_id"] = datacenter_id
4944 datacenter_tenants_dict
["name"] = name
4946 datacenter_tenants_dict
["name"] = datacenter_name
4948 datacenter_tenants_dict
["config"] = yaml
.safe_dump(config
, default_flow_style
=True, width
=256)
4949 id_
= mydb
.new_row('datacenter_tenants', datacenter_tenants_dict
, add_uuid
=True, confidential_data
=True)
4950 datacenter_tenants_dict
["uuid"] = id_
4952 #fill tenants_datacenters table
4953 datacenter_tenant_id
= datacenter_tenants_dict
["uuid"]
4954 tenants_datacenter_dict
["datacenter_tenant_id"] = datacenter_tenant_id
4955 mydb
.new_row('tenants_datacenters', tenants_datacenter_dict
)
4958 thread_name
= get_non_used_vim_name(datacenter_name
, datacenter_id
, tenant_dict
['name'], tenant_dict
['uuid'])
4959 new_thread
= vim_thread
.vim_thread(task_lock
, thread_name
, datacenter_name
, datacenter_tenant_id
,
4960 db
=db
, db_lock
=db_lock
, ovim
=ovim
)
4962 thread_id
= datacenter_tenants_dict
["uuid"]
4963 vim_threads
["running"][thread_id
] = new_thread
4965 except vimconn
.vimconnException
as e
:
4966 raise NfvoException(str(e
), httperrors
.Bad_Request
)
4969 def edit_vim_account(mydb
, nfvo_tenant
, datacenter_tenant_id
, datacenter_id
=None, name
=None, vim_tenant
=None,
4970 vim_tenant_name
=None, vim_username
=None, vim_password
=None, config
=None):
4972 # get vim_account; check is valid for this tenant
4973 from_
= "datacenter_tenants as dt JOIN tenants_datacenters as td ON dt.uuid=td.datacenter_tenant_id"
4974 where_
= {"td.nfvo_tenant_id": nfvo_tenant
}
4975 if datacenter_tenant_id
:
4976 where_
["dt.uuid"] = datacenter_tenant_id
4978 where_
["dt.datacenter_id"] = datacenter_id
4979 vim_accounts
= mydb
.get_rows(SELECT
="dt.uuid as uuid, config", FROM
=from_
, WHERE
=where_
)
4980 if not vim_accounts
:
4981 raise NfvoException("vim_account not found for this tenant", http_code
=httperrors
.Not_Found
)
4982 elif len(vim_accounts
) > 1:
4983 raise NfvoException("found more than one vim_account for this tenant", http_code
=httperrors
.Conflict
)
4984 datacenter_tenant_id
= vim_accounts
[0]["uuid"]
4985 original_config
= vim_accounts
[0]["config"]
4989 original_config_dict
= yaml
.load(original_config
)
4990 original_config_dict
.update(config
)
4991 update
["config"] = yaml
.safe_dump(original_config_dict
, default_flow_style
=True, width
=256)
4993 update_
['name'] = name
4995 update_
['vim_tenant_id'] = vim_tenant
4997 update_
['vim_tenant_name'] = vim_tenant_name
4999 update_
['user'] = vim_username
5001 update_
['passwd'] = vim_password
5003 mydb
.update_rows("datacenter_tenants", UPDATE
=update_
, WHERE
={"uuid": datacenter_tenant_id
})
5005 vim_threads
["running"][datacenter_tenant_id
].insert_task("reload")
5006 return datacenter_tenant_id
5008 def delete_vim_account(mydb
, tenant_id
, vim_account_id
, datacenter
=None):
5009 #get nfvo_tenant info
5010 if not tenant_id
or tenant_id
=="any":
5013 tenant_dict
= mydb
.get_table_by_uuid_name('nfvo_tenants', tenant_id
)
5014 tenant_uuid
= tenant_dict
['uuid']
5016 #check that this association exist before
5017 tenants_datacenter_dict
= {}
5019 datacenter_id
, _
= get_datacenter_uuid(mydb
, tenant_uuid
, datacenter
)
5020 tenants_datacenter_dict
["datacenter_id"] = datacenter_id
5021 elif vim_account_id
:
5022 tenants_datacenter_dict
["datacenter_tenant_id"] = vim_account_id
5024 tenants_datacenter_dict
["nfvo_tenant_id"] = tenant_uuid
5025 tenant_datacenter_list
= mydb
.get_rows(FROM
='tenants_datacenters', WHERE
=tenants_datacenter_dict
)
5026 if len(tenant_datacenter_list
)==0 and tenant_uuid
:
5027 raise NfvoException("datacenter '{}' and tenant '{}' are not attached".format(datacenter_id
, tenant_dict
['uuid']), httperrors
.Not_Found
)
5029 #delete this association
5030 mydb
.delete_row(FROM
='tenants_datacenters', WHERE
=tenants_datacenter_dict
)
5032 #get vim_tenant info and deletes
5034 for tenant_datacenter_item
in tenant_datacenter_list
:
5035 vim_tenant_dict
= mydb
.get_table_by_uuid_name('datacenter_tenants', tenant_datacenter_item
['datacenter_tenant_id'])
5036 #try to delete vim:tenant
5038 mydb
.delete_row_by_id('datacenter_tenants', tenant_datacenter_item
['datacenter_tenant_id'])
5039 if vim_tenant_dict
['created']=='true':
5040 #delete tenant at VIM if created by NFVO
5042 datacenter_id
, myvim
= get_datacenter_by_name_uuid(mydb
, tenant_id
, datacenter
)
5043 myvim
.delete_tenant(vim_tenant_dict
['vim_tenant_id'])
5044 except vimconn
.vimconnException
as e
:
5045 warning
= "Not possible to delete vim_tenant_id {} from VIM: {} ".format(vim_tenant_dict
['vim_tenant_id'], str(e
))
5046 logger
.warn(warning
)
5047 except db_base_Exception
as e
:
5048 logger
.error("Cannot delete datacenter_tenants " + str(e
))
5049 pass # the error will be caused because dependencies, vim_tenant can not be deleted
5050 thread_id
= tenant_datacenter_item
["datacenter_tenant_id"]
5051 thread
= vim_threads
["running"].get(thread_id
)
5053 thread
.insert_task("exit")
5054 vim_threads
["deleting"][thread_id
] = thread
5055 return "datacenter {} detached. {}".format(datacenter_id
, warning
)
5058 def datacenter_action(mydb
, tenant_id
, datacenter
, action_dict
):
5060 #get datacenter info
5061 datacenter_id
, myvim
= get_datacenter_by_name_uuid(mydb
, tenant_id
, datacenter
)
5063 if 'net-update' in action_dict
:
5065 nets
= myvim
.get_network_list(filter_dict
={'shared': True, 'admin_state_up': True, 'status': 'ACTIVE'})
5067 except vimconn
.vimconnException
as e
:
5068 #logger.error("nfvo.datacenter_action() Not possible to get_network_list from VIM: %s ", str(e))
5069 raise NfvoException(str(e
), httperrors
.Internal_Server_Error
)
5070 #update nets Change from VIM format to NFVO format
5073 net_nfvo
={'datacenter_id': datacenter_id
}
5074 net_nfvo
['name'] = net
['name']
5075 #net_nfvo['description']= net['name']
5076 net_nfvo
['vim_net_id'] = net
['id']
5077 net_nfvo
['type'] = net
['type'][0:6] #change from ('ptp','data','bridge_data','bridge_man') to ('bridge','data','ptp')
5078 net_nfvo
['shared'] = net
['shared']
5079 net_nfvo
['multipoint'] = False if net
['type']=='ptp' else True
5080 net_list
.append(net_nfvo
)
5081 inserted
, deleted
= mydb
.update_datacenter_nets(datacenter_id
, net_list
)
5082 logger
.info("Inserted %d nets, deleted %d old nets", inserted
, deleted
)
5084 elif 'net-edit' in action_dict
:
5085 net
= action_dict
['net-edit'].pop('net')
5086 what
= 'vim_net_id' if utils
.check_valid_uuid(net
) else 'name'
5087 result
= mydb
.update_rows('datacenter_nets', action_dict
['net-edit'],
5088 WHERE
={'datacenter_id':datacenter_id
, what
: net
})
5090 elif 'net-delete' in action_dict
:
5091 net
= action_dict
['net-deelte'].get('net')
5092 what
= 'vim_net_id' if utils
.check_valid_uuid(net
) else 'name'
5093 result
= mydb
.delete_row(FROM
='datacenter_nets',
5094 WHERE
={'datacenter_id':datacenter_id
, what
: net
})
5098 raise NfvoException("Unknown action " + str(action_dict
), httperrors
.Bad_Request
)
5101 def datacenter_edit_netmap(mydb
, tenant_id
, datacenter
, netmap
, action_dict
):
5102 #get datacenter info
5103 datacenter_id
, _
= get_datacenter_by_name_uuid(mydb
, tenant_id
, datacenter
)
5105 what
= 'uuid' if utils
.check_valid_uuid(netmap
) else 'name'
5106 result
= mydb
.update_rows('datacenter_nets', action_dict
['netmap'],
5107 WHERE
={'datacenter_id':datacenter_id
, what
: netmap
})
5111 def datacenter_new_netmap(mydb
, tenant_id
, datacenter
, action_dict
=None):
5112 #get datacenter info
5113 datacenter_id
, myvim
= get_datacenter_by_name_uuid(mydb
, tenant_id
, datacenter
)
5116 action_dict
= action_dict
["netmap"]
5117 if 'vim_id' in action_dict
:
5118 filter_dict
["id"] = action_dict
['vim_id']
5119 if 'vim_name' in action_dict
:
5120 filter_dict
["name"] = action_dict
['vim_name']
5122 filter_dict
["shared"] = True
5125 vim_nets
= myvim
.get_network_list(filter_dict
=filter_dict
)
5126 except vimconn
.vimconnException
as e
:
5127 #logger.error("nfvo.datacenter_new_netmap() Not possible to get_network_list from VIM: %s ", str(e))
5128 raise NfvoException(str(e
), httperrors
.Internal_Server_Error
)
5129 if len(vim_nets
)>1 and action_dict
:
5130 raise NfvoException("more than two networks found, specify with vim_id", httperrors
.Conflict
)
5131 elif len(vim_nets
)==0: # and action_dict:
5132 raise NfvoException("Not found a network at VIM with " + str(filter_dict
), httperrors
.Not_Found
)
5134 for net
in vim_nets
:
5135 net_nfvo
={'datacenter_id': datacenter_id
}
5136 if action_dict
and "name" in action_dict
:
5137 net_nfvo
['name'] = action_dict
['name']
5139 net_nfvo
['name'] = net
['name']
5140 #net_nfvo['description']= net['name']
5141 net_nfvo
['vim_net_id'] = net
['id']
5142 net_nfvo
['type'] = net
['type'][0:6] #change from ('ptp','data','bridge_data','bridge_man') to ('bridge','data','ptp')
5143 net_nfvo
['shared'] = net
['shared']
5144 net_nfvo
['multipoint'] = False if net
['type']=='ptp' else True
5146 net_id
= mydb
.new_row("datacenter_nets", net_nfvo
, add_uuid
=True)
5147 net_nfvo
["status"] = "OK"
5148 net_nfvo
["uuid"] = net_id
5149 except db_base_Exception
as e
:
5153 net_nfvo
["status"] = "FAIL: " + str(e
)
5154 net_list
.append(net_nfvo
)
5157 def get_sdn_net_id(mydb
, tenant_id
, datacenter
, network_id
):
5158 # obtain all network data
5160 if utils
.check_valid_uuid(network_id
):
5161 filter_dict
= {"id": network_id
}
5163 filter_dict
= {"name": network_id
}
5165 datacenter_id
, myvim
= get_datacenter_by_name_uuid(mydb
, tenant_id
, datacenter
)
5166 network
= myvim
.get_network_list(filter_dict
=filter_dict
)
5167 except vimconn
.vimconnException
as e
:
5168 raise NfvoException("Not possible to get_sdn_net_id from VIM: {}".format(str(e
)), e
.http_code
)
5170 # ensure the network is defined
5171 if len(network
) == 0:
5172 raise NfvoException("Network {} is not present in the system".format(network_id
),
5173 httperrors
.Bad_Request
)
5175 # ensure there is only one network with the provided name
5176 if len(network
) > 1:
5177 raise NfvoException("Multiple networks present in vim identified by {}".format(network_id
), httperrors
.Bad_Request
)
5179 # ensure it is a dataplane network
5180 if network
[0]['type'] != 'data':
5183 # ensure we use the id
5184 network_id
= network
[0]['id']
5186 # search in dabase mano_db in table instance nets for the sdn_net_id that corresponds to the vim_net_id==network_id
5187 # and with instance_scenario_id==NULL
5188 #search_dict = {'vim_net_id': network_id, 'instance_scenario_id': None}
5189 search_dict
= {'vim_net_id': network_id
}
5192 #sdn_network_id = mydb.get_rows(SELECT=('sdn_net_id',), FROM='instance_nets', WHERE=search_dict)[0]['sdn_net_id']
5193 result
= mydb
.get_rows(SELECT
=('sdn_net_id',), FROM
='instance_nets', WHERE
=search_dict
)
5194 except db_base_Exception
as e
:
5195 raise NfvoException("db_base_Exception obtaining SDN network to associated to vim network {}".format(
5196 network_id
) + str(e
), e
.http_code
)
5200 if net
['sdn_net_id'] != None:
5202 sdn_net_id
= net
['sdn_net_id']
5204 if sdn_net_counter
== 0:
5206 elif sdn_net_counter
== 1:
5209 raise NfvoException("More than one SDN network is associated to vim network {}".format(
5210 network_id
), httperrors
.Internal_Server_Error
)
5212 def get_sdn_controller_id(mydb
, datacenter
):
5213 # Obtain sdn controller id
5214 config
= mydb
.get_rows(SELECT
=('config',), FROM
='datacenters', WHERE
={'uuid': datacenter
})[0].get('config', '{}')
5218 return yaml
.load(config
).get('sdn-controller')
5220 def vim_net_sdn_attach(mydb
, tenant_id
, datacenter
, network_id
, descriptor
):
5222 sdn_network_id
= get_sdn_net_id(mydb
, tenant_id
, datacenter
, network_id
)
5223 if not sdn_network_id
:
5224 raise NfvoException("No SDN network is associated to vim-network {}".format(network_id
), httperrors
.Internal_Server_Error
)
5226 #Obtain sdn controller id
5227 controller_id
= get_sdn_controller_id(mydb
, datacenter
)
5228 if not controller_id
:
5229 raise NfvoException("No SDN controller is set for datacenter {}".format(datacenter
), httperrors
.Internal_Server_Error
)
5231 #Obtain sdn controller info
5232 sdn_controller
= ovim
.show_of_controller(controller_id
)
5235 'name': 'external_port',
5236 'net_id': sdn_network_id
,
5237 'ofc_id': controller_id
,
5238 'switch_dpid': sdn_controller
['dpid'],
5239 'switch_port': descriptor
['port']
5242 if 'vlan' in descriptor
:
5243 port_data
['vlan'] = descriptor
['vlan']
5244 if 'mac' in descriptor
:
5245 port_data
['mac'] = descriptor
['mac']
5247 result
= ovim
.new_port(port_data
)
5248 except ovimException
as e
:
5249 raise NfvoException("ovimException attaching SDN network {} to vim network {}".format(
5250 sdn_network_id
, network_id
) + str(e
), httperrors
.Internal_Server_Error
)
5251 except db_base_Exception
as e
:
5252 raise NfvoException("db_base_Exception attaching SDN network to vim network {}".format(
5253 network_id
) + str(e
), e
.http_code
)
5255 return 'Port uuid: '+ result
5257 def vim_net_sdn_detach(mydb
, tenant_id
, datacenter
, network_id
, port_id
=None):
5259 filter = {'uuid': port_id
}
5261 sdn_network_id
= get_sdn_net_id(mydb
, tenant_id
, datacenter
, network_id
)
5262 if not sdn_network_id
:
5263 raise NfvoException("No SDN network is associated to vim-network {}".format(network_id
),
5264 httperrors
.Internal_Server_Error
)
5265 #in case no port_id is specified only ports marked as 'external_port' will be detached
5266 filter = {'name': 'external_port', 'net_id': sdn_network_id
}
5269 port_list
= ovim
.get_ports(columns
={'uuid'}, filter=filter)
5270 except ovimException
as e
:
5271 raise NfvoException("ovimException obtaining external ports for net {}. ".format(network_id
) + str(e
),
5272 httperrors
.Internal_Server_Error
)
5274 if len(port_list
) == 0:
5275 raise NfvoException("No ports attached to the network {} were found with the requested criteria".format(network_id
),
5276 httperrors
.Bad_Request
)
5279 for port
in port_list
:
5281 port_uuid_list
.append(port
['uuid'])
5282 ovim
.delete_port(port
['uuid'])
5283 except ovimException
as e
:
5284 raise NfvoException("ovimException deleting port {} for net {}. ".format(port
['uuid'], network_id
) + str(e
), httperrors
.Internal_Server_Error
)
5286 return 'Detached ports uuid: {}'.format(','.join(port_uuid_list
))
5288 def vim_action_get(mydb
, tenant_id
, datacenter
, item
, name
):
5289 #get datacenter info
5290 datacenter_id
, myvim
= get_datacenter_by_name_uuid(mydb
, tenant_id
, datacenter
)
5293 if utils
.check_valid_uuid(name
):
5294 filter_dict
["id"] = name
5296 filter_dict
["name"] = name
5298 if item
=="networks":
5299 #filter_dict['tenant_id'] = myvim['tenant_id']
5300 content
= myvim
.get_network_list(filter_dict
=filter_dict
)
5302 if len(content
) == 0:
5303 raise NfvoException("Network {} is not present in the system. ".format(name
),
5304 httperrors
.Bad_Request
)
5306 #Update the networks with the attached ports
5308 sdn_network_id
= get_sdn_net_id(mydb
, tenant_id
, datacenter
, net
['id'])
5309 if sdn_network_id
!= None:
5311 #port_list = ovim.get_ports(columns={'uuid', 'switch_port', 'vlan'}, filter={'name': 'external_port', 'net_id': sdn_network_id})
5312 port_list
= ovim
.get_ports(columns
={'uuid', 'switch_port', 'vlan','name'}, filter={'net_id': sdn_network_id
})
5313 except ovimException
as e
:
5314 raise NfvoException("ovimException obtaining external ports for net {}. ".format(network_id
) + str(e
), httperrors
.Internal_Server_Error
)
5315 #Remove field name and if port name is external_port save it as 'type'
5316 for port
in port_list
:
5317 if port
['name'] == 'external_port':
5318 port
['type'] = "External"
5320 net
['sdn_network_id'] = sdn_network_id
5321 net
['sdn_attached_ports'] = port_list
5323 elif item
=="tenants":
5324 content
= myvim
.get_tenant_list(filter_dict
=filter_dict
)
5325 elif item
== "images":
5327 content
= myvim
.get_image_list(filter_dict
=filter_dict
)
5329 raise NfvoException(item
+ "?", httperrors
.Method_Not_Allowed
)
5330 logger
.debug("vim_action response %s", content
) #update nets Change from VIM format to NFVO format
5331 if name
and len(content
)==1:
5332 return {item
[:-1]: content
[0]}
5333 elif name
and len(content
)==0:
5334 raise NfvoException("No {} found with ".format(item
[:-1]) + " and ".join(map(lambda x
: str(x
[0])+": "+str(x
[1]), filter_dict
.iteritems())),
5337 return {item
: content
}
5338 except vimconn
.vimconnException
as e
:
5339 print "vim_action Not possible to get_%s_list from VIM: %s " % (item
, str(e
))
5340 raise NfvoException("Not possible to get_{}_list from VIM: {}".format(item
, str(e
)), e
.http_code
)
5343 def vim_action_delete(mydb
, tenant_id
, datacenter
, item
, name
):
5344 #get datacenter info
5345 if tenant_id
== "any":
5348 datacenter_id
, myvim
= get_datacenter_by_name_uuid(mydb
, tenant_id
, datacenter
)
5350 content
= vim_action_get(mydb
, tenant_id
, datacenter
, item
, name
)
5351 logger
.debug("vim_action_delete vim response: " + str(content
))
5352 items
= content
.values()[0]
5353 if type(items
)==list and len(items
)==0:
5354 raise NfvoException("Not found " + item
, httperrors
.Not_Found
)
5355 elif type(items
)==list and len(items
)>1:
5356 raise NfvoException("Found more than one {} with this name. Use uuid.".format(item
), httperrors
.Not_Found
)
5357 else: # it is a dict
5358 item_id
= items
["id"]
5359 item_name
= str(items
.get("name"))
5362 if item
=="networks":
5363 # If there is a SDN network associated to the vim-network, proceed to clear the relationship and delete it
5364 sdn_network_id
= get_sdn_net_id(mydb
, tenant_id
, datacenter
, item_id
)
5365 if sdn_network_id
!= None:
5366 #Delete any port attachment to this network
5368 port_list
= ovim
.get_ports(columns
={'uuid'}, filter={'net_id': sdn_network_id
})
5369 except ovimException
as e
:
5370 raise NfvoException(
5371 "ovimException obtaining external ports for net {}. ".format(network_id
) + str(e
),
5372 httperrors
.Internal_Server_Error
)
5374 # By calling one by one all ports to be detached we ensure that not only the external_ports get detached
5375 for port
in port_list
:
5376 vim_net_sdn_detach(mydb
, tenant_id
, datacenter
, item_id
, port
['uuid'])
5378 #Delete from 'instance_nets' the correspondence between the vim-net-id and the sdn-net-id
5380 mydb
.delete_row(FROM
='instance_nets', WHERE
={'instance_scenario_id': None, 'sdn_net_id': sdn_network_id
, 'vim_net_id': item_id
})
5381 except db_base_Exception
as e
:
5382 raise NfvoException("Error deleting correspondence for VIM/SDN dataplane networks{}: ".format(correspondence
) +
5383 str(e
), e
.http_code
)
5385 #Delete the SDN network
5387 ovim
.delete_network(sdn_network_id
)
5388 except ovimException
as e
:
5389 logger
.error("ovimException deleting SDN network={} ".format(sdn_network_id
) + str(e
), exc_info
=True)
5390 raise NfvoException("ovimException deleting SDN network={} ".format(sdn_network_id
) + str(e
),
5391 httperrors
.Internal_Server_Error
)
5393 content
= myvim
.delete_network(item_id
)
5394 elif item
=="tenants":
5395 content
= myvim
.delete_tenant(item_id
)
5396 elif item
== "images":
5397 content
= myvim
.delete_image(item_id
)
5399 raise NfvoException(item
+ "?", httperrors
.Method_Not_Allowed
)
5400 except vimconn
.vimconnException
as e
:
5401 #logger.error( "vim_action Not possible to delete_{} {}from VIM: {} ".format(item, name, str(e)))
5402 raise NfvoException("Not possible to delete_{} {} from VIM: {}".format(item
, name
, str(e
)), e
.http_code
)
5404 return "{} {} {} deleted".format(item
[:-1], item_id
,item_name
)
5407 def vim_action_create(mydb
, tenant_id
, datacenter
, item
, descriptor
):
5408 #get datacenter info
5409 logger
.debug("vim_action_create descriptor %s", str(descriptor
))
5410 if tenant_id
== "any":
5412 datacenter_id
, myvim
= get_datacenter_by_name_uuid(mydb
, tenant_id
, datacenter
)
5414 if item
=="networks":
5415 net
= descriptor
["network"]
5416 net_name
= net
.pop("name")
5417 net_type
= net
.pop("type", "bridge")
5418 net_public
= net
.pop("shared", False)
5419 net_ipprofile
= net
.pop("ip_profile", None)
5420 net_vlan
= net
.pop("vlan", None)
5421 content
= myvim
.new_network(net_name
, net_type
, net_ipprofile
, shared
=net_public
, vlan
=net_vlan
) #, **net)
5423 #If the datacenter has a SDN controller defined and the network is of dataplane type, then create the sdn network
5424 if get_sdn_controller_id(mydb
, datacenter
) != None and (net_type
== 'data' or net_type
== 'ptp'):
5425 #obtain datacenter_tenant_id
5426 datacenter_tenant_id
= mydb
.get_rows(SELECT
=('uuid',),
5427 FROM
='datacenter_tenants',
5428 WHERE
={'datacenter_id': datacenter
})[0]['uuid']
5431 sdn_network
['vlan'] = net_vlan
5432 sdn_network
['type'] = net_type
5433 sdn_network
['name'] = net_name
5434 sdn_network
['region'] = datacenter_tenant_id
5435 ovim_content
= ovim
.new_network(sdn_network
)
5436 except ovimException
as e
:
5437 logger
.error("ovimException creating SDN network={} ".format(
5438 sdn_network
) + str(e
), exc_info
=True)
5439 raise NfvoException("ovimException creating SDN network={} ".format(sdn_network
) + str(e
),
5440 httperrors
.Internal_Server_Error
)
5442 # Save entry in in dabase mano_db in table instance_nets to stablish a dictionary vim_net_id <->sdn_net_id
5443 # use instance_scenario_id=None to distinguish from real instaces of nets
5444 correspondence
= {'instance_scenario_id': None,
5445 'sdn_net_id': ovim_content
,
5446 'vim_net_id': content
,
5447 'datacenter_tenant_id': datacenter_tenant_id
5450 mydb
.new_row('instance_nets', correspondence
, add_uuid
=True)
5451 except db_base_Exception
as e
:
5452 raise NfvoException("Error saving correspondence for VIM/SDN dataplane networks{}: {}".format(
5453 correspondence
, e
), e
.http_code
)
5454 elif item
=="tenants":
5455 tenant
= descriptor
["tenant"]
5456 content
= myvim
.new_tenant(tenant
["name"], tenant
.get("description"))
5458 raise NfvoException(item
+ "?", httperrors
.Method_Not_Allowed
)
5459 except vimconn
.vimconnException
as e
:
5460 raise NfvoException("Not possible to create {} at VIM: {}".format(item
, str(e
)), e
.http_code
)
5462 return vim_action_get(mydb
, tenant_id
, datacenter
, item
, content
)
5464 def sdn_controller_create(mydb
, tenant_id
, sdn_controller
):
5465 data
= ovim
.new_of_controller(sdn_controller
)
5466 logger
.debug('New SDN controller created with uuid {}'.format(data
))
5469 def sdn_controller_update(mydb
, tenant_id
, controller_id
, sdn_controller
):
5470 data
= ovim
.edit_of_controller(controller_id
, sdn_controller
)
5471 msg
= 'SDN controller {} updated'.format(data
)
5475 def sdn_controller_list(mydb
, tenant_id
, controller_id
=None):
5476 if controller_id
== None:
5477 data
= ovim
.get_of_controllers()
5479 data
= ovim
.show_of_controller(controller_id
)
5481 msg
= 'SDN controller list:\n {}'.format(data
)
5485 def sdn_controller_delete(mydb
, tenant_id
, controller_id
):
5486 select_
= ('uuid', 'config')
5487 datacenters
= mydb
.get_rows(FROM
='datacenters', SELECT
=select_
)
5488 for datacenter
in datacenters
:
5489 if datacenter
['config']:
5490 config
= yaml
.load(datacenter
['config'])
5491 if 'sdn-controller' in config
and config
['sdn-controller'] == controller_id
:
5492 raise NfvoException("SDN controller {} is in use by datacenter {}".format(controller_id
, datacenter
['uuid']), httperrors
.Conflict
)
5494 data
= ovim
.delete_of_controller(controller_id
)
5495 msg
= 'SDN controller {} deleted'.format(data
)
5499 def datacenter_sdn_port_mapping_set(mydb
, tenant_id
, datacenter_id
, sdn_port_mapping
):
5500 controller
= mydb
.get_rows(FROM
="datacenters", SELECT
=("config",), WHERE
={"uuid":datacenter_id
})
5501 if len(controller
) < 1:
5502 raise NfvoException("Datacenter {} not present in the database".format(datacenter_id
), httperrors
.Not_Found
)
5505 sdn_controller_id
= yaml
.load(controller
[0]["config"])["sdn-controller"]
5507 raise NfvoException("The datacenter {} has not an SDN controller associated".format(datacenter_id
), httperrors
.Bad_Request
)
5509 sdn_controller
= ovim
.show_of_controller(sdn_controller_id
)
5510 switch_dpid
= sdn_controller
["dpid"]
5513 for compute_node
in sdn_port_mapping
:
5514 #element = {"ofc_id": sdn_controller_id, "region": datacenter_id, "switch_dpid": switch_dpid}
5516 element
["compute_node"] = compute_node
["compute_node"]
5517 for port
in compute_node
["ports"]:
5518 pci
= port
.get("pci")
5519 element
["switch_port"] = port
.get("switch_port")
5520 element
["switch_mac"] = port
.get("switch_mac")
5521 if not pci
or not (element
["switch_port"] or element
["switch_mac"]):
5522 raise NfvoException ("The mapping must contain the 'pci' and at least one of the elements 'switch_port'"
5523 " or 'switch_mac'", httperrors
.Bad_Request
)
5524 for pci_expanded
in utils
.expand_brackets(pci
):
5525 element
["pci"] = pci_expanded
5526 maps
.append(dict(element
))
5528 return ovim
.set_of_port_mapping(maps
, ofc_id
=sdn_controller_id
, switch_dpid
=switch_dpid
, region
=datacenter_id
)
5530 def datacenter_sdn_port_mapping_list(mydb
, tenant_id
, datacenter_id
):
5531 maps
= ovim
.get_of_port_mappings(db_filter
={"region": datacenter_id
})
5534 "sdn-controller": None,
5535 "datacenter-id": datacenter_id
,
5537 "ports_mapping": list()
5540 datacenter
= mydb
.get_table_by_uuid_name('datacenters', datacenter_id
)
5541 if datacenter
['config']:
5542 config
= yaml
.load(datacenter
['config'])
5543 if 'sdn-controller' in config
:
5544 controller_id
= config
['sdn-controller']
5545 sdn_controller
= sdn_controller_list(mydb
, tenant_id
, controller_id
)
5546 result
["sdn-controller"] = controller_id
5547 result
["dpid"] = sdn_controller
["dpid"]
5549 if result
["sdn-controller"] == None:
5550 raise NfvoException("SDN controller is not defined for datacenter {}".format(datacenter_id
), httperrors
.Bad_Request
)
5551 if result
["dpid"] == None:
5552 raise NfvoException("It was not possible to determine DPID for SDN controller {}".format(result
["sdn-controller"]),
5553 httperrors
.Internal_Server_Error
)
5558 ports_correspondence_dict
= dict()
5560 if result
["sdn-controller"] != link
["ofc_id"]:
5561 raise NfvoException("The sdn-controller specified for different port mappings differ", httperrors
.Internal_Server_Error
)
5562 if result
["dpid"] != link
["switch_dpid"]:
5563 raise NfvoException("The dpid specified for different port mappings differ", httperrors
.Internal_Server_Error
)
5565 element
["pci"] = link
["pci"]
5566 if link
["switch_port"]:
5567 element
["switch_port"] = link
["switch_port"]
5568 if link
["switch_mac"]:
5569 element
["switch_mac"] = link
["switch_mac"]
5571 if not link
["compute_node"] in ports_correspondence_dict
:
5573 content
["compute_node"] = link
["compute_node"]
5574 content
["ports"] = list()
5575 ports_correspondence_dict
[link
["compute_node"]] = content
5577 ports_correspondence_dict
[link
["compute_node"]]["ports"].append(element
)
5579 for key
in sorted(ports_correspondence_dict
):
5580 result
["ports_mapping"].append(ports_correspondence_dict
[key
])
5584 def datacenter_sdn_port_mapping_delete(mydb
, tenant_id
, datacenter_id
):
5585 return ovim
.clear_of_port_mapping(db_filter
={"region":datacenter_id
})
5587 def create_RO_keypair(tenant_id
):
5589 Creates a public / private keys for a RO tenant and returns their values
5591 tenant_id: ID of the tenant
5593 public_key: Public key for the RO tenant
5594 private_key: Encrypted private key for RO tenant
5598 key
= RSA
.generate(bits
)
5600 public_key
= key
.publickey().exportKey('OpenSSH')
5601 if isinstance(public_key
, ValueError):
5602 raise NfvoException("Unable to create public key: {}".format(public_key
), httperrors
.Internal_Server_Error
)
5603 private_key
= key
.exportKey(passphrase
=tenant_id
, pkcs
=8)
5604 except (ValueError, NameError) as e
:
5605 raise NfvoException("Unable to create private key: {}".format(e
), httperrors
.Internal_Server_Error
)
5606 return public_key
, private_key
5608 def decrypt_key (key
, tenant_id
):
5610 Decrypts an encrypted RSA key
5612 key: Private key to be decrypted
5613 tenant_id: ID of the tenant
5615 unencrypted_key: Unencrypted private key for RO tenant
5618 key
= RSA
.importKey(key
,tenant_id
)
5619 unencrypted_key
= key
.exportKey('PEM')
5620 if isinstance(unencrypted_key
, ValueError):
5621 raise NfvoException("Unable to decrypt the private key: {}".format(unencrypted_key
), httperrors
.Internal_Server_Error
)
5622 except ValueError as e
:
5623 raise NfvoException("Unable to decrypt the private key: {}".format(e
), httperrors
.Internal_Server_Error
)
5624 return unencrypted_key