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
67 global vimconn_imported
71 global wimconn_imported
74 global default_volume_size
75 default_volume_size
= '5' #size in GB
80 vimconn_imported
= {} # dictionary with VIM type as key, loaded module as value
81 vim_threads
= {"running":{}, "deleting": {}, "names": []} # threads running for attached-VIMs
82 vim_persistent_info
= {}
84 wimconn_imported
= {} # dictionary with WIM type as key, loaded module as value
85 wim_threads
= {"running":{}, "deleting": {}, "names": []} # threads running for attached-WIMs
86 wim_persistent_info
= {}
89 logger
= logging
.getLogger('openmano.nfvo')
96 class NfvoException(httperrors
.HttpMappedError
):
97 """Common Class for NFVO errors"""
103 if task_id
<= last_task_id
:
104 task_id
= last_task_id
+ 0.000001
105 last_task_id
= task_id
106 return "ACTION-{:.6f}".format(task_id
)
107 # return (t.strftime("%Y%m%dT%H%M%S.{}%Z", t.localtime(task_id))).format(int((task_id % 1)*1e6))
110 def new_task(name
, params
, depends
=None):
112 task_id
= get_task_id()
113 task
= {"status": "enqueued", "id": task_id
, "name": name
, "params": params
}
115 task
["depends"] = depends
120 return True if id[:5] == "TASK-" else False
123 def get_non_used_vim_name(datacenter_name
, datacenter_id
, tenant_name
, tenant_id
):
124 name
= datacenter_name
[:16]
125 if name
not in vim_threads
["names"]:
126 vim_threads
["names"].append(name
)
128 name
= datacenter_name
[:16] + "." + tenant_name
[:16]
129 if name
not in vim_threads
["names"]:
130 vim_threads
["names"].append(name
)
132 name
= datacenter_id
+ "-" + tenant_id
133 vim_threads
["names"].append(name
)
137 def get_non_used_wim_name(wim_name
, wim_id
, tenant_name
, tenant_id
):
139 if name
not in wim_threads
["names"]:
140 wim_threads
["names"].append(name
)
142 name
= wim_name
[:16] + "." + tenant_name
[:16]
143 if name
not in wim_threads
["names"]:
144 wim_threads
["names"].append(name
)
146 name
= wim_id
+ "-" + tenant_id
147 wim_threads
["names"].append(name
)
151 def start_service(mydb
, persistence
=None, wim
=None):
152 global db
, global_config
153 db
= nfvo_db
.nfvo_db()
154 db
.connect(global_config
['db_host'], global_config
['db_user'], global_config
['db_passwd'], global_config
['db_name'])
158 persistence
.lock
= db_lock
160 persistence
= WimPersistence(db
, lock
=db_lock
)
162 # Initialize openvim for SDN control
163 # TODO: Avoid static configuration by adding new parameters to openmanod.cfg
164 # TODO: review ovim.py to delete not needed configuration
165 ovim_configuration
= {
166 'logger_name': 'openmano.ovim',
167 'network_vlan_range_start': 1000,
168 'network_vlan_range_end': 4096,
169 'db_name': global_config
["db_ovim_name"],
170 'db_host': global_config
["db_ovim_host"],
171 'db_user': global_config
["db_ovim_user"],
172 'db_passwd': global_config
["db_ovim_passwd"],
175 'network_type': 'bridge',
176 #TODO: log_level_of should not be needed. To be modified in ovim
177 'log_level_of': 'DEBUG'
180 # starts ovim library
181 ovim
= ovim_module
.ovim(ovim_configuration
)
184 wim_engine
= wim
or WimEngine(persistence
)
185 wim_engine
.ovim
= ovim
189 #delete old unneeded vim_wim_actions
193 from_
= 'tenants_datacenters as td join datacenters as d on td.datacenter_id=d.uuid join '\
194 'datacenter_tenants as dt on td.datacenter_tenant_id=dt.uuid'
195 select_
= ('type', 'd.config as config', 'd.uuid as datacenter_id', 'vim_url', 'vim_url_admin',
196 'd.name as datacenter_name', 'dt.uuid as datacenter_tenant_id',
197 'dt.vim_tenant_name as vim_tenant_name', 'dt.vim_tenant_id as vim_tenant_id',
198 'user', 'passwd', 'dt.config as dt_config', 'nfvo_tenant_id')
199 vims
= mydb
.get_rows(FROM
=from_
, SELECT
=select_
)
201 extra
={'datacenter_tenant_id': vim
.get('datacenter_tenant_id'),
202 'datacenter_id': vim
.get('datacenter_id')}
204 extra
.update(yaml
.load(vim
["config"]))
205 if vim
.get('dt_config'):
206 extra
.update(yaml
.load(vim
["dt_config"]))
207 if vim
["type"] not in vimconn_imported
:
210 module
= "vimconn_" + vim
["type"]
211 pkg
= __import__("osm_ro." + module
)
212 vim_conn
= getattr(pkg
, module
)
213 # module_info = imp.find_module(module, [__file__[:__file__.rfind("/")]])
214 # vim_conn = imp.load_module(vim["type"], *module_info)
215 vimconn_imported
[vim
["type"]] = vim_conn
216 except (IOError, ImportError) as e
:
217 # if module_info and module_info[0]:
218 # file.close(module_info[0])
219 raise NfvoException("Unknown vim type '{}'. Cannot open file '{}.py'; {}: {}".format(
220 vim
["type"], module
, type(e
).__name
__, str(e
)), httperrors
.Bad_Request
)
222 thread_id
= vim
['datacenter_tenant_id']
223 vim_persistent_info
[thread_id
] = {}
226 # return -httperrors.Bad_Request, "You must provide a valid tenant name or uuid for VIM %s" % ( vim["type"])
227 myvim
= vimconn_imported
[ vim
["type"] ].vimconnector(
228 uuid
=vim
['datacenter_id'], name
=vim
['datacenter_name'],
229 tenant_id
=vim
['vim_tenant_id'], tenant_name
=vim
['vim_tenant_name'],
230 url
=vim
['vim_url'], url_admin
=vim
['vim_url_admin'],
231 user
=vim
['user'], passwd
=vim
['passwd'],
232 config
=extra
, persistent_info
=vim_persistent_info
[thread_id
]
234 except vimconn
.vimconnException
as e
:
236 logger
.error("Cannot launch thread for VIM {} '{}': {}".format(vim
['datacenter_name'],
237 vim
['datacenter_id'], e
))
238 except Exception as e
:
239 raise NfvoException("Error at VIM {}; {}: {}".format(vim
["type"], type(e
).__name
__, e
),
240 httperrors
.Internal_Server_Error
)
241 thread_name
= get_non_used_vim_name(vim
['datacenter_name'], vim
['vim_tenant_id'], vim
['vim_tenant_name'],
242 vim
['vim_tenant_id'])
243 new_thread
= vim_thread
.vim_thread(task_lock
, thread_name
, vim
['datacenter_name'],
244 vim
['datacenter_tenant_id'], db
=db
, db_lock
=db_lock
, ovim
=ovim
)
246 vim_threads
["running"][thread_id
] = new_thread
248 wim_engine
.start_threads()
249 except db_base_Exception
as e
:
250 raise NfvoException(str(e
) + " at nfvo.get_vim", e
.http_code
)
251 except ovim_module
.ovimException
as e
:
253 if message
[:22] == "DATABASE wrong version":
254 message
= "DATABASE wrong version of lib_osm_openvim {msg} -d{dbname} -u{dbuser} -p{dbpass} {ver}' "\
255 "at host {dbhost}".format(
256 msg
=message
[22:-3], dbname
=global_config
["db_ovim_name"],
257 dbuser
=global_config
["db_ovim_user"], dbpass
=global_config
["db_ovim_passwd"],
258 ver
=message
[-3:-1], dbhost
=global_config
["db_ovim_host"])
259 raise NfvoException(message
, httperrors
.Bad_Request
)
263 global ovim
, global_config
266 for thread_id
, thread
in vim_threads
["running"].items():
267 thread
.insert_task("exit")
268 vim_threads
["deleting"][thread_id
] = thread
269 vim_threads
["running"] = {}
272 wim_engine
.stop_threads()
274 if global_config
and global_config
.get("console_thread"):
275 for thread
in global_config
["console_thread"]:
276 thread
.terminate
= True
279 return ("openmanod version {} {}\n(c) Copyright Telefonica".format(global_config
["version"],
280 global_config
["version_date"] ))
284 Clean unused or old entries at database to avoid unlimited growing
285 :param mydb: database connector
288 # get and delete unused vim_wim_actions: all elements deleted, one week before, instance not present
289 now
= t
.time()-3600*24*7
290 instance_action_id
= None
293 actions_to_delete
= mydb
.get_rows(
294 SELECT
=("item", "item_id", "instance_action_id"),
295 FROM
="vim_wim_actions as va join instance_actions as ia on va.instance_action_id=ia.uuid "
296 "left join instance_scenarios as i on ia.instance_id=i.uuid",
297 WHERE
={"va.action": "DELETE", "va.modified_at<": now
, "i.uuid": None,
298 "va.status": ("DONE", "SUPERSEDED")},
301 for to_delete
in actions_to_delete
:
302 mydb
.delete_row(FROM
="vim_wim_actions", WHERE
=to_delete
)
303 if instance_action_id
!= to_delete
["instance_action_id"]:
304 instance_action_id
= to_delete
["instance_action_id"]
305 mydb
.delete_row(FROM
="instance_actions", WHERE
={"uuid": instance_action_id
})
306 nb_deleted
+= len(actions_to_delete
)
307 if len(actions_to_delete
) < 100:
310 logger
.debug("Removed {} unused vim_wim_actions".format(nb_deleted
))
313 def get_flavorlist(mydb
, vnf_id
, nfvo_tenant
=None):
315 return result, content:
316 <0, error_text upon error
317 nb_records, flavor_list on success
320 WHERE_dict
['vnf_id'] = vnf_id
321 if nfvo_tenant
is not None:
322 WHERE_dict
['nfvo_tenant_id'] = nfvo_tenant
324 #result, content = mydb.get_table(FROM='vms join vnfs on vms.vnf_id = vnfs.uuid',SELECT=('uuid'),WHERE=WHERE_dict )
325 #result, content = mydb.get_table(FROM='vms',SELECT=('vim_flavor_id',),WHERE=WHERE_dict )
326 flavors
= mydb
.get_rows(FROM
='vms join flavors on vms.flavor_id=flavors.uuid',SELECT
=('flavor_id',),WHERE
=WHERE_dict
)
327 #print "get_flavor_list result:", result
328 #print "get_flavor_list content:", content
330 for flavor
in flavors
:
331 flavorList
.append(flavor
['flavor_id'])
335 def get_imagelist(mydb
, vnf_id
, nfvo_tenant
=None):
337 Get used images of all vms belonging to this VNFD
338 :param mydb: database conector
339 :param vnf_id: vnfd uuid
340 :param nfvo_tenant: tenant, not used
341 :return: The list of image uuid used
344 vms
= mydb
.get_rows(SELECT
=('image_id','image_list'), FROM
='vms', WHERE
={'vnf_id': vnf_id
})
346 if vm
["image_id"] not in image_list
:
347 image_list
.append(vm
["image_id"])
349 vm_image_list
= yaml
.load(vm
["image_list"])
350 for image_dict
in vm_image_list
:
351 if image_dict
["image_id"] not in image_list
:
352 image_list
.append(image_dict
["image_id"])
356 def get_vim(mydb
, nfvo_tenant
=None, datacenter_id
=None, datacenter_name
=None, datacenter_tenant_id
=None,
357 vim_tenant
=None, vim_tenant_name
=None, vim_user
=None, vim_passwd
=None, ignore_errors
=False):
358 '''Obtain a dictionary of VIM (datacenter) classes with some of the input parameters
359 return dictionary with {datacenter_id: vim_class, ... }. vim_class contain:
360 'nfvo_tenant_id','datacenter_id','vim_tenant_id','vim_url','vim_url_admin','datacenter_name','type','user','passwd'
361 raise exception upon error
364 if nfvo_tenant
is not None: WHERE_dict
['nfvo_tenant_id'] = nfvo_tenant
365 if datacenter_id
is not None: WHERE_dict
['d.uuid'] = datacenter_id
366 if datacenter_tenant_id
is not None: WHERE_dict
['datacenter_tenant_id'] = datacenter_tenant_id
367 if datacenter_name
is not None: WHERE_dict
['d.name'] = datacenter_name
368 if vim_tenant
is not None: WHERE_dict
['dt.vim_tenant_id'] = vim_tenant
369 if vim_tenant_name
is not None: WHERE_dict
['vim_tenant_name'] = vim_tenant_name
370 if nfvo_tenant
or vim_tenant
or vim_tenant_name
or datacenter_tenant_id
:
371 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'
372 select_
= ('type','d.config as config','d.uuid as datacenter_id', 'vim_url', 'vim_url_admin', 'd.name as datacenter_name',
373 'dt.uuid as datacenter_tenant_id','dt.vim_tenant_name as vim_tenant_name','dt.vim_tenant_id as vim_tenant_id',
374 'user','passwd', 'dt.config as dt_config')
376 from_
= 'datacenters as d'
377 select_
= ('type','config','d.uuid as datacenter_id', 'vim_url', 'vim_url_admin', 'd.name as datacenter_name')
379 vims
= mydb
.get_rows(FROM
=from_
, SELECT
=select_
, WHERE
=WHERE_dict
)
382 extra
={'datacenter_tenant_id': vim
.get('datacenter_tenant_id'),
383 'datacenter_id': vim
.get('datacenter_id'),
384 '_vim_type_internal': vim
.get('type')}
386 extra
.update(yaml
.load(vim
["config"]))
387 if vim
.get('dt_config'):
388 extra
.update(yaml
.load(vim
["dt_config"]))
389 if vim
["type"] not in vimconn_imported
:
392 module
= "vimconn_" + vim
["type"]
393 pkg
= __import__("osm_ro." + module
)
394 vim_conn
= getattr(pkg
, module
)
395 # module_info = imp.find_module(module, [__file__[:__file__.rfind("/")]])
396 # vim_conn = imp.load_module(vim["type"], *module_info)
397 vimconn_imported
[vim
["type"]] = vim_conn
398 except (IOError, ImportError) as e
:
399 # if module_info and module_info[0]:
400 # file.close(module_info[0])
402 logger
.error("Unknown vim type '{}'. Can not open file '{}.py'; {}: {}".format(
403 vim
["type"], module
, type(e
).__name
__, str(e
)))
405 raise NfvoException("Unknown vim type '{}'. Can not open file '{}.py'; {}: {}".format(
406 vim
["type"], module
, type(e
).__name
__, str(e
)), httperrors
.Bad_Request
)
409 if 'datacenter_tenant_id' in vim
:
410 thread_id
= vim
["datacenter_tenant_id"]
411 if thread_id
not in vim_persistent_info
:
412 vim_persistent_info
[thread_id
] = {}
413 persistent_info
= vim_persistent_info
[thread_id
]
417 # return -httperrors.Bad_Request, "You must provide a valid tenant name or uuid for VIM %s" % ( vim["type"])
418 vim_dict
[ vim
['datacenter_id'] ] = vimconn_imported
[ vim
["type"] ].vimconnector(
419 uuid
=vim
['datacenter_id'], name
=vim
['datacenter_name'],
420 tenant_id
=vim
.get('vim_tenant_id',vim_tenant
),
421 tenant_name
=vim
.get('vim_tenant_name',vim_tenant_name
),
422 url
=vim
['vim_url'], url_admin
=vim
['vim_url_admin'],
423 user
=vim
.get('user',vim_user
), passwd
=vim
.get('passwd',vim_passwd
),
424 config
=extra
, persistent_info
=persistent_info
426 except Exception as e
:
428 logger
.error("Error at VIM {}; {}: {}".format(vim
["type"], type(e
).__name
__, str(e
)))
430 http_code
= httperrors
.Internal_Server_Error
431 if isinstance(e
, vimconn
.vimconnException
):
432 http_code
= e
.http_code
433 raise NfvoException("Error at VIM {}; {}: {}".format(vim
["type"], type(e
).__name
__, str(e
)), http_code
)
435 except db_base_Exception
as e
:
436 raise NfvoException(str(e
) + " at nfvo.get_vim", e
.http_code
)
439 def rollback(mydb
, vims
, rollback_list
):
441 #delete things by reverse order
442 for i
in range(len(rollback_list
)-1, -1, -1):
443 item
= rollback_list
[i
]
444 if item
["where"]=="vim":
445 if item
["vim_id"] not in vims
:
447 if is_task_id(item
["uuid"]):
449 vim
= vims
[item
["vim_id"]]
451 if item
["what"]=="image":
452 vim
.delete_image(item
["uuid"])
453 mydb
.delete_row(FROM
="datacenters_images", WHERE
={"datacenter_vim_id": vim
["id"], "vim_id":item
["uuid"]})
454 elif item
["what"]=="flavor":
455 vim
.delete_flavor(item
["uuid"])
456 mydb
.delete_row(FROM
="datacenters_flavors", WHERE
={"datacenter_vim_id": vim
["id"], "vim_id":item
["uuid"]})
457 elif item
["what"]=="network":
458 vim
.delete_network(item
["uuid"])
459 elif item
["what"]=="vm":
460 vim
.delete_vminstance(item
["uuid"])
461 except vimconn
.vimconnException
as e
:
462 logger
.error("Error in rollback. Not possible to delete VIM %s '%s'. Message: %s", item
['what'], item
["uuid"], str(e
))
463 undeleted_items
.append("{} {} from VIM {}".format(item
['what'], item
["uuid"], vim
["name"]))
464 except db_base_Exception
as e
:
465 logger
.error("Error in rollback. Not possible to delete %s '%s' from DB.datacenters Message: %s", item
['what'], item
["uuid"], str(e
))
469 if item
["what"]=="image":
470 mydb
.delete_row(FROM
="images", WHERE
={"uuid": item
["uuid"]})
471 elif item
["what"]=="flavor":
472 mydb
.delete_row(FROM
="flavors", WHERE
={"uuid": item
["uuid"]})
473 except db_base_Exception
as e
:
474 logger
.error("Error in rollback. Not possible to delete %s '%s' from DB. Message: %s", item
['what'], item
["uuid"], str(e
))
475 undeleted_items
.append("{} '{}'".format(item
['what'], item
["uuid"]))
476 if len(undeleted_items
)==0:
477 return True," Rollback successful."
479 return False," Rollback fails to delete: " + str(undeleted_items
)
482 def check_vnf_descriptor(vnf_descriptor
, vnf_descriptor_version
=1):
484 #create a dictionary with vnfc-name: vnfc:interface-list key:values pairs
486 for vnfc
in vnf_descriptor
["vnf"]["VNFC"]:
488 #dataplane interfaces
489 for numa
in vnfc
.get("numas",() ):
490 for interface
in numa
.get("interfaces",()):
491 if interface
["name"] in name_dict
:
493 "Error at vnf:VNFC[name:'{}']:numas:interfaces:name, interface name '{}' already used in this VNFC".format(
494 vnfc
["name"], interface
["name"]),
495 httperrors
.Bad_Request
)
496 name_dict
[ interface
["name"] ] = "underlay"
498 for interface
in vnfc
.get("bridge-ifaces",() ):
499 if interface
["name"] in name_dict
:
501 "Error at vnf:VNFC[name:'{}']:bridge-ifaces:name, interface name '{}' already used in this VNFC".format(
502 vnfc
["name"], interface
["name"]),
503 httperrors
.Bad_Request
)
504 name_dict
[ interface
["name"] ] = "overlay"
505 vnfc_interfaces
[ vnfc
["name"] ] = name_dict
506 # check bood-data info
507 # if "boot-data" in vnfc:
508 # # check that user-data is incompatible with users and config-files
509 # if (vnfc["boot-data"].get("users") or vnfc["boot-data"].get("config-files")) and vnfc["boot-data"].get("user-data"):
510 # raise NfvoException(
511 # "Error at vnf:VNFC:boot-data, fields 'users' and 'config-files' are not compatible with 'user-data'",
512 # httperrors.Bad_Request)
514 #check if the info in external_connections matches with the one in the vnfcs
516 for external_connection
in vnf_descriptor
["vnf"].get("external-connections",() ):
517 if external_connection
["name"] in name_list
:
519 "Error at vnf:external-connections:name, value '{}' already used as an external-connection".format(
520 external_connection
["name"]),
521 httperrors
.Bad_Request
)
522 name_list
.append(external_connection
["name"])
523 if external_connection
["VNFC"] not in vnfc_interfaces
:
525 "Error at vnf:external-connections[name:'{}']:VNFC, value '{}' does not match any VNFC".format(
526 external_connection
["name"], external_connection
["VNFC"]),
527 httperrors
.Bad_Request
)
529 if external_connection
["local_iface_name"] not in vnfc_interfaces
[ external_connection
["VNFC"] ]:
531 "Error at vnf:external-connections[name:'{}']:local_iface_name, value '{}' does not match any interface of this VNFC".format(
532 external_connection
["name"],
533 external_connection
["local_iface_name"]),
534 httperrors
.Bad_Request
)
536 #check if the info in internal_connections matches with the one in the vnfcs
538 for internal_connection
in vnf_descriptor
["vnf"].get("internal-connections",() ):
539 if internal_connection
["name"] in name_list
:
541 "Error at vnf:internal-connections:name, value '%s' already used as an internal-connection".format(
542 internal_connection
["name"]),
543 httperrors
.Bad_Request
)
544 name_list
.append(internal_connection
["name"])
545 #We should check that internal-connections of type "ptp" have only 2 elements
547 if len(internal_connection
["elements"])>2 and (internal_connection
.get("type") == "ptp" or internal_connection
.get("type") == "e-line"):
549 "Error at 'vnf:internal-connections[name:'{}']:elements', size must be 2 for a '{}' type. Consider change it to '{}' type".format(
550 internal_connection
["name"],
551 'ptp' if vnf_descriptor_version
==1 else 'e-line',
552 'data' if vnf_descriptor_version
==1 else "e-lan"),
553 httperrors
.Bad_Request
)
554 for port
in internal_connection
["elements"]:
556 iface
= port
["local_iface_name"]
557 if vnf
not in vnfc_interfaces
:
559 "Error at vnf:internal-connections[name:'{}']:elements[]:VNFC, value '{}' does not match any VNFC".format(
560 internal_connection
["name"], vnf
),
561 httperrors
.Bad_Request
)
562 if iface
not in vnfc_interfaces
[ vnf
]:
564 "Error at vnf:internal-connections[name:'{}']:elements[]:local_iface_name, value '{}' does not match any interface of this VNFC".format(
565 internal_connection
["name"], iface
),
566 httperrors
.Bad_Request
)
567 return -httperrors
.Bad_Request
,
568 if vnf_descriptor_version
==1 and "type" not in internal_connection
:
569 if vnfc_interfaces
[vnf
][iface
] == "overlay":
570 internal_connection
["type"] = "bridge"
572 internal_connection
["type"] = "data"
573 if vnf_descriptor_version
==2 and "implementation" not in internal_connection
:
574 if vnfc_interfaces
[vnf
][iface
] == "overlay":
575 internal_connection
["implementation"] = "overlay"
577 internal_connection
["implementation"] = "underlay"
578 if (internal_connection
.get("type") == "data" or internal_connection
.get("type") == "ptp" or \
579 internal_connection
.get("implementation") == "underlay") and vnfc_interfaces
[vnf
][iface
] == "overlay":
581 "Error at vnf:internal-connections[name:'{}']:elements[]:{}, interface of type {} connected to an {} network".format(
582 internal_connection
["name"],
583 iface
, 'bridge' if vnf_descriptor_version
==1 else 'overlay',
584 'data' if vnf_descriptor_version
==1 else 'underlay'),
585 httperrors
.Bad_Request
)
586 if (internal_connection
.get("type") == "bridge" or internal_connection
.get("implementation") == "overlay") and \
587 vnfc_interfaces
[vnf
][iface
] == "underlay":
589 "Error at vnf:internal-connections[name:'{}']:elements[]:{}, interface of type {} connected to an {} network".format(
590 internal_connection
["name"], iface
,
591 'data' if vnf_descriptor_version
==1 else 'underlay',
592 'bridge' if vnf_descriptor_version
==1 else 'overlay'),
593 httperrors
.Bad_Request
)
596 def create_or_use_image(mydb
, vims
, image_dict
, rollback_list
, only_create_at_vim
=False, return_on_error
=None):
598 if only_create_at_vim
:
599 image_mano_id
= image_dict
['uuid']
600 if return_on_error
== None:
601 return_on_error
= True
603 if image_dict
['location']:
604 images
= mydb
.get_rows(FROM
="images", WHERE
={'location':image_dict
['location'], 'metadata':image_dict
['metadata']})
606 images
= mydb
.get_rows(FROM
="images", WHERE
={'universal_name':image_dict
['universal_name'], 'checksum':image_dict
['checksum']})
608 image_mano_id
= images
[0]['uuid']
610 #create image in MANO DB
611 temp_image_dict
={'name':image_dict
['name'], 'description':image_dict
.get('description',None),
612 'location':image_dict
['location'], 'metadata':image_dict
.get('metadata',None),
613 'universal_name':image_dict
['universal_name'] , 'checksum':image_dict
['checksum']
615 #temp_image_dict['location'] = image_dict.get('new_location') if image_dict['location'] is None
616 image_mano_id
= mydb
.new_row('images', temp_image_dict
, add_uuid
=True)
617 rollback_list
.append({"where":"mano", "what":"image","uuid":image_mano_id
})
618 #create image at every vim
619 for vim_id
,vim
in vims
.iteritems():
620 datacenter_vim_id
= vim
["config"]["datacenter_tenant_id"]
621 image_created
="false"
623 image_db
= mydb
.get_rows(FROM
="datacenters_images",
624 WHERE
={'datacenter_vim_id': datacenter_vim_id
, 'image_id': image_mano_id
})
625 #look at VIM if this image exist
627 if image_dict
['location'] is not None:
628 image_vim_id
= vim
.get_image_id_from_path(image_dict
['location'])
631 filter_dict
['name'] = image_dict
['universal_name']
632 if image_dict
.get('checksum') != None:
633 filter_dict
['checksum'] = image_dict
['checksum']
634 #logger.debug('>>>>>>>> Filter dict: %s', str(filter_dict))
635 vim_images
= vim
.get_image_list(filter_dict
)
636 #logger.debug('>>>>>>>> VIM images: %s', str(vim_images))
637 if len(vim_images
) > 1:
638 raise vimconn
.vimconnException("More than one candidate VIM image found for filter: {}".format(str(filter_dict
)), httperrors
.Conflict
)
639 elif len(vim_images
) == 0:
640 raise vimconn
.vimconnNotFoundException("Image not found at VIM with filter: '{}'".format(str(filter_dict
)))
642 #logger.debug('>>>>>>>> VIM image 0: %s', str(vim_images[0]))
643 image_vim_id
= vim_images
[0]['id']
645 except vimconn
.vimconnNotFoundException
as e
:
646 #Create the image in VIM only if image_dict['location'] or image_dict['new_location'] is not None
648 #image_dict['location']=image_dict.get('new_location') if image_dict['location'] is None
649 if image_dict
['location']:
650 image_vim_id
= vim
.new_image(image_dict
)
651 rollback_list
.append({"where":"vim", "vim_id": vim_id
, "what":"image","uuid":image_vim_id
})
654 #If we reach this point, then the image has image name, and optionally checksum, and could not be found
655 raise vimconn
.vimconnException(str(e
))
656 except vimconn
.vimconnException
as e
:
658 logger
.error("Error creating image at VIM '%s': %s", vim
["name"], str(e
))
661 logger
.warn("Error creating image at VIM '%s': %s", vim
["name"], str(e
))
663 except vimconn
.vimconnException
as e
:
665 logger
.error("Error contacting VIM to know if the image exists at VIM: %s", str(e
))
667 logger
.warn("Error contacting VIM to know if the image exists at VIM: %s", str(e
))
670 #if we reach here, the image has been created or existed
672 #add new vim_id at datacenters_images
673 mydb
.new_row('datacenters_images', {'datacenter_vim_id': datacenter_vim_id
,
674 'image_id':image_mano_id
,
675 'vim_id': image_vim_id
,
676 'created':image_created
})
677 elif image_db
[0]["vim_id"]!=image_vim_id
:
678 #modify existing vim_id at datacenters_images
679 mydb
.update_rows('datacenters_images', UPDATE
={'vim_id':image_vim_id
}, WHERE
={'datacenter_vim_id':vim_id
, 'image_id':image_mano_id
})
681 return image_vim_id
if only_create_at_vim
else image_mano_id
684 def create_or_use_flavor(mydb
, vims
, flavor_dict
, rollback_list
, only_create_at_vim
=False, return_on_error
= None):
685 temp_flavor_dict
= {'disk':flavor_dict
.get('disk',0),
686 'ram':flavor_dict
.get('ram'),
687 'vcpus':flavor_dict
.get('vcpus'),
689 if 'extended' in flavor_dict
and flavor_dict
['extended']==None:
690 del flavor_dict
['extended']
691 if 'extended' in flavor_dict
:
692 temp_flavor_dict
['extended']=yaml
.safe_dump(flavor_dict
['extended'],default_flow_style
=True,width
=256)
694 #look if flavor exist
695 if only_create_at_vim
:
696 flavor_mano_id
= flavor_dict
['uuid']
697 if return_on_error
== None:
698 return_on_error
= True
700 flavors
= mydb
.get_rows(FROM
="flavors", WHERE
=temp_flavor_dict
)
702 flavor_mano_id
= flavors
[0]['uuid']
705 #create one by one the images of aditional disks
706 dev_image_list
=[] #list of images
707 if 'extended' in flavor_dict
and flavor_dict
['extended']!=None:
709 for device
in flavor_dict
['extended'].get('devices',[]):
710 if "image" not in device
and "image name" not in device
:
713 image_dict
['name']=device
.get('image name',flavor_dict
['name']+str(dev_nb
)+"-img")
714 image_dict
['universal_name']=device
.get('image name')
715 image_dict
['description']=flavor_dict
['name']+str(dev_nb
)+"-img"
716 image_dict
['location']=device
.get('image')
717 #image_dict['new_location']=vnfc.get('image location')
718 image_dict
['checksum']=device
.get('image checksum')
719 image_metadata_dict
= device
.get('image metadata', None)
720 image_metadata_str
= None
721 if image_metadata_dict
!= None:
722 image_metadata_str
= yaml
.safe_dump(image_metadata_dict
,default_flow_style
=True,width
=256)
723 image_dict
['metadata']=image_metadata_str
724 image_id
= create_or_use_image(mydb
, vims
, image_dict
, rollback_list
)
725 #print "Additional disk image id for VNFC %s: %s" % (flavor_dict['name']+str(dev_nb)+"-img", image_id)
726 dev_image_list
.append(image_id
)
728 temp_flavor_dict
['name'] = flavor_dict
['name']
729 temp_flavor_dict
['description'] = flavor_dict
.get('description',None)
730 content
= mydb
.new_row('flavors', temp_flavor_dict
, add_uuid
=True)
731 flavor_mano_id
= content
732 rollback_list
.append({"where":"mano", "what":"flavor","uuid":flavor_mano_id
})
733 #create flavor at every vim
734 if 'uuid' in flavor_dict
:
735 del flavor_dict
['uuid']
737 for vim_id
,vim
in vims
.items():
738 datacenter_vim_id
= vim
["config"]["datacenter_tenant_id"]
739 flavor_created
="false"
741 flavor_db
= mydb
.get_rows(FROM
="datacenters_flavors",
742 WHERE
={'datacenter_vim_id': datacenter_vim_id
, 'flavor_id': flavor_mano_id
})
743 #look at VIM if this flavor exist SKIPPED
744 #res_vim, flavor_vim_id = vim.get_flavor_id_from_path(flavor_dict['location'])
746 # print "Error contacting VIM to know if the flavor %s existed previously." %flavor_vim_id
750 # Create the flavor in VIM
751 # Translate images at devices from MANO id to VIM id
753 if 'extended' in flavor_dict
and flavor_dict
['extended']!=None and "devices" in flavor_dict
['extended']:
754 # make a copy of original devices
757 for device
in flavor_dict
["extended"].get("devices",[]):
760 devices_original
.append(dev
)
761 if 'image' in device
:
763 if 'image metadata' in device
:
764 del device
['image metadata']
765 if 'image checksum' in device
:
766 del device
['image checksum']
768 for index
in range(0,len(devices_original
)) :
769 device
=devices_original
[index
]
770 if "image" not in device
and "image name" not in device
:
771 # if 'size' in device:
772 disk_list
.append({'size': device
.get('size', default_volume_size
), 'name': device
.get('name')})
775 image_dict
['name']=device
.get('image name',flavor_dict
['name']+str(dev_nb
)+"-img")
776 image_dict
['universal_name']=device
.get('image name')
777 image_dict
['description']=flavor_dict
['name']+str(dev_nb
)+"-img"
778 image_dict
['location']=device
.get('image')
779 # image_dict['new_location']=device.get('image location')
780 image_dict
['checksum']=device
.get('image checksum')
781 image_metadata_dict
= device
.get('image metadata', None)
782 image_metadata_str
= None
783 if image_metadata_dict
!= None:
784 image_metadata_str
= yaml
.safe_dump(image_metadata_dict
,default_flow_style
=True,width
=256)
785 image_dict
['metadata']=image_metadata_str
786 image_mano_id
=create_or_use_image(mydb
, vims
, image_dict
, rollback_list
, only_create_at_vim
=False, return_on_error
=return_on_error
)
787 image_dict
["uuid"]=image_mano_id
788 image_vim_id
=create_or_use_image(mydb
, vims
, image_dict
, rollback_list
, only_create_at_vim
=True, return_on_error
=return_on_error
)
790 #save disk information (image must be based on and size
791 disk_list
.append({'image_id': image_vim_id
, 'size': device
.get('size', default_volume_size
)})
793 flavor_dict
["extended"]["devices"][index
]['imageRef']=image_vim_id
796 #check that this vim_id exist in VIM, if not create
797 flavor_vim_id
=flavor_db
[0]["vim_id"]
799 vim
.get_flavor(flavor_vim_id
)
800 continue #flavor exist
801 except vimconn
.vimconnException
:
803 #create flavor at vim
804 logger
.debug("nfvo.create_or_use_flavor() adding flavor to VIM %s", vim
["name"])
807 flavor_vim_id
=vim
.get_flavor_id_from_data(flavor_dict
)
808 flavor_create
="false"
809 except vimconn
.vimconnException
as e
:
812 if not flavor_vim_id
:
813 flavor_vim_id
= vim
.new_flavor(flavor_dict
)
814 rollback_list
.append({"where":"vim", "vim_id": vim_id
, "what":"flavor","uuid":flavor_vim_id
})
815 flavor_created
="true"
816 except vimconn
.vimconnException
as e
:
818 logger
.error("Error creating flavor at VIM %s: %s.", vim
["name"], str(e
))
820 logger
.warn("Error creating flavor at VIM %s: %s.", vim
["name"], str(e
))
823 #if reach here the flavor has been create or exist
824 if len(flavor_db
)==0:
825 #add new vim_id at datacenters_flavors
826 extended_devices_yaml
= None
827 if len(disk_list
) > 0:
828 extended_devices
= dict()
829 extended_devices
['disks'] = disk_list
830 extended_devices_yaml
= yaml
.safe_dump(extended_devices
,default_flow_style
=True,width
=256)
831 mydb
.new_row('datacenters_flavors',
832 {'datacenter_vim_id': datacenter_vim_id
, 'flavor_id': flavor_mano_id
, 'vim_id': flavor_vim_id
,
833 'created': flavor_created
, 'extended': extended_devices_yaml
})
834 elif flavor_db
[0]["vim_id"]!=flavor_vim_id
:
835 #modify existing vim_id at datacenters_flavors
836 mydb
.update_rows('datacenters_flavors', UPDATE
={'vim_id':flavor_vim_id
},
837 WHERE
={'datacenter_vim_id': datacenter_vim_id
, 'flavor_id': flavor_mano_id
})
839 return flavor_vim_id
if only_create_at_vim
else flavor_mano_id
842 def get_str(obj
, field
, length
):
844 Obtain the str value,
849 value
= obj
.get(field
)
850 if value
is not None:
851 value
= str(value
)[:length
]
854 def _lookfor_or_create_image(db_image
, mydb
, descriptor
):
856 fill image content at db_image dictionary. Check if the image with this image and checksum exist
857 :param db_image: dictionary to insert data
858 :param mydb: database connector
859 :param descriptor: yang descriptor
860 :return: uuid if the image exist at DB, or None if a new image must be created with the data filled at db_image
863 db_image
["name"] = get_str(descriptor
, "image", 255)
864 db_image
["checksum"] = get_str(descriptor
, "image-checksum", 32)
865 if not db_image
["checksum"]: # Ensure that if empty string, None is stored
866 db_image
["checksum"] = None
867 if db_image
["name"].startswith("/"):
868 db_image
["location"] = db_image
["name"]
869 existing_images
= mydb
.get_rows(FROM
="images", WHERE
={'location': db_image
["location"]})
871 db_image
["universal_name"] = db_image
["name"]
872 existing_images
= mydb
.get_rows(FROM
="images", WHERE
={'universal_name': db_image
['universal_name'],
873 'checksum': db_image
['checksum']})
875 return existing_images
[0]["uuid"]
877 image_uuid
= str(uuid4())
878 db_image
["uuid"] = image_uuid
881 def new_vnfd_v3(mydb
, tenant_id
, vnf_descriptor
):
883 Parses an OSM IM vnfd_catalog and insert at DB
886 :param vnf_descriptor:
887 :return: The list of cretated vnf ids
890 myvnfd
= vnfd_catalog
.vnfd()
892 pybindJSONDecoder
.load_ietf_json(vnf_descriptor
, None, None, obj
=myvnfd
, path_helper
=True)
893 except Exception as e
:
894 raise NfvoException("Error. Invalid VNF descriptor format " + str(e
), httperrors
.Bad_Request
)
902 db_ip_profiles_index
= 0
906 vnfd_catalog_descriptor
= vnf_descriptor
.get("vnfd:vnfd-catalog")
907 if not vnfd_catalog_descriptor
:
908 vnfd_catalog_descriptor
= vnf_descriptor
.get("vnfd-catalog")
909 vnfd_descriptor_list
= vnfd_catalog_descriptor
.get("vnfd")
910 if not vnfd_descriptor_list
:
911 vnfd_descriptor_list
= vnfd_catalog_descriptor
.get("vnfd:vnfd")
912 for vnfd_yang
in myvnfd
.vnfd_catalog
.vnfd
.itervalues():
913 vnfd
= vnfd_yang
.get()
916 vnf_uuid
= str(uuid4())
917 uuid_list
.append(vnf_uuid
)
918 vnfd_uuid_list
.append(vnf_uuid
)
919 vnfd_id
= get_str(vnfd
, "id", 255)
923 "name": get_str(vnfd
, "name", 255),
924 "description": get_str(vnfd
, "description", 255),
925 "tenant_id": tenant_id
,
926 "vendor": get_str(vnfd
, "vendor", 255),
927 "short_name": get_str(vnfd
, "short-name", 255),
928 "descriptor": str(vnf_descriptor
)[:60000]
931 for vnfd_descriptor
in vnfd_descriptor_list
:
932 if vnfd_descriptor
["id"] == str(vnfd
["id"]):
935 # table ip_profiles (ip-profiles)
936 ip_profile_name2db_table_index
= {}
937 for ip_profile
in vnfd
.get("ip-profiles").itervalues():
939 "ip_version": str(ip_profile
["ip-profile-params"].get("ip-version", "ipv4")),
940 "subnet_address": str(ip_profile
["ip-profile-params"].get("subnet-address")),
941 "gateway_address": str(ip_profile
["ip-profile-params"].get("gateway-address")),
942 "dhcp_enabled": str(ip_profile
["ip-profile-params"]["dhcp-params"].get("enabled", True)),
943 "dhcp_start_address": str(ip_profile
["ip-profile-params"]["dhcp-params"].get("start-address")),
944 "dhcp_count": str(ip_profile
["ip-profile-params"]["dhcp-params"].get("count")),
947 for dns
in ip_profile
["ip-profile-params"]["dns-server"].itervalues():
948 dns_list
.append(str(dns
.get("address")))
949 db_ip_profile
["dns_address"] = ";".join(dns_list
)
950 if ip_profile
["ip-profile-params"].get('security-group'):
951 db_ip_profile
["security_group"] = ip_profile
["ip-profile-params"]['security-group']
952 ip_profile_name2db_table_index
[str(ip_profile
["name"])] = db_ip_profiles_index
953 db_ip_profiles_index
+= 1
954 db_ip_profiles
.append(db_ip_profile
)
956 # table nets (internal-vld)
957 net_id2uuid
= {} # for mapping interface with network
958 for vld
in vnfd
.get("internal-vld").itervalues():
959 net_uuid
= str(uuid4())
960 uuid_list
.append(net_uuid
)
962 "name": get_str(vld
, "name", 255),
965 "description": get_str(vld
, "description", 255),
966 "osm_id": get_str(vld
, "id", 255),
967 "type": "bridge", # TODO adjust depending on connection point type
969 net_id2uuid
[vld
.get("id")] = net_uuid
970 db_nets
.append(db_net
)
971 # ip-profile, link db_ip_profile with db_sce_net
972 if vld
.get("ip-profile-ref"):
973 ip_profile_name
= vld
.get("ip-profile-ref")
974 if ip_profile_name
not in ip_profile_name2db_table_index
:
975 raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{}]':'vld[{}]':'ip-profile-ref':"
976 "'{}'. Reference to a non-existing 'ip_profiles'".format(
977 str(vnfd
["id"]), str(vld
["id"]), str(vld
["ip-profile-ref"])),
978 httperrors
.Bad_Request
)
979 db_ip_profiles
[ip_profile_name2db_table_index
[ip_profile_name
]]["net_id"] = net_uuid
980 else: #check no ip-address has been defined
981 for icp
in vld
.get("internal-connection-point").itervalues():
982 if icp
.get("ip-address"):
983 raise NfvoException("Error at 'vnfd[{}]':'vld[{}]':'internal-connection-point[{}]' "
984 "contains an ip-address but no ip-profile has been defined at VLD".format(
985 str(vnfd
["id"]), str(vld
["id"]), str(icp
["id"])),
986 httperrors
.Bad_Request
)
988 # connection points vaiable declaration
989 cp_name2iface_uuid
= {}
991 cp_name2db_interface
= {}
992 vdu_id2cp_name
= {} # stored only when one external connection point is presented at this VDU
996 vdu_id2db_table_index
= {}
997 for vdu
in vnfd
.get("vdu").itervalues():
999 for vdu_descriptor
in vnfd_descriptor
["vdu"]:
1000 if vdu_descriptor
["id"] == str(vdu
["id"]):
1002 vm_uuid
= str(uuid4())
1003 uuid_list
.append(vm_uuid
)
1004 vdu_id
= get_str(vdu
, "id", 255)
1008 "name": get_str(vdu
, "name", 255),
1009 "description": get_str(vdu
, "description", 255),
1010 "pdu_type": get_str(vdu
, "pdu-type", 255),
1013 vdu_id2uuid
[db_vm
["osm_id"]] = vm_uuid
1014 vdu_id2db_table_index
[db_vm
["osm_id"]] = db_vms_index
1015 if vdu
.get("count"):
1016 db_vm
["count"] = int(vdu
["count"])
1019 image_present
= False
1020 if vdu
.get("image"):
1021 image_present
= True
1023 image_uuid
= _lookfor_or_create_image(db_image
, mydb
, vdu
)
1025 image_uuid
= db_image
["uuid"]
1026 db_images
.append(db_image
)
1027 db_vm
["image_id"] = image_uuid
1028 if vdu
.get("alternative-images"):
1029 vm_alternative_images
= []
1030 for alt_image
in vdu
.get("alternative-images").itervalues():
1032 image_uuid
= _lookfor_or_create_image(db_image
, mydb
, alt_image
)
1034 image_uuid
= db_image
["uuid"]
1035 db_images
.append(db_image
)
1036 vm_alternative_images
.append({
1037 "image_id": image_uuid
,
1038 "vim_type": str(alt_image
["vim-type"]),
1039 # "universal_name": str(alt_image["image"]),
1040 # "checksum": str(alt_image["image-checksum"]) if alt_image.get("image-checksum") else None
1043 db_vm
["image_list"] = yaml
.safe_dump(vm_alternative_images
, default_flow_style
=True, width
=256)
1047 if vdu
.get("volumes"):
1048 for volume_key
in vdu
["volumes"]:
1049 volume
= vdu
["volumes"][volume_key
]
1050 if not image_present
:
1051 # Convert the first volume to vnfc.image
1052 image_present
= True
1054 image_uuid
= _lookfor_or_create_image(db_image
, mydb
, volume
)
1056 image_uuid
= db_image
["uuid"]
1057 db_images
.append(db_image
)
1058 db_vm
["image_id"] = image_uuid
1060 # Add Openmano devices
1061 device
= {"name": str(volume
.get("name"))}
1062 device
["type"] = str(volume
.get("device-type"))
1063 if volume
.get("size"):
1064 device
["size"] = int(volume
["size"])
1065 if volume
.get("image"):
1066 device
["image name"] = str(volume
["image"])
1067 if volume
.get("image-checksum"):
1068 device
["image checksum"] = str(volume
["image-checksum"])
1070 devices
.append(device
)
1074 if vdu
.get("cloud-init"):
1075 boot_data
["user-data"] = str(vdu
["cloud-init"])
1076 elif vdu
.get("cloud-init-file"):
1077 # TODO Where this file content is present???
1078 # boot_data["user-data"] = vnfd_yang.files[vdu["cloud-init-file"]]
1079 boot_data
["user-data"] = str(vdu
["cloud-init-file"])
1081 if vdu
.get("supplemental-boot-data"):
1082 if vdu
["supplemental-boot-data"].get('boot-data-drive'):
1083 boot_data
['boot-data-drive'] = True
1084 if vdu
["supplemental-boot-data"].get('config-file'):
1085 om_cfgfile_list
= list()
1086 for custom_config_file
in vdu
["supplemental-boot-data"]['config-file'].itervalues():
1087 # TODO Where this file content is present???
1088 cfg_source
= str(custom_config_file
["source"])
1089 om_cfgfile_list
.append({"dest": custom_config_file
["dest"],
1090 "content": cfg_source
})
1091 boot_data
['config-files'] = om_cfgfile_list
1093 db_vm
["boot_data"] = yaml
.safe_dump(boot_data
, default_flow_style
=True, width
=256)
1095 db_vms
.append(db_vm
)
1098 # table interfaces (internal/external interfaces)
1099 flavor_epa_interfaces
= []
1100 # for iface in chain(vdu.get("internal-interface").itervalues(), vdu.get("external-interface").itervalues()):
1101 for iface
in vdu
.get("interface").itervalues():
1102 flavor_epa_interface
= {}
1103 iface_uuid
= str(uuid4())
1104 uuid_list
.append(iface_uuid
)
1107 "internal_name": get_str(iface
, "name", 255),
1110 flavor_epa_interface
["name"] = db_interface
["internal_name"]
1111 if iface
.get("virtual-interface").get("vpci"):
1112 db_interface
["vpci"] = get_str(iface
.get("virtual-interface"), "vpci", 12)
1113 flavor_epa_interface
["vpci"] = db_interface
["vpci"]
1115 if iface
.get("virtual-interface").get("bandwidth"):
1116 bps
= int(iface
.get("virtual-interface").get("bandwidth"))
1117 db_interface
["bw"] = int(math
.ceil(bps
/1000000.0))
1118 flavor_epa_interface
["bandwidth"] = "{} Mbps".format(db_interface
["bw"])
1120 if iface
.get("virtual-interface").get("type") == "OM-MGMT":
1121 db_interface
["type"] = "mgmt"
1122 elif iface
.get("virtual-interface").get("type") in ("VIRTIO", "E1000", "PARAVIRT"):
1123 db_interface
["type"] = "bridge"
1124 db_interface
["model"] = get_str(iface
.get("virtual-interface"), "type", 12)
1125 elif iface
.get("virtual-interface").get("type") in ("SR-IOV", "PCI-PASSTHROUGH"):
1126 db_interface
["type"] = "data"
1127 db_interface
["model"] = get_str(iface
.get("virtual-interface"), "type", 12)
1128 flavor_epa_interface
["dedicated"] = "no" if iface
["virtual-interface"]["type"] == "SR-IOV" \
1130 flavor_epa_interfaces
.append(flavor_epa_interface
)
1132 raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{}]':'vdu[{}]':'interface':'virtual"
1133 "-interface':'type':'{}'. Interface type is not supported".format(
1134 vnfd_id
, vdu_id
, iface
.get("virtual-interface").get("type")),
1135 httperrors
.Bad_Request
)
1137 if iface
.get("mgmt-interface"):
1138 db_interface
["type"] = "mgmt"
1140 if iface
.get("external-connection-point-ref"):
1142 cp
= vnfd
.get("connection-point")[iface
.get("external-connection-point-ref")]
1143 db_interface
["external_name"] = get_str(cp
, "name", 255)
1144 cp_name2iface_uuid
[db_interface
["external_name"]] = iface_uuid
1145 cp_name2vm_uuid
[db_interface
["external_name"]] = vm_uuid
1146 cp_name2db_interface
[db_interface
["external_name"]] = db_interface
1147 for cp_descriptor
in vnfd_descriptor
["connection-point"]:
1148 if cp_descriptor
["name"] == db_interface
["external_name"]:
1153 if vdu_id
in vdu_id2cp_name
:
1154 vdu_id2cp_name
[vdu_id
] = None # more than two connecdtion point for this VDU
1156 vdu_id2cp_name
[vdu_id
] = db_interface
["external_name"]
1159 if str(cp_descriptor
.get("port-security-enabled")).lower() == "false":
1160 db_interface
["port_security"] = 0
1161 elif str(cp_descriptor
.get("port-security-enabled")).lower() == "true":
1162 db_interface
["port_security"] = 1
1164 raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{vnf}]':'vdu[{vdu}]':"
1165 "'interface[{iface}]':'vnfd-connection-point-ref':'{cp}' is not present"
1166 " at connection-point".format(
1167 vnf
=vnfd_id
, vdu
=vdu_id
, iface
=iface
["name"],
1168 cp
=iface
.get("vnfd-connection-point-ref")),
1169 httperrors
.Bad_Request
)
1170 elif iface
.get("internal-connection-point-ref"):
1172 for icp_descriptor
in vdu_descriptor
["internal-connection-point"]:
1173 if icp_descriptor
["id"] == str(iface
.get("internal-connection-point-ref")):
1176 raise KeyError("does not exist at vdu:internal-connection-point")
1179 for vld
in vnfd
.get("internal-vld").itervalues():
1180 for cp
in vld
.get("internal-connection-point").itervalues():
1181 if cp
.get("id-ref") == iface
.get("internal-connection-point-ref"):
1183 raise KeyError("is referenced by more than one 'internal-vld'")
1187 raise KeyError("is not referenced by any 'internal-vld'")
1189 db_interface
["net_id"] = net_id2uuid
[icp_vld
.get("id")]
1190 if str(icp_descriptor
.get("port-security-enabled")).lower() == "false":
1191 db_interface
["port_security"] = 0
1192 elif str(icp_descriptor
.get("port-security-enabled")).lower() == "true":
1193 db_interface
["port_security"] = 1
1194 if icp
.get("ip-address"):
1195 if not icp_vld
.get("ip-profile-ref"):
1197 db_interface
["ip_address"] = str(icp
.get("ip-address"))
1198 except KeyError as e
:
1199 raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{vnf}]':'vdu[{vdu}]':"
1200 "'interface[{iface}]':'internal-connection-point-ref':'{cp}'"
1202 vnf
=vnfd_id
, vdu
=vdu_id
, iface
=iface
["name"],
1203 cp
=iface
.get("internal-connection-point-ref"), msg
=str(e
)),
1204 httperrors
.Bad_Request
)
1205 if iface
.get("position"):
1206 db_interface
["created_at"] = int(iface
.get("position")) * 50
1207 if iface
.get("mac-address"):
1208 db_interface
["mac"] = str(iface
.get("mac-address"))
1209 db_interfaces
.append(db_interface
)
1213 "name": get_str(vdu
, "name", 250) + "-flv",
1214 "vcpus": int(vdu
["vm-flavor"].get("vcpu-count", 1)),
1215 "ram": int(vdu
["vm-flavor"].get("memory-mb", 1)),
1216 "disk": int(vdu
["vm-flavor"].get("storage-gb", 0)),
1218 # TODO revise the case of several numa-node-policy node
1222 extended
["devices"] = devices
1223 if flavor_epa_interfaces
:
1224 numa
["interfaces"] = flavor_epa_interfaces
1225 if vdu
.get("guest-epa"): # TODO or dedicated_int:
1226 epa_vcpu_set
= False
1227 if vdu
["guest-epa"].get("numa-node-policy"): # TODO or dedicated_int:
1228 numa_node_policy
= vdu
["guest-epa"].get("numa-node-policy")
1229 if numa_node_policy
.get("node"):
1230 numa_node
= numa_node_policy
["node"].values()[0]
1231 if numa_node
.get("num-cores"):
1232 numa
["cores"] = numa_node
["num-cores"]
1234 if numa_node
.get("paired-threads"):
1235 if numa_node
["paired-threads"].get("num-paired-threads"):
1236 numa
["paired-threads"] = int(numa_node
["paired-threads"]["num-paired-threads"])
1238 if len(numa_node
["paired-threads"].get("paired-thread-ids")):
1239 numa
["paired-threads-id"] = []
1240 for pair
in numa_node
["paired-threads"]["paired-thread-ids"].itervalues():
1241 numa
["paired-threads-id"].append(
1242 (str(pair
["thread-a"]), str(pair
["thread-b"]))
1244 if numa_node
.get("num-threads"):
1245 numa
["threads"] = int(numa_node
["num-threads"])
1247 if numa_node
.get("memory-mb"):
1248 numa
["memory"] = max(int(numa_node
["memory-mb"] / 1024), 1)
1249 if vdu
["guest-epa"].get("mempage-size"):
1250 if vdu
["guest-epa"]["mempage-size"] != "SMALL":
1251 numa
["memory"] = max(int(db_flavor
["ram"] / 1024), 1)
1252 if vdu
["guest-epa"].get("cpu-pinning-policy") and not epa_vcpu_set
:
1253 if vdu
["guest-epa"]["cpu-pinning-policy"] == "DEDICATED":
1254 if vdu
["guest-epa"].get("cpu-thread-pinning-policy") and \
1255 vdu
["guest-epa"]["cpu-thread-pinning-policy"] != "PREFER":
1256 numa
["cores"] = max(db_flavor
["vcpus"], 1)
1258 numa
["threads"] = max(db_flavor
["vcpus"], 1)
1260 extended
["numas"] = [numa
]
1262 extended_text
= yaml
.safe_dump(extended
, default_flow_style
=True, width
=256)
1263 db_flavor
["extended"] = extended_text
1264 # look if flavor exist
1265 temp_flavor_dict
= {'disk': db_flavor
.get('disk', 0),
1266 'ram': db_flavor
.get('ram'),
1267 'vcpus': db_flavor
.get('vcpus'),
1268 'extended': db_flavor
.get('extended')
1270 existing_flavors
= mydb
.get_rows(FROM
="flavors", WHERE
=temp_flavor_dict
)
1271 if existing_flavors
:
1272 flavor_uuid
= existing_flavors
[0]["uuid"]
1274 flavor_uuid
= str(uuid4())
1275 uuid_list
.append(flavor_uuid
)
1276 db_flavor
["uuid"] = flavor_uuid
1277 db_flavors
.append(db_flavor
)
1278 db_vm
["flavor_id"] = flavor_uuid
1280 # VNF affinity and antiaffinity
1281 for pg
in vnfd
.get("placement-groups").itervalues():
1282 pg_name
= get_str(pg
, "name", 255)
1283 for vdu
in pg
.get("member-vdus").itervalues():
1284 vdu_id
= get_str(vdu
, "member-vdu-ref", 255)
1285 if vdu_id
not in vdu_id2db_table_index
:
1286 raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{vnf}]':'placement-groups[{pg}]':"
1287 "'member-vdus':'{vdu}'. Reference to a non-existing vdu".format(
1288 vnf
=vnfd_id
, pg
=pg_name
, vdu
=vdu_id
),
1289 httperrors
.Bad_Request
)
1290 if vdu_id2db_table_index
[vdu_id
]:
1291 db_vms
[vdu_id2db_table_index
[vdu_id
]]["availability_zone"] = pg_name
1292 # TODO consider the case of isolation and not colocation
1293 # if pg.get("strategy") == "ISOLATION":
1295 # VNF mgmt configuration
1297 if vnfd
["mgmt-interface"].get("vdu-id"):
1298 mgmt_vdu_id
= get_str(vnfd
["mgmt-interface"], "vdu-id", 255)
1299 if mgmt_vdu_id
not in vdu_id2uuid
:
1300 raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{vnf}]':'mgmt-interface':'vdu-id':"
1301 "'{vdu}'. Reference to a non-existing vdu".format(
1302 vnf
=vnfd_id
, vdu
=mgmt_vdu_id
),
1303 httperrors
.Bad_Request
)
1304 mgmt_access
["vm_id"] = vdu_id2uuid
[vnfd
["mgmt-interface"]["vdu-id"]]
1305 # if only one cp is defined by this VDU, mark this interface as of type "mgmt"
1306 if vdu_id2cp_name
.get(mgmt_vdu_id
):
1307 if cp_name2db_interface
[vdu_id2cp_name
[mgmt_vdu_id
]]:
1308 cp_name2db_interface
[vdu_id2cp_name
[mgmt_vdu_id
]]["type"] = "mgmt"
1310 if vnfd
["mgmt-interface"].get("ip-address"):
1311 mgmt_access
["ip-address"] = str(vnfd
["mgmt-interface"].get("ip-address"))
1312 if vnfd
["mgmt-interface"].get("cp"):
1313 if vnfd
["mgmt-interface"]["cp"] not in cp_name2iface_uuid
:
1314 raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{vnf}]':'mgmt-interface':'cp'['{cp}']. "
1315 "Reference to a non-existing connection-point".format(
1316 vnf
=vnfd_id
, cp
=vnfd
["mgmt-interface"]["cp"]),
1317 httperrors
.Bad_Request
)
1318 mgmt_access
["vm_id"] = cp_name2vm_uuid
[vnfd
["mgmt-interface"]["cp"]]
1319 mgmt_access
["interface_id"] = cp_name2iface_uuid
[vnfd
["mgmt-interface"]["cp"]]
1320 # mark this interface as of type mgmt
1321 if cp_name2db_interface
[vnfd
["mgmt-interface"]["cp"]]:
1322 cp_name2db_interface
[vnfd
["mgmt-interface"]["cp"]]["type"] = "mgmt"
1324 default_user
= get_str(vnfd
.get("vnf-configuration", {}).get("config-access", {}).get("ssh-access", {}),
1328 mgmt_access
["default_user"] = default_user
1329 required
= get_str(vnfd
.get("vnf-configuration", {}).get("config-access", {}).get("ssh-access", {}),
1332 mgmt_access
["required"] = required
1335 db_vnf
["mgmt_access"] = yaml
.safe_dump(mgmt_access
, default_flow_style
=True, width
=256)
1337 db_vnfs
.append(db_vnf
)
1341 {"images": db_images
},
1342 {"flavors": db_flavors
},
1343 {"ip_profiles": db_ip_profiles
},
1345 {"interfaces": db_interfaces
},
1348 logger
.debug("create_vnf Deployment done vnfDict: %s",
1349 yaml
.safe_dump(db_tables
, indent
=4, default_flow_style
=False) )
1350 mydb
.new_rows(db_tables
, uuid_list
)
1351 return vnfd_uuid_list
1352 except NfvoException
:
1354 except Exception as e
:
1355 logger
.error("Exception {}".format(e
))
1356 raise # NfvoException("Exception {}".format(e), httperrors.Bad_Request)
1359 @deprecated("Use new_vnfd_v3")
1360 def new_vnf(mydb
, tenant_id
, vnf_descriptor
):
1361 global global_config
1363 # Step 1. Check the VNF descriptor
1364 check_vnf_descriptor(vnf_descriptor
, vnf_descriptor_version
=1)
1365 # Step 2. Check tenant exist
1367 if tenant_id
!= "any":
1368 check_tenant(mydb
, tenant_id
)
1369 if "tenant_id" in vnf_descriptor
["vnf"]:
1370 if vnf_descriptor
["vnf"]["tenant_id"] != tenant_id
:
1371 raise NfvoException("VNF can not have a different tenant owner '{}', must be '{}'".format(vnf_descriptor
["vnf"]["tenant_id"], tenant_id
),
1372 httperrors
.Unauthorized
)
1374 vnf_descriptor
['vnf']['tenant_id'] = tenant_id
1375 # Step 3. Get the URL of the VIM from the nfvo_tenant and the datacenter
1376 if global_config
["auto_push_VNF_to_VIMs"]:
1377 vims
= get_vim(mydb
, tenant_id
, ignore_errors
=True)
1379 # Step 4. Review the descriptor and add missing fields
1380 #print vnf_descriptor
1381 #logger.debug("Refactoring VNF descriptor with fields: description, public (default: true)")
1382 vnf_name
= vnf_descriptor
['vnf']['name']
1383 vnf_descriptor
['vnf']['description'] = vnf_descriptor
['vnf'].get("description", vnf_name
)
1384 if "physical" in vnf_descriptor
['vnf']:
1385 del vnf_descriptor
['vnf']['physical']
1386 #print vnf_descriptor
1388 # Step 6. For each VNFC in the descriptor, flavors and images are created in the VIM
1389 logger
.debug('BEGIN creation of VNF "%s"' % vnf_name
)
1390 logger
.debug("VNF %s: consisting of %d VNFC(s)" % (vnf_name
,len(vnf_descriptor
['vnf']['VNFC'])))
1392 #For each VNFC, we add it to the VNFCDict and we create a flavor.
1393 VNFCDict
= {} # Dictionary, key: VNFC name, value: dict with the relevant information to create the VNF and VMs in the MANO database
1394 rollback_list
= [] # It will contain the new images created in mano. It is used for rollback
1396 logger
.debug("Creating additional disk images and new flavors in the VIM for each VNFC")
1397 for vnfc
in vnf_descriptor
['vnf']['VNFC']:
1399 VNFCitem
["name"] = vnfc
['name']
1400 VNFCitem
["availability_zone"] = vnfc
.get('availability_zone')
1401 VNFCitem
["description"] = vnfc
.get("description", 'VM %s of the VNF %s' %(vnfc
['name'],vnf_name
))
1403 #print "Flavor name: %s. Description: %s" % (VNFCitem["name"]+"-flv", VNFCitem["description"])
1406 myflavorDict
["name"] = vnfc
['name']+"-flv" #Maybe we could rename the flavor by using the field "image name" if exists
1407 myflavorDict
["description"] = VNFCitem
["description"]
1408 myflavorDict
["ram"] = vnfc
.get("ram", 0)
1409 myflavorDict
["vcpus"] = vnfc
.get("vcpus", 0)
1410 myflavorDict
["disk"] = vnfc
.get("disk", 0)
1411 myflavorDict
["extended"] = {}
1413 devices
= vnfc
.get("devices")
1415 myflavorDict
["extended"]["devices"] = devices
1418 # 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
1419 # Another option is that the processor in the VNF descriptor specifies directly the ranking of the host
1421 # Previous code has been commented
1422 #if vnfc['processor']['model'] == "Intel(R) Xeon(R) CPU E5-4620 0 @ 2.20GHz" :
1423 # myflavorDict["flavor"]['extended']['processor_ranking'] = 200
1424 #elif vnfc['processor']['model'] == "Intel(R) Xeon(R) CPU E5-2697 v2 @ 2.70GHz" :
1425 # myflavorDict["flavor"]['extended']['processor_ranking'] = 300
1427 # result2, message = rollback(myvim, myvimURL, myvim_tenant, flavorList, imageList)
1429 # print "Error creating flavor: unknown processor model. Rollback successful."
1430 # return -httperrors.Bad_Request, "Error creating flavor: unknown processor model. Rollback successful."
1432 # return -httperrors.Bad_Request, "Error creating flavor: unknown processor model. Rollback fail: you need to access VIM and delete the following %s" % message
1433 myflavorDict
['extended']['processor_ranking'] = 100 #Hardcoded value, while we decide when the mapping is done
1435 if 'numas' in vnfc
and len(vnfc
['numas'])>0:
1436 myflavorDict
['extended']['numas'] = vnfc
['numas']
1440 # Step 6.2 New flavors are created in the VIM
1441 flavor_id
= create_or_use_flavor(mydb
, vims
, myflavorDict
, rollback_list
)
1443 #print "Flavor id for VNFC %s: %s" % (vnfc['name'],flavor_id)
1444 VNFCitem
["flavor_id"] = flavor_id
1445 VNFCDict
[vnfc
['name']] = VNFCitem
1447 logger
.debug("Creating new images in the VIM for each VNFC")
1448 # Step 6.3 New images are created in the VIM
1449 #For each VNFC, we must create the appropriate image.
1450 #This "for" loop might be integrated with the previous one
1451 #In case this integration is made, the VNFCDict might become a VNFClist.
1452 for vnfc
in vnf_descriptor
['vnf']['VNFC']:
1453 #print "Image name: %s. Description: %s" % (vnfc['name']+"-img", VNFCDict[vnfc['name']]['description'])
1455 image_dict
['name']=vnfc
.get('image name',vnf_name
+"-"+vnfc
['name']+"-img")
1456 image_dict
['universal_name']=vnfc
.get('image name')
1457 image_dict
['description']=vnfc
.get('image name', VNFCDict
[vnfc
['name']]['description'])
1458 image_dict
['location']=vnfc
.get('VNFC image')
1459 #image_dict['new_location']=vnfc.get('image location')
1460 image_dict
['checksum']=vnfc
.get('image checksum')
1461 image_metadata_dict
= vnfc
.get('image metadata', None)
1462 image_metadata_str
= None
1463 if image_metadata_dict
is not None:
1464 image_metadata_str
= yaml
.safe_dump(image_metadata_dict
,default_flow_style
=True,width
=256)
1465 image_dict
['metadata']=image_metadata_str
1466 #print "create_or_use_image", mydb, vims, image_dict, rollback_list
1467 image_id
= create_or_use_image(mydb
, vims
, image_dict
, rollback_list
)
1468 #print "Image id for VNFC %s: %s" % (vnfc['name'],image_id)
1469 VNFCDict
[vnfc
['name']]["image_id"] = image_id
1470 VNFCDict
[vnfc
['name']]["image_path"] = vnfc
.get('VNFC image')
1471 VNFCDict
[vnfc
['name']]["count"] = vnfc
.get('count', 1)
1472 if vnfc
.get("boot-data"):
1473 VNFCDict
[vnfc
['name']]["boot_data"] = yaml
.safe_dump(vnfc
["boot-data"], default_flow_style
=True, width
=256)
1476 # Step 7. Storing the VNF descriptor in the repository
1477 if "descriptor" not in vnf_descriptor
["vnf"]:
1478 vnf_descriptor
["vnf"]["descriptor"] = yaml
.safe_dump(vnf_descriptor
, indent
=4, explicit_start
=True, default_flow_style
=False)
1480 # Step 8. Adding the VNF to the NFVO DB
1481 vnf_id
= mydb
.new_vnf_as_a_whole(tenant_id
,vnf_name
,vnf_descriptor
,VNFCDict
)
1483 except (db_base_Exception
, vimconn
.vimconnException
, KeyError) as e
:
1484 _
, message
= rollback(mydb
, vims
, rollback_list
)
1485 if isinstance(e
, db_base_Exception
):
1486 error_text
= "Exception at database"
1487 elif isinstance(e
, KeyError):
1488 error_text
= "KeyError exception "
1489 e
.http_code
= httperrors
.Internal_Server_Error
1491 error_text
= "Exception at VIM"
1492 error_text
+= " {} {}. {}".format(type(e
).__name
__, str(e
), message
)
1493 #logger.error("start_scenario %s", error_text)
1494 raise NfvoException(error_text
, e
.http_code
)
1497 @deprecated("Use new_vnfd_v3")
1498 def new_vnf_v02(mydb
, tenant_id
, vnf_descriptor
):
1499 global global_config
1501 # Step 1. Check the VNF descriptor
1502 check_vnf_descriptor(vnf_descriptor
, vnf_descriptor_version
=2)
1503 # Step 2. Check tenant exist
1505 if tenant_id
!= "any":
1506 check_tenant(mydb
, tenant_id
)
1507 if "tenant_id" in vnf_descriptor
["vnf"]:
1508 if vnf_descriptor
["vnf"]["tenant_id"] != tenant_id
:
1509 raise NfvoException("VNF can not have a different tenant owner '{}', must be '{}'".format(vnf_descriptor
["vnf"]["tenant_id"], tenant_id
),
1510 httperrors
.Unauthorized
)
1512 vnf_descriptor
['vnf']['tenant_id'] = tenant_id
1513 # Step 3. Get the URL of the VIM from the nfvo_tenant and the datacenter
1514 if global_config
["auto_push_VNF_to_VIMs"]:
1515 vims
= get_vim(mydb
, tenant_id
, ignore_errors
=True)
1517 # Step 4. Review the descriptor and add missing fields
1518 #print vnf_descriptor
1519 #logger.debug("Refactoring VNF descriptor with fields: description, public (default: true)")
1520 vnf_name
= vnf_descriptor
['vnf']['name']
1521 vnf_descriptor
['vnf']['description'] = vnf_descriptor
['vnf'].get("description", vnf_name
)
1522 if "physical" in vnf_descriptor
['vnf']:
1523 del vnf_descriptor
['vnf']['physical']
1524 #print vnf_descriptor
1526 # Step 6. For each VNFC in the descriptor, flavors and images are created in the VIM
1527 logger
.debug('BEGIN creation of VNF "%s"' % vnf_name
)
1528 logger
.debug("VNF %s: consisting of %d VNFC(s)" % (vnf_name
,len(vnf_descriptor
['vnf']['VNFC'])))
1530 #For each VNFC, we add it to the VNFCDict and we create a flavor.
1531 VNFCDict
= {} # Dictionary, key: VNFC name, value: dict with the relevant information to create the VNF and VMs in the MANO database
1532 rollback_list
= [] # It will contain the new images created in mano. It is used for rollback
1534 logger
.debug("Creating additional disk images and new flavors in the VIM for each VNFC")
1535 for vnfc
in vnf_descriptor
['vnf']['VNFC']:
1537 VNFCitem
["name"] = vnfc
['name']
1538 VNFCitem
["description"] = vnfc
.get("description", 'VM %s of the VNF %s' %(vnfc
['name'],vnf_name
))
1540 #print "Flavor name: %s. Description: %s" % (VNFCitem["name"]+"-flv", VNFCitem["description"])
1543 myflavorDict
["name"] = vnfc
['name']+"-flv" #Maybe we could rename the flavor by using the field "image name" if exists
1544 myflavorDict
["description"] = VNFCitem
["description"]
1545 myflavorDict
["ram"] = vnfc
.get("ram", 0)
1546 myflavorDict
["vcpus"] = vnfc
.get("vcpus", 0)
1547 myflavorDict
["disk"] = vnfc
.get("disk", 0)
1548 myflavorDict
["extended"] = {}
1550 devices
= vnfc
.get("devices")
1552 myflavorDict
["extended"]["devices"] = devices
1555 # 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
1556 # Another option is that the processor in the VNF descriptor specifies directly the ranking of the host
1558 # Previous code has been commented
1559 #if vnfc['processor']['model'] == "Intel(R) Xeon(R) CPU E5-4620 0 @ 2.20GHz" :
1560 # myflavorDict["flavor"]['extended']['processor_ranking'] = 200
1561 #elif vnfc['processor']['model'] == "Intel(R) Xeon(R) CPU E5-2697 v2 @ 2.70GHz" :
1562 # myflavorDict["flavor"]['extended']['processor_ranking'] = 300
1564 # result2, message = rollback(myvim, myvimURL, myvim_tenant, flavorList, imageList)
1566 # print "Error creating flavor: unknown processor model. Rollback successful."
1567 # return -httperrors.Bad_Request, "Error creating flavor: unknown processor model. Rollback successful."
1569 # return -httperrors.Bad_Request, "Error creating flavor: unknown processor model. Rollback fail: you need to access VIM and delete the following %s" % message
1570 myflavorDict
['extended']['processor_ranking'] = 100 #Hardcoded value, while we decide when the mapping is done
1572 if 'numas' in vnfc
and len(vnfc
['numas'])>0:
1573 myflavorDict
['extended']['numas'] = vnfc
['numas']
1577 # Step 6.2 New flavors are created in the VIM
1578 flavor_id
= create_or_use_flavor(mydb
, vims
, myflavorDict
, rollback_list
)
1580 #print "Flavor id for VNFC %s: %s" % (vnfc['name'],flavor_id)
1581 VNFCitem
["flavor_id"] = flavor_id
1582 VNFCDict
[vnfc
['name']] = VNFCitem
1584 logger
.debug("Creating new images in the VIM for each VNFC")
1585 # Step 6.3 New images are created in the VIM
1586 #For each VNFC, we must create the appropriate image.
1587 #This "for" loop might be integrated with the previous one
1588 #In case this integration is made, the VNFCDict might become a VNFClist.
1589 for vnfc
in vnf_descriptor
['vnf']['VNFC']:
1590 #print "Image name: %s. Description: %s" % (vnfc['name']+"-img", VNFCDict[vnfc['name']]['description'])
1592 image_dict
['name']=vnfc
.get('image name',vnf_name
+"-"+vnfc
['name']+"-img")
1593 image_dict
['universal_name']=vnfc
.get('image name')
1594 image_dict
['description']=vnfc
.get('image name', VNFCDict
[vnfc
['name']]['description'])
1595 image_dict
['location']=vnfc
.get('VNFC image')
1596 #image_dict['new_location']=vnfc.get('image location')
1597 image_dict
['checksum']=vnfc
.get('image checksum')
1598 image_metadata_dict
= vnfc
.get('image metadata', None)
1599 image_metadata_str
= None
1600 if image_metadata_dict
is not None:
1601 image_metadata_str
= yaml
.safe_dump(image_metadata_dict
,default_flow_style
=True,width
=256)
1602 image_dict
['metadata']=image_metadata_str
1603 #print "create_or_use_image", mydb, vims, image_dict, rollback_list
1604 image_id
= create_or_use_image(mydb
, vims
, image_dict
, rollback_list
)
1605 #print "Image id for VNFC %s: %s" % (vnfc['name'],image_id)
1606 VNFCDict
[vnfc
['name']]["image_id"] = image_id
1607 VNFCDict
[vnfc
['name']]["image_path"] = vnfc
.get('VNFC image')
1608 VNFCDict
[vnfc
['name']]["count"] = vnfc
.get('count', 1)
1609 if vnfc
.get("boot-data"):
1610 VNFCDict
[vnfc
['name']]["boot_data"] = yaml
.safe_dump(vnfc
["boot-data"], default_flow_style
=True, width
=256)
1612 # Step 7. Storing the VNF descriptor in the repository
1613 if "descriptor" not in vnf_descriptor
["vnf"]:
1614 vnf_descriptor
["vnf"]["descriptor"] = yaml
.safe_dump(vnf_descriptor
, indent
=4, explicit_start
=True, default_flow_style
=False)
1616 # Step 8. Adding the VNF to the NFVO DB
1617 vnf_id
= mydb
.new_vnf_as_a_whole2(tenant_id
,vnf_name
,vnf_descriptor
,VNFCDict
)
1619 except (db_base_Exception
, vimconn
.vimconnException
, KeyError) as e
:
1620 _
, message
= rollback(mydb
, vims
, rollback_list
)
1621 if isinstance(e
, db_base_Exception
):
1622 error_text
= "Exception at database"
1623 elif isinstance(e
, KeyError):
1624 error_text
= "KeyError exception "
1625 e
.http_code
= httperrors
.Internal_Server_Error
1627 error_text
= "Exception at VIM"
1628 error_text
+= " {} {}. {}".format(type(e
).__name
__, str(e
), message
)
1629 #logger.error("start_scenario %s", error_text)
1630 raise NfvoException(error_text
, e
.http_code
)
1633 def get_vnf_id(mydb
, tenant_id
, vnf_id
):
1634 #check valid tenant_id
1635 check_tenant(mydb
, tenant_id
)
1638 if tenant_id
!= "any":
1639 where_or
["tenant_id"] = tenant_id
1640 where_or
["public"] = True
1641 vnf
= mydb
.get_table_by_uuid_name('vnfs', vnf_id
, "VNF", WHERE_OR
=where_or
, WHERE_AND_OR
="AND")
1643 vnf_id
= vnf
["uuid"]
1644 filter_keys
= ('uuid', 'name', 'description', 'public', "tenant_id", "osm_id", "created_at")
1645 filtered_content
= dict( (k
,v
) for k
,v
in vnf
.iteritems() if k
in filter_keys
)
1646 #change_keys_http2db(filtered_content, http2db_vnf, reverse=True)
1647 data
={'vnf' : filtered_content
}
1649 content
= mydb
.get_rows(FROM
='vnfs join vms on vnfs.uuid=vms.vnf_id',
1650 SELECT
=('vms.uuid as uuid', 'vms.osm_id as osm_id', 'vms.name as name', 'vms.description as description',
1652 WHERE
={'vnfs.uuid': vnf_id
} )
1653 if len(content
) != 0:
1654 #raise NfvoException("vnf '{}' not found".format(vnf_id), httperrors.Not_Found)
1655 # change boot_data into boot-data
1657 if vm
.get("boot_data"):
1658 vm
["boot-data"] = yaml
.safe_load(vm
["boot_data"])
1661 data
['vnf']['VNFC'] = content
1662 #TODO: GET all the information from a VNFC and include it in the output.
1665 content
= mydb
.get_rows(FROM
='vnfs join nets on vnfs.uuid=nets.vnf_id',
1666 SELECT
=('nets.uuid as uuid','nets.name as name','nets.description as description', 'nets.type as type', 'nets.multipoint as multipoint'),
1667 WHERE
={'vnfs.uuid': vnf_id
} )
1668 data
['vnf']['nets'] = content
1670 #GET ip-profile for each net
1671 for net
in data
['vnf']['nets']:
1672 ipprofiles
= mydb
.get_rows(FROM
='ip_profiles',
1673 SELECT
=('ip_version','subnet_address','gateway_address','dns_address','dhcp_enabled','dhcp_start_address','dhcp_count'),
1674 WHERE
={'net_id': net
["uuid"]} )
1675 if len(ipprofiles
)==1:
1676 net
["ip_profile"] = ipprofiles
[0]
1677 elif len(ipprofiles
)>1:
1678 raise NfvoException("More than one ip-profile found with this criteria: net_id='{}'".format(net
['uuid']), httperrors
.Bad_Request
)
1681 #TODO: For each net, GET its elements and relevant info per element (VNFC, iface, ip_address) and include them in the output.
1683 #GET External Interfaces
1684 content
= mydb
.get_rows(FROM
='vnfs join vms on vnfs.uuid=vms.vnf_id join interfaces on vms.uuid=interfaces.vm_id',\
1685 SELECT
=('interfaces.uuid as uuid','interfaces.external_name as external_name', 'vms.name as vm_name', 'interfaces.vm_id as vm_id', \
1686 'interfaces.internal_name as internal_name', 'interfaces.type as type', 'interfaces.vpci as vpci','interfaces.bw as bw'),\
1687 WHERE
={'vnfs.uuid': vnf_id
, 'interfaces.external_name<>': None} )
1689 data
['vnf']['external-connections'] = content
1694 def delete_vnf(mydb
,tenant_id
,vnf_id
,datacenter
=None,vim_tenant
=None):
1695 # Check tenant exist
1696 if tenant_id
!= "any":
1697 check_tenant(mydb
, tenant_id
)
1698 # Get the URL of the VIM from the nfvo_tenant and the datacenter
1699 vims
= get_vim(mydb
, tenant_id
, ignore_errors
=True)
1703 # Checking if it is a valid uuid and, if not, getting the uuid assuming that the name was provided"
1705 if tenant_id
!= "any":
1706 where_or
["tenant_id"] = tenant_id
1707 where_or
["public"] = True
1708 vnf
= mydb
.get_table_by_uuid_name('vnfs', vnf_id
, "VNF", WHERE_OR
=where_or
, WHERE_AND_OR
="AND")
1709 vnf_id
= vnf
["uuid"]
1711 # "Getting the list of flavors and tenants of the VNF"
1712 flavorList
= get_flavorlist(mydb
, vnf_id
)
1713 if len(flavorList
)==0:
1714 logger
.warn("delete_vnf error. No flavors found for the VNF id '%s'", vnf_id
)
1716 imageList
= get_imagelist(mydb
, vnf_id
)
1717 if len(imageList
)==0:
1718 logger
.warn( "delete_vnf error. No images found for the VNF id '%s'", vnf_id
)
1720 deleted
= mydb
.delete_row_by_id('vnfs', vnf_id
)
1722 raise NfvoException("vnf '{}' not found".format(vnf_id
), httperrors
.Not_Found
)
1725 for flavor
in flavorList
:
1726 #check if flavor is used by other vnf
1728 c
= mydb
.get_rows(FROM
='vms', WHERE
={'flavor_id':flavor
} )
1730 logger
.debug("Flavor '%s' not deleted because it is being used by another VNF", flavor
)
1732 #flavor not used, must be deleted
1734 c
= mydb
.get_rows(FROM
='datacenters_flavors', WHERE
={'flavor_id': flavor
})
1735 for flavor_vim
in c
:
1736 if not flavor_vim
['created']: # skip this flavor because not created by openmano
1740 for vim
in vims
.values():
1741 if vim
["config"]["datacenter_tenant_id"] == flavor_vim
["datacenter_vim_id"]:
1747 myvim
.delete_flavor(flavor_vim
["vim_id"])
1748 except vimconn
.vimconnNotFoundException
:
1749 logger
.warn("VIM flavor %s not exist at datacenter %s", flavor_vim
["vim_id"],
1750 flavor_vim
["datacenter_vim_id"] )
1751 except vimconn
.vimconnException
as e
:
1752 logger
.error("Not possible to delete VIM flavor %s from datacenter %s: %s %s",
1753 flavor_vim
["vim_id"], flavor_vim
["datacenter_vim_id"], type(e
).__name
__, str(e
))
1754 undeletedItems
.append("flavor {} from VIM {}".format(flavor_vim
["vim_id"],
1755 flavor_vim
["datacenter_vim_id"]))
1756 # delete flavor from Database, using table flavors and with cascade foreign key also at datacenters_flavors
1757 mydb
.delete_row_by_id('flavors', flavor
)
1758 except db_base_Exception
as e
:
1759 logger
.error("delete_vnf_error. Not possible to get flavor details and delete '%s'. %s", flavor
, str(e
))
1760 undeletedItems
.append("flavor {}".format(flavor
))
1763 for image
in imageList
:
1765 #check if image is used by other vnf
1766 c
= mydb
.get_rows(FROM
='vms', WHERE
=[{'image_id': image
}, {'image_list LIKE ': '%' + image
+ '%'}])
1768 logger
.debug("Image '%s' not deleted because it is being used by another VNF", image
)
1770 #image not used, must be deleted
1772 c
= mydb
.get_rows(FROM
='datacenters_images', WHERE
={'image_id':image
})
1774 if image_vim
["datacenter_vim_id"] not in vims
: # TODO change to datacenter_tenant_id
1776 if image_vim
['created']=='false': #skip this image because not created by openmano
1778 myvim
=vims
[ image_vim
["datacenter_id"] ]
1780 myvim
.delete_image(image_vim
["vim_id"])
1781 except vimconn
.vimconnNotFoundException
as e
:
1782 logger
.warn("VIM image %s not exist at datacenter %s", image_vim
["vim_id"], image_vim
["datacenter_id"] )
1783 except vimconn
.vimconnException
as e
:
1784 logger
.error("Not possible to delete VIM image %s from datacenter %s: %s %s",
1785 image_vim
["vim_id"], image_vim
["datacenter_id"], type(e
).__name
__, str(e
))
1786 undeletedItems
.append("image {} from VIM {}".format(image_vim
["vim_id"], image_vim
["datacenter_id"] ))
1787 #delete image from Database, using table images and with cascade foreign key also at datacenters_images
1788 mydb
.delete_row_by_id('images', image
)
1789 except db_base_Exception
as e
:
1790 logger
.error("delete_vnf_error. Not possible to get image details and delete '%s'. %s", image
, str(e
))
1791 undeletedItems
.append("image %s" % image
)
1793 return vnf_id
+ " " + vnf
["name"]
1795 # return "delete_vnf. Undeleted: %s" %(undeletedItems)
1798 @deprecated("Not used")
1799 def get_hosts_info(mydb
, nfvo_tenant_id
, datacenter_name
=None):
1800 result
, vims
= get_vim(mydb
, nfvo_tenant_id
, None, datacenter_name
)
1804 return -httperrors
.Not_Found
, "datacenter '%s' not found" % datacenter_name
1805 myvim
= vims
.values()[0]
1806 result
,servers
= myvim
.get_hosts_info()
1808 return result
, servers
1809 topology
= {'name':myvim
['name'] , 'servers': servers
}
1810 return result
, topology
1813 def get_hosts(mydb
, nfvo_tenant_id
):
1814 vims
= get_vim(mydb
, nfvo_tenant_id
)
1816 raise NfvoException("No datacenter found for tenant '{}'".format(str(nfvo_tenant_id
)), httperrors
.Not_Found
)
1818 #print "nfvo.datacenter_action() error. Several datacenters found"
1819 raise NfvoException("More than one datacenters found, try to identify with uuid", httperrors
.Conflict
)
1820 myvim
= vims
.values()[0]
1822 hosts
= myvim
.get_hosts()
1823 logger
.debug('VIM hosts response: '+ yaml
.safe_dump(hosts
, indent
=4, default_flow_style
=False))
1825 datacenter
= {'Datacenters': [ {'name':myvim
['name'],'servers':[]} ] }
1827 server
={'name':host
['name'], 'vms':[]}
1828 for vm
in host
['instances']:
1829 #get internal name and model
1831 c
= mydb
.get_rows(SELECT
=('name',), FROM
='instance_vms as iv join vms on iv.vm_id=vms.uuid',\
1832 WHERE
={'vim_vm_id':vm
['id']} )
1834 logger
.warn("nfvo.get_hosts virtual machine at VIM '{}' not found at tidnfvo".format(vm
['id']))
1836 server
['vms'].append( {'name':vm
['name'] , 'model':c
[0]['name']} )
1838 except db_base_Exception
as e
:
1839 logger
.warn("nfvo.get_hosts virtual machine at VIM '{}' error {}".format(vm
['id'], str(e
)))
1840 datacenter
['Datacenters'][0]['servers'].append(server
)
1841 #return -400, "en construccion"
1843 #print 'datacenters '+ json.dumps(datacenter, indent=4)
1845 except vimconn
.vimconnException
as e
:
1846 raise NfvoException("Not possible to get_host_list from VIM: {}".format(str(e
)), e
.http_code
)
1849 @deprecated("Use new_nsd_v3")
1850 def new_scenario(mydb
, tenant_id
, topo
):
1852 # result, vims = get_vim(mydb, tenant_id)
1854 # return result, vims
1856 if tenant_id
!= "any":
1857 check_tenant(mydb
, tenant_id
)
1858 if "tenant_id" in topo
:
1859 if topo
["tenant_id"] != tenant_id
:
1860 raise NfvoException("VNF can not have a different tenant owner '{}', must be '{}'".format(topo
["tenant_id"], tenant_id
),
1861 httperrors
.Unauthorized
)
1865 #1.1: get VNFs and external_networks (other_nets).
1867 other_nets
={} #external_networks, bridge_networks and data_networkds
1868 nodes
= topo
['topology']['nodes']
1869 for k
in nodes
.keys():
1870 if nodes
[k
]['type'] == 'VNF':
1872 vnfs
[k
]['ifaces'] = {}
1873 elif nodes
[k
]['type'] == 'other_network' or nodes
[k
]['type'] == 'external_network':
1874 other_nets
[k
] = nodes
[k
]
1875 other_nets
[k
]['external']=True
1876 elif nodes
[k
]['type'] == 'network':
1877 other_nets
[k
] = nodes
[k
]
1878 other_nets
[k
]['external']=False
1881 #1.2: Check that VNF are present at database table vnfs. Insert uuid, description and external interfaces
1882 for name
,vnf
in vnfs
.items():
1883 where
= {"OR": {"tenant_id": tenant_id
, 'public': "true"}}
1885 error_pos
= "'topology':'nodes':'" + name
+ "'"
1887 error_text
+= " 'vnf_id' " + vnf
['vnf_id']
1888 where
['uuid'] = vnf
['vnf_id']
1889 if 'VNF model' in vnf
:
1890 error_text
+= " 'VNF model' " + vnf
['VNF model']
1891 where
['name'] = vnf
['VNF model']
1893 raise NfvoException("Descriptor need a 'vnf_id' or 'VNF model' field at " + error_pos
, httperrors
.Bad_Request
)
1895 vnf_db
= mydb
.get_rows(SELECT
=('uuid','name','description'),
1899 raise NfvoException("unknown" + error_text
+ " at " + error_pos
, httperrors
.Not_Found
)
1901 raise NfvoException("more than one" + error_text
+ " at " + error_pos
+ " Concrete with 'vnf_id'", httperrors
.Conflict
)
1902 vnf
['uuid']=vnf_db
[0]['uuid']
1903 vnf
['description']=vnf_db
[0]['description']
1904 #get external interfaces
1905 ext_ifaces
= mydb
.get_rows(SELECT
=('external_name as name','i.uuid as iface_uuid', 'i.type as type'),
1906 FROM
='vnfs join vms on vnfs.uuid=vms.vnf_id join interfaces as i on vms.uuid=i.vm_id',
1907 WHERE
={'vnfs.uuid':vnf
['uuid'], 'external_name<>': None} )
1908 for ext_iface
in ext_ifaces
:
1909 vnf
['ifaces'][ ext_iface
['name'] ] = {'uuid':ext_iface
['iface_uuid'], 'type':ext_iface
['type']}
1911 #1.4 get list of connections
1912 conections
= topo
['topology']['connections']
1913 conections_list
= []
1914 conections_list_name
= []
1915 for k
in conections
.keys():
1916 if type(conections
[k
]['nodes'])==dict: #dict with node:iface pairs
1917 ifaces_list
= conections
[k
]['nodes'].items()
1918 elif type(conections
[k
]['nodes'])==list: #list with dictionary
1920 conection_pair_list
= map(lambda x
: x
.items(), conections
[k
]['nodes'] )
1921 for k2
in conection_pair_list
:
1924 con_type
= conections
[k
].get("type", "link")
1925 if con_type
!= "link":
1927 raise NfvoException("Format error. Reapeted network name at 'topology':'connections':'{}'".format(str(k
)), httperrors
.Bad_Request
)
1928 other_nets
[k
] = {'external': False}
1929 if conections
[k
].get("graph"):
1930 other_nets
[k
]["graph"] = conections
[k
]["graph"]
1931 ifaces_list
.append( (k
, None) )
1934 if con_type
== "external_network":
1935 other_nets
[k
]['external'] = True
1936 if conections
[k
].get("model"):
1937 other_nets
[k
]["model"] = conections
[k
]["model"]
1939 other_nets
[k
]["model"] = k
1940 if con_type
== "dataplane_net" or con_type
== "bridge_net":
1941 other_nets
[k
]["model"] = con_type
1943 conections_list_name
.append(k
)
1944 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)
1945 #print set(ifaces_list)
1946 #check valid VNF and iface names
1947 for iface
in ifaces_list
:
1948 if iface
[0] not in vnfs
and iface
[0] not in other_nets
:
1949 raise NfvoException("format error. Invalid VNF name at 'topology':'connections':'{}':'nodes':'{}'".format(
1950 str(k
), iface
[0]), httperrors
.Not_Found
)
1951 if iface
[0] in vnfs
and iface
[1] not in vnfs
[ iface
[0] ]['ifaces']:
1952 raise NfvoException("format error. Invalid interface name at 'topology':'connections':'{}':'nodes':'{}':'{}'".format(
1953 str(k
), iface
[0], iface
[1]), httperrors
.Not_Found
)
1955 #1.5 unify connections from the pair list to a consolidated list
1957 while index
< len(conections_list
):
1959 while index2
< len(conections_list
):
1960 if len(conections_list
[index
] & conections_list
[index2
])>0: #common interface, join nets
1961 conections_list
[index
] |
= conections_list
[index2
]
1962 del conections_list
[index2
]
1963 del conections_list_name
[index2
]
1966 conections_list
[index
] = list(conections_list
[index
]) # from set to list again
1968 #for k in conections_list:
1973 #1.6 Delete non external nets
1974 # for k in other_nets.keys():
1975 # if other_nets[k]['model']=='bridge' or other_nets[k]['model']=='dataplane_net' or other_nets[k]['model']=='bridge_net':
1976 # for con in conections_list:
1978 # for index in range(0,len(con)):
1979 # if con[index][0] == k: delete_indexes.insert(0,index) #order from higher to lower
1980 # for index in delete_indexes:
1983 #1.7: Check external_ports are present at database table datacenter_nets
1984 for k
,net
in other_nets
.items():
1985 error_pos
= "'topology':'nodes':'" + k
+ "'"
1986 if net
['external']==False:
1987 if 'name' not in net
:
1989 if 'model' not in net
:
1990 raise NfvoException("needed a 'model' at " + error_pos
, httperrors
.Bad_Request
)
1991 if net
['model']=='bridge_net':
1992 net
['type']='bridge';
1993 elif net
['model']=='dataplane_net':
1996 raise NfvoException("unknown 'model' '"+ net
['model'] +"' at " + error_pos
, httperrors
.Not_Found
)
1998 #IF we do not want to check that external network exist at datacenter
2003 # if 'net_id' in net:
2004 # error_text += " 'net_id' " + net['net_id']
2005 # WHERE_['uuid'] = net['net_id']
2006 # if 'model' in net:
2007 # error_text += " 'model' " + net['model']
2008 # WHERE_['name'] = net['model']
2009 # if len(WHERE_) == 0:
2010 # return -httperrors.Bad_Request, "needed a 'net_id' or 'model' at " + error_pos
2011 # r,net_db = mydb.get_table(SELECT=('uuid','name','description','type','shared'),
2012 # FROM='datacenter_nets', WHERE=WHERE_ )
2014 # print "nfvo.new_scenario Error getting datacenter_nets",r,net_db
2016 # print "nfvo.new_scenario Error" +error_text+ " is not present at database"
2017 # return -httperrors.Bad_Request, "unknown " +error_text+ " at " + error_pos
2019 # print "nfvo.new_scenario Error more than one external_network for " +error_text+ " is present at database"
2020 # return -httperrors.Bad_Request, "more than one external_network for " +error_text+ "at "+ error_pos + " Concrete with 'net_id'"
2021 # other_nets[k].update(net_db[0])
2024 net_nb
=0 #Number of nets
2025 for con
in conections_list
:
2026 #check if this is connected to a external net
2030 for index
in range(0,len(con
)):
2031 #check if this is connected to a external net
2032 for net_key
in other_nets
.keys():
2033 if con
[index
][0]==net_key
:
2034 if other_net_index
>=0:
2035 error_text
="There is some interface connected both to net '%s' and net '%s'" % (con
[other_net_index
][0], net_key
)
2036 #print "nfvo.new_scenario " + error_text
2037 raise NfvoException(error_text
, httperrors
.Bad_Request
)
2039 other_net_index
= index
2040 net_target
= net_key
2042 #print "other_net_index", other_net_index
2044 if other_net_index
>=0:
2045 del con
[other_net_index
]
2046 #IF we do not want to check that external network exist at datacenter
2047 if other_nets
[net_target
]['external'] :
2048 if "name" not in other_nets
[net_target
]:
2049 other_nets
[net_target
]['name'] = other_nets
[net_target
]['model']
2050 if other_nets
[net_target
]["type"] == "external_network":
2051 if vnfs
[ con
[0][0] ]['ifaces'][ con
[0][1] ]["type"] == "data":
2052 other_nets
[net_target
]["type"] = "data"
2054 other_nets
[net_target
]["type"] = "bridge"
2056 # if other_nets[net_target]['external'] :
2057 # 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
2058 # if type_=='data' and other_nets[net_target]['type']=="ptp":
2059 # error_text = "Error connecting %d nodes on a not multipoint net %s" % (len(con), net_target)
2060 # print "nfvo.new_scenario " + error_text
2061 # return -httperrors.Bad_Request, error_text
2064 vnfs
[ iface
[0] ]['ifaces'][ iface
[1] ]['net_key'] = net_target
2067 net_type_bridge
=False
2069 net_target
= "__-__net"+str(net_nb
)
2070 net_list
[net_target
] = {'name': conections_list_name
[net_nb
], #"net-"+str(net_nb),
2071 'description':"net-%s in scenario %s" %(net_nb
,topo
['name']),
2074 vnfs
[ iface
[0] ]['ifaces'][ iface
[1] ]['net_key'] = net_target
2075 iface_type
= vnfs
[ iface
[0] ]['ifaces'][ iface
[1] ]['type']
2076 if iface_type
=='mgmt' or iface_type
=='bridge':
2077 net_type_bridge
= True
2079 net_type_data
= True
2080 if net_type_bridge
and net_type_data
:
2081 error_text
= "Error connection interfaces of bridge type with data type. Firs node %s, iface %s" % (iface
[0], iface
[1])
2082 #print "nfvo.new_scenario " + error_text
2083 raise NfvoException(error_text
, httperrors
.Bad_Request
)
2084 elif net_type_bridge
:
2087 type_
='data' if len(con
)>2 else 'ptp'
2088 net_list
[net_target
]['type'] = type_
2091 error_text
= "Error connection node %s : %s does not match any VNF or interface" % (iface
[0], iface
[1])
2092 #print "nfvo.new_scenario " + error_text
2094 raise NfvoException(error_text
, httperrors
.Bad_Request
)
2096 #1.8: Connect to management net all not already connected interfaces of type 'mgmt'
2097 #1.8.1 obtain management net
2098 mgmt_net
= mydb
.get_rows(SELECT
=('uuid','name','description','type','shared'),
2099 FROM
='datacenter_nets', WHERE
={'name':'mgmt'} )
2100 #1.8.2 check all interfaces from all vnfs
2102 add_mgmt_net
= False
2103 for vnf
in vnfs
.values():
2104 for iface
in vnf
['ifaces'].values():
2105 if iface
['type']=='mgmt' and 'net_key' not in iface
:
2106 #iface not connected
2107 iface
['net_key'] = 'mgmt'
2109 if add_mgmt_net
and 'mgmt' not in net_list
:
2110 net_list
['mgmt']=mgmt_net
[0]
2111 net_list
['mgmt']['external']=True
2112 net_list
['mgmt']['graph']={'visible':False}
2114 net_list
.update(other_nets
)
2116 #print 'net_list', net_list
2121 #2: insert scenario. filling tables scenarios,sce_vnfs,sce_interfaces,sce_nets
2122 c
= mydb
.new_scenario( { 'vnfs':vnfs
, 'nets':net_list
,
2123 'tenant_id':tenant_id
, 'name':topo
['name'],
2124 'description':topo
.get('description',topo
['name']),
2125 'public': topo
.get('public', False)
2131 @deprecated("Use new_nsd_v3")
2132 def new_scenario_v02(mydb
, tenant_id
, scenario_dict
, version
):
2133 """ This creates a new scenario for version 0.2 and 0.3"""
2134 scenario
= scenario_dict
["scenario"]
2135 if tenant_id
!= "any":
2136 check_tenant(mydb
, tenant_id
)
2137 if "tenant_id" in scenario
:
2138 if scenario
["tenant_id"] != tenant_id
:
2139 # print "nfvo.new_scenario_v02() tenant '%s' not found" % tenant_id
2140 raise NfvoException("VNF can not have a different tenant owner '{}', must be '{}'".format(
2141 scenario
["tenant_id"], tenant_id
), httperrors
.Unauthorized
)
2145 # 1: Check that VNF are present at database table vnfs and update content into scenario dict
2146 for name
,vnf
in scenario
["vnfs"].iteritems():
2147 where
= {"OR": {"tenant_id": tenant_id
, 'public': "true"}}
2149 error_pos
= "'scenario':'vnfs':'" + name
+ "'"
2151 error_text
+= " 'vnf_id' " + vnf
['vnf_id']
2152 where
['uuid'] = vnf
['vnf_id']
2153 if 'vnf_name' in vnf
:
2154 error_text
+= " 'vnf_name' " + vnf
['vnf_name']
2155 where
['name'] = vnf
['vnf_name']
2157 raise NfvoException("Needed a 'vnf_id' or 'vnf_name' at " + error_pos
, httperrors
.Bad_Request
)
2158 vnf_db
= mydb
.get_rows(SELECT
=('uuid', 'name', 'description'),
2161 if len(vnf_db
) == 0:
2162 raise NfvoException("Unknown" + error_text
+ " at " + error_pos
, httperrors
.Not_Found
)
2163 elif len(vnf_db
) > 1:
2164 raise NfvoException("More than one" + error_text
+ " at " + error_pos
+ " Concrete with 'vnf_id'", httperrors
.Conflict
)
2165 vnf
['uuid'] = vnf_db
[0]['uuid']
2166 vnf
['description'] = vnf_db
[0]['description']
2168 # get external interfaces
2169 ext_ifaces
= mydb
.get_rows(SELECT
=('external_name as name', 'i.uuid as iface_uuid', 'i.type as type'),
2170 FROM
='vnfs join vms on vnfs.uuid=vms.vnf_id join interfaces as i on vms.uuid=i.vm_id',
2171 WHERE
={'vnfs.uuid':vnf
['uuid'], 'external_name<>': None} )
2172 for ext_iface
in ext_ifaces
:
2173 vnf
['ifaces'][ ext_iface
['name'] ] = {'uuid':ext_iface
['iface_uuid'], 'type': ext_iface
['type']}
2174 # TODO? get internal-connections from db.nets and their profiles, and update scenario[vnfs][internal-connections] accordingly
2176 # 2: Insert net_key and ip_address at every vnf interface
2177 for net_name
, net
in scenario
["networks"].items():
2178 net_type_bridge
= False
2179 net_type_data
= False
2180 for iface_dict
in net
["interfaces"]:
2181 if version
== "0.2":
2182 temp_dict
= iface_dict
2184 elif version
== "0.3":
2185 temp_dict
= {iface_dict
["vnf"] : iface_dict
["vnf_interface"]}
2186 ip_address
= iface_dict
.get('ip_address', None)
2187 for vnf
, iface
in temp_dict
.items():
2188 if vnf
not in scenario
["vnfs"]:
2189 error_text
= "Error at 'networks':'{}':'interfaces' VNF '{}' not match any VNF at 'vnfs'".format(
2191 # logger.debug("nfvo.new_scenario_v02 " + error_text)
2192 raise NfvoException(error_text
, httperrors
.Not_Found
)
2193 if iface
not in scenario
["vnfs"][vnf
]['ifaces']:
2194 error_text
= "Error at 'networks':'{}':'interfaces':'{}' interface not match any VNF interface"\
2195 .format(net_name
, iface
)
2196 # logger.debug("nfvo.new_scenario_v02 " + error_text)
2197 raise NfvoException(error_text
, httperrors
.Bad_Request
)
2198 if "net_key" in scenario
["vnfs"][vnf
]['ifaces'][iface
]:
2199 error_text
= "Error at 'networks':'{}':'interfaces':'{}' interface already connected at network"\
2200 "'{}'".format(net_name
, iface
,scenario
["vnfs"][vnf
]['ifaces'][iface
]['net_key'])
2201 # logger.debug("nfvo.new_scenario_v02 " + error_text)
2202 raise NfvoException(error_text
, httperrors
.Bad_Request
)
2203 scenario
["vnfs"][vnf
]['ifaces'][ iface
]['net_key'] = net_name
2204 scenario
["vnfs"][vnf
]['ifaces'][iface
]['ip_address'] = ip_address
2205 iface_type
= scenario
["vnfs"][vnf
]['ifaces'][iface
]['type']
2206 if iface_type
== 'mgmt' or iface_type
== 'bridge':
2207 net_type_bridge
= True
2209 net_type_data
= True
2211 if net_type_bridge
and net_type_data
:
2212 error_text
= "Error connection interfaces of 'bridge' type and 'data' type at 'networks':'{}':'interfaces'"\
2214 # logger.debug("nfvo.new_scenario " + error_text)
2215 raise NfvoException(error_text
, httperrors
.Bad_Request
)
2216 elif net_type_bridge
:
2219 type_
= 'data' if len(net
["interfaces"]) > 2 else 'ptp'
2221 if net
.get("implementation"): # for v0.3
2222 if type_
== "bridge" and net
["implementation"] == "underlay":
2223 error_text
= "Error connecting interfaces of data type to a network declared as 'underlay' at "\
2224 "'network':'{}'".format(net_name
)
2225 # logger.debug(error_text)
2226 raise NfvoException(error_text
, httperrors
.Bad_Request
)
2227 elif type_
!= "bridge" and net
["implementation"] == "overlay":
2228 error_text
= "Error connecting interfaces of data type to a network declared as 'overlay' at "\
2229 "'network':'{}'".format(net_name
)
2230 # logger.debug(error_text)
2231 raise NfvoException(error_text
, httperrors
.Bad_Request
)
2232 net
.pop("implementation")
2233 if "type" in net
and version
== "0.3": # for v0.3
2234 if type_
== "data" and net
["type"] == "e-line":
2235 error_text
= "Error connecting more than 2 interfaces of data type to a network declared as type "\
2236 "'e-line' at 'network':'{}'".format(net_name
)
2237 # logger.debug(error_text)
2238 raise NfvoException(error_text
, httperrors
.Bad_Request
)
2239 elif type_
== "ptp" and net
["type"] == "e-lan":
2243 net
['name'] = net_name
2244 net
['external'] = net
.get('external', False)
2246 # 3: insert at database
2247 scenario
["nets"] = scenario
["networks"]
2248 scenario
['tenant_id'] = tenant_id
2249 scenario_id
= mydb
.new_scenario(scenario
)
2253 def new_nsd_v3(mydb
, tenant_id
, nsd_descriptor
):
2255 Parses an OSM IM nsd_catalog and insert at DB
2258 :param nsd_descriptor:
2259 :return: The list of created NSD ids
2262 mynsd
= nsd_catalog
.nsd()
2264 pybindJSONDecoder
.load_ietf_json(nsd_descriptor
, None, None, obj
=mynsd
)
2265 except Exception as e
:
2266 raise NfvoException("Error. Invalid NS descriptor format: " + str(e
), httperrors
.Bad_Request
)
2270 db_sce_interfaces
= []
2273 db_sce_rsp_hops
= []
2274 db_sce_classifiers
= []
2275 db_sce_classifier_matches
= []
2277 db_ip_profiles_index
= 0
2280 for nsd_yang
in mynsd
.nsd_catalog
.nsd
.itervalues():
2281 nsd
= nsd_yang
.get()
2284 scenario_uuid
= str(uuid4())
2285 uuid_list
.append(scenario_uuid
)
2286 nsd_uuid_list
.append(scenario_uuid
)
2288 "uuid": scenario_uuid
,
2289 "osm_id": get_str(nsd
, "id", 255),
2290 "name": get_str(nsd
, "name", 255),
2291 "description": get_str(nsd
, "description", 255),
2292 "tenant_id": tenant_id
,
2293 "vendor": get_str(nsd
, "vendor", 255),
2294 "short_name": get_str(nsd
, "short-name", 255),
2295 "descriptor": str(nsd_descriptor
)[:60000],
2297 db_scenarios
.append(db_scenario
)
2299 # table sce_vnfs (constituent-vnfd)
2300 vnf_index2scevnf_uuid
= {}
2301 vnf_index2vnf_uuid
= {}
2302 for vnf
in nsd
.get("constituent-vnfd").itervalues():
2303 existing_vnf
= mydb
.get_rows(FROM
="vnfs", WHERE
={'osm_id': str(vnf
["vnfd-id-ref"])[:255],
2304 'tenant_id': tenant_id
})
2305 if not existing_vnf
:
2306 raise NfvoException("Error. Invalid NS descriptor at 'nsd[{}]':'constituent-vnfd':'vnfd-id-ref':"
2307 "'{}'. Reference to a non-existing VNFD in the catalog".format(
2308 str(nsd
["id"]), str(vnf
["vnfd-id-ref"])[:255]),
2309 httperrors
.Bad_Request
)
2310 sce_vnf_uuid
= str(uuid4())
2311 uuid_list
.append(sce_vnf_uuid
)
2313 "uuid": sce_vnf_uuid
,
2314 "scenario_id": scenario_uuid
,
2315 # "name": get_str(vnf, "member-vnf-index", 255),
2316 "name": existing_vnf
[0]["name"][:200] + "." + get_str(vnf
, "member-vnf-index", 50),
2317 "vnf_id": existing_vnf
[0]["uuid"],
2318 "member_vnf_index": str(vnf
["member-vnf-index"]),
2319 # TODO 'start-by-default': True
2321 vnf_index2scevnf_uuid
[str(vnf
['member-vnf-index'])] = sce_vnf_uuid
2322 vnf_index2vnf_uuid
[str(vnf
['member-vnf-index'])] = existing_vnf
[0]["uuid"]
2323 db_sce_vnfs
.append(db_sce_vnf
)
2325 # table ip_profiles (ip-profiles)
2326 ip_profile_name2db_table_index
= {}
2327 for ip_profile
in nsd
.get("ip-profiles").itervalues():
2329 "ip_version": str(ip_profile
["ip-profile-params"].get("ip-version", "ipv4")),
2330 "subnet_address": str(ip_profile
["ip-profile-params"].get("subnet-address")),
2331 "gateway_address": str(ip_profile
["ip-profile-params"].get("gateway-address")),
2332 "dhcp_enabled": str(ip_profile
["ip-profile-params"]["dhcp-params"].get("enabled", True)),
2333 "dhcp_start_address": str(ip_profile
["ip-profile-params"]["dhcp-params"].get("start-address")),
2334 "dhcp_count": str(ip_profile
["ip-profile-params"]["dhcp-params"].get("count")),
2337 for dns
in ip_profile
["ip-profile-params"]["dns-server"].itervalues():
2338 dns_list
.append(str(dns
.get("address")))
2339 db_ip_profile
["dns_address"] = ";".join(dns_list
)
2340 if ip_profile
["ip-profile-params"].get('security-group'):
2341 db_ip_profile
["security_group"] = ip_profile
["ip-profile-params"]['security-group']
2342 ip_profile_name2db_table_index
[str(ip_profile
["name"])] = db_ip_profiles_index
2343 db_ip_profiles_index
+= 1
2344 db_ip_profiles
.append(db_ip_profile
)
2346 # table sce_nets (internal-vld)
2347 for vld
in nsd
.get("vld").itervalues():
2348 sce_net_uuid
= str(uuid4())
2349 uuid_list
.append(sce_net_uuid
)
2351 "uuid": sce_net_uuid
,
2352 "name": get_str(vld
, "name", 255),
2353 "scenario_id": scenario_uuid
,
2355 "multipoint": not vld
.get("type") == "ELINE",
2356 "osm_id": get_str(vld
, "id", 255),
2358 "description": get_str(vld
, "description", 255),
2360 # guess type of network
2361 if vld
.get("mgmt-network"):
2362 db_sce_net
["type"] = "bridge"
2363 db_sce_net
["external"] = True
2364 elif vld
.get("provider-network").get("overlay-type") == "VLAN":
2365 db_sce_net
["type"] = "data"
2367 # later on it will be fixed to bridge or data depending on the type of interfaces attached to it
2368 db_sce_net
["type"] = None
2369 db_sce_nets
.append(db_sce_net
)
2371 # ip-profile, link db_ip_profile with db_sce_net
2372 if vld
.get("ip-profile-ref"):
2373 ip_profile_name
= vld
.get("ip-profile-ref")
2374 if ip_profile_name
not in ip_profile_name2db_table_index
:
2375 raise NfvoException("Error. Invalid NS descriptor at 'nsd[{}]':'vld[{}]':'ip-profile-ref':'{}'."
2376 " Reference to a non-existing 'ip_profiles'".format(
2377 str(nsd
["id"]), str(vld
["id"]), str(vld
["ip-profile-ref"])),
2378 httperrors
.Bad_Request
)
2379 db_ip_profiles
[ip_profile_name2db_table_index
[ip_profile_name
]]["sce_net_id"] = sce_net_uuid
2380 elif vld
.get("vim-network-name"):
2381 db_sce_net
["vim_network_name"] = get_str(vld
, "vim-network-name", 255)
2383 # table sce_interfaces (vld:vnfd-connection-point-ref)
2384 for iface
in vld
.get("vnfd-connection-point-ref").itervalues():
2385 vnf_index
= str(iface
['member-vnf-index-ref'])
2386 # check correct parameters
2387 if vnf_index
not in vnf_index2vnf_uuid
:
2388 raise NfvoException("Error. Invalid NS descriptor at 'nsd[{}]':'vld[{}]':'vnfd-connection-point"
2389 "-ref':'member-vnf-index-ref':'{}'. Reference to a non-existing index at "
2390 "'nsd':'constituent-vnfd'".format(
2391 str(nsd
["id"]), str(vld
["id"]), str(iface
["member-vnf-index-ref"])),
2392 httperrors
.Bad_Request
)
2394 existing_ifaces
= mydb
.get_rows(SELECT
=('i.uuid as uuid', 'i.type as iface_type'),
2395 FROM
="interfaces as i join vms on i.vm_id=vms.uuid",
2396 WHERE
={'vnf_id': vnf_index2vnf_uuid
[vnf_index
],
2397 'external_name': get_str(iface
, "vnfd-connection-point-ref",
2399 if not existing_ifaces
:
2400 raise NfvoException("Error. Invalid NS descriptor at 'nsd[{}]':'vld[{}]':'vnfd-connection-point"
2401 "-ref':'vnfd-connection-point-ref':'{}'. Reference to a non-existing "
2402 "connection-point name at VNFD '{}'".format(
2403 str(nsd
["id"]), str(vld
["id"]), str(iface
["vnfd-connection-point-ref"]),
2404 str(iface
.get("vnfd-id-ref"))[:255]),
2405 httperrors
.Bad_Request
)
2406 interface_uuid
= existing_ifaces
[0]["uuid"]
2407 if existing_ifaces
[0]["iface_type"] == "data" and not db_sce_net
["type"]:
2408 db_sce_net
["type"] = "data"
2409 sce_interface_uuid
= str(uuid4())
2410 uuid_list
.append(sce_net_uuid
)
2411 iface_ip_address
= None
2412 if iface
.get("ip-address"):
2413 iface_ip_address
= str(iface
.get("ip-address"))
2414 db_sce_interface
= {
2415 "uuid": sce_interface_uuid
,
2416 "sce_vnf_id": vnf_index2scevnf_uuid
[vnf_index
],
2417 "sce_net_id": sce_net_uuid
,
2418 "interface_id": interface_uuid
,
2419 "ip_address": iface_ip_address
,
2421 db_sce_interfaces
.append(db_sce_interface
)
2422 if not db_sce_net
["type"]:
2423 db_sce_net
["type"] = "bridge"
2425 # table sce_vnffgs (vnffgd)
2426 for vnffg
in nsd
.get("vnffgd").itervalues():
2427 sce_vnffg_uuid
= str(uuid4())
2428 uuid_list
.append(sce_vnffg_uuid
)
2430 "uuid": sce_vnffg_uuid
,
2431 "name": get_str(vnffg
, "name", 255),
2432 "scenario_id": scenario_uuid
,
2433 "vendor": get_str(vnffg
, "vendor", 255),
2434 "description": get_str(vld
, "description", 255),
2436 db_sce_vnffgs
.append(db_sce_vnffg
)
2440 for rsp
in vnffg
.get("rsp").itervalues():
2441 sce_rsp_uuid
= str(uuid4())
2442 uuid_list
.append(sce_rsp_uuid
)
2444 "uuid": sce_rsp_uuid
,
2445 "name": get_str(rsp
, "name", 255),
2446 "sce_vnffg_id": sce_vnffg_uuid
,
2447 "id": get_str(rsp
, "id", 255), # only useful to link with classifiers; will be removed later in the code
2449 db_sce_rsps
.append(db_sce_rsp
)
2450 db_sce_rsp_hops
= []
2451 for iface
in rsp
.get("vnfd-connection-point-ref").itervalues():
2452 vnf_index
= str(iface
['member-vnf-index-ref'])
2453 if_order
= int(iface
['order'])
2454 # check correct parameters
2455 if vnf_index
not in vnf_index2vnf_uuid
:
2456 raise NfvoException("Error. Invalid NS descriptor at 'nsd[{}]':'rsp[{}]':'vnfd-connection-point"
2457 "-ref':'member-vnf-index-ref':'{}'. Reference to a non-existing index at "
2458 "'nsd':'constituent-vnfd'".format(
2459 str(nsd
["id"]), str(rsp
["id"]), str(iface
["member-vnf-index-ref"])),
2460 httperrors
.Bad_Request
)
2462 existing_ifaces
= mydb
.get_rows(SELECT
=('i.uuid as uuid',),
2463 FROM
="interfaces as i join vms on i.vm_id=vms.uuid",
2464 WHERE
={'vnf_id': vnf_index2vnf_uuid
[vnf_index
],
2465 'external_name': get_str(iface
, "vnfd-connection-point-ref",
2467 if not existing_ifaces
:
2468 raise NfvoException("Error. Invalid NS descriptor at 'nsd[{}]':'rsp[{}]':'vnfd-connection-point"
2469 "-ref':'vnfd-connection-point-ref':'{}'. Reference to a non-existing "
2470 "connection-point name at VNFD '{}'".format(
2471 str(nsd
["id"]), str(rsp
["id"]), str(iface
["vnfd-connection-point-ref"]),
2472 str(iface
.get("vnfd-id-ref"))[:255]),
2473 httperrors
.Bad_Request
)
2474 interface_uuid
= existing_ifaces
[0]["uuid"]
2475 sce_rsp_hop_uuid
= str(uuid4())
2476 uuid_list
.append(sce_rsp_hop_uuid
)
2478 "uuid": sce_rsp_hop_uuid
,
2479 "if_order": if_order
,
2480 "interface_id": interface_uuid
,
2481 "sce_vnf_id": vnf_index2scevnf_uuid
[vnf_index
],
2482 "sce_rsp_id": sce_rsp_uuid
,
2484 db_sce_rsp_hops
.append(db_sce_rsp_hop
)
2486 # deal with classifiers
2487 db_sce_classifiers
= []
2488 for classifier
in vnffg
.get("classifier").itervalues():
2489 sce_classifier_uuid
= str(uuid4())
2490 uuid_list
.append(sce_classifier_uuid
)
2493 vnf_index
= str(classifier
['member-vnf-index-ref'])
2494 if vnf_index
not in vnf_index2vnf_uuid
:
2495 raise NfvoException("Error. Invalid NS descriptor at 'nsd[{}]':'classifier[{}]':'vnfd-connection-point"
2496 "-ref':'member-vnf-index-ref':'{}'. Reference to a non-existing index at "
2497 "'nsd':'constituent-vnfd'".format(
2498 str(nsd
["id"]), str(classifier
["id"]), str(classifier
["member-vnf-index-ref"])),
2499 httperrors
.Bad_Request
)
2500 existing_ifaces
= mydb
.get_rows(SELECT
=('i.uuid as uuid',),
2501 FROM
="interfaces as i join vms on i.vm_id=vms.uuid",
2502 WHERE
={'vnf_id': vnf_index2vnf_uuid
[vnf_index
],
2503 'external_name': get_str(classifier
, "vnfd-connection-point-ref",
2505 if not existing_ifaces
:
2506 raise NfvoException("Error. Invalid NS descriptor at 'nsd[{}]':'rsp[{}]':'vnfd-connection-point"
2507 "-ref':'vnfd-connection-point-ref':'{}'. Reference to a non-existing "
2508 "connection-point name at VNFD '{}'".format(
2509 str(nsd
["id"]), str(rsp
["id"]), str(iface
["vnfd-connection-point-ref"]),
2510 str(iface
.get("vnfd-id-ref"))[:255]),
2511 httperrors
.Bad_Request
)
2512 interface_uuid
= existing_ifaces
[0]["uuid"]
2514 db_sce_classifier
= {
2515 "uuid": sce_classifier_uuid
,
2516 "name": get_str(classifier
, "name", 255),
2517 "sce_vnffg_id": sce_vnffg_uuid
,
2518 "sce_vnf_id": vnf_index2scevnf_uuid
[vnf_index
],
2519 "interface_id": interface_uuid
,
2521 rsp_id
= get_str(classifier
, "rsp-id-ref", 255)
2522 rsp
= next((item
for item
in db_sce_rsps
if item
["id"] == rsp_id
), None)
2523 db_sce_classifier
["sce_rsp_id"] = rsp
["uuid"]
2524 db_sce_classifiers
.append(db_sce_classifier
)
2526 db_sce_classifier_matches
= []
2527 for match
in classifier
.get("match-attributes").itervalues():
2528 sce_classifier_match_uuid
= str(uuid4())
2529 uuid_list
.append(sce_classifier_match_uuid
)
2530 db_sce_classifier_match
= {
2531 "uuid": sce_classifier_match_uuid
,
2532 "ip_proto": get_str(match
, "ip-proto", 2),
2533 "source_ip": get_str(match
, "source-ip-address", 16),
2534 "destination_ip": get_str(match
, "destination-ip-address", 16),
2535 "source_port": get_str(match
, "source-port", 5),
2536 "destination_port": get_str(match
, "destination-port", 5),
2537 "sce_classifier_id": sce_classifier_uuid
,
2539 db_sce_classifier_matches
.append(db_sce_classifier_match
)
2542 # remove unneeded id's in sce_rsps
2543 for rsp
in db_sce_rsps
:
2547 {"scenarios": db_scenarios
},
2548 {"sce_nets": db_sce_nets
},
2549 {"ip_profiles": db_ip_profiles
},
2550 {"sce_vnfs": db_sce_vnfs
},
2551 {"sce_interfaces": db_sce_interfaces
},
2552 {"sce_vnffgs": db_sce_vnffgs
},
2553 {"sce_rsps": db_sce_rsps
},
2554 {"sce_rsp_hops": db_sce_rsp_hops
},
2555 {"sce_classifiers": db_sce_classifiers
},
2556 {"sce_classifier_matches": db_sce_classifier_matches
},
2559 logger
.debug("new_nsd_v3 done: %s",
2560 yaml
.safe_dump(db_tables
, indent
=4, default_flow_style
=False) )
2561 mydb
.new_rows(db_tables
, uuid_list
)
2562 return nsd_uuid_list
2563 except NfvoException
:
2565 except Exception as e
:
2566 logger
.error("Exception {}".format(e
))
2567 raise # NfvoException("Exception {}".format(e), httperrors.Bad_Request)
2570 def edit_scenario(mydb
, tenant_id
, scenario_id
, data
):
2571 data
["uuid"] = scenario_id
2572 data
["tenant_id"] = tenant_id
2573 c
= mydb
.edit_scenario( data
)
2577 @deprecated("Use create_instance")
2578 def start_scenario(mydb
, tenant_id
, scenario_id
, instance_scenario_name
, instance_scenario_description
, datacenter
=None,vim_tenant
=None, startvms
=True):
2579 #print "Checking that nfvo_tenant_id exists and getting the VIM URI and the VIM tenant_id"
2580 datacenter_id
, myvim
= get_datacenter_by_name_uuid(mydb
, tenant_id
, datacenter
, vim_tenant
=vim_tenant
)
2581 vims
= {datacenter_id
: myvim
}
2582 myvim_tenant
= myvim
['tenant_id']
2583 datacenter_name
= myvim
['name']
2587 #print "Checking that the scenario_id exists and getting the scenario dictionary"
2588 scenarioDict
= mydb
.get_scenario(scenario_id
, tenant_id
, datacenter_id
=datacenter_id
)
2589 scenarioDict
['datacenter2tenant'] = { datacenter_id
: myvim
['config']['datacenter_tenant_id'] }
2590 scenarioDict
['datacenter_id'] = datacenter_id
2591 #print '================scenarioDict======================='
2592 #print json.dumps(scenarioDict, indent=4)
2593 #print 'BEGIN launching instance scenario "%s" based on "%s"' % (instance_scenario_name,scenarioDict['name'])
2595 logger
.debug("start_scenario Scenario %s: consisting of %d VNF(s)", scenarioDict
['name'],len(scenarioDict
['vnfs']))
2596 #print yaml.safe_dump(scenarioDict, indent=4, default_flow_style=False)
2598 auxNetDict
= {} #Auxiliar dictionary. First key:'scenario' or sce_vnf uuid. Second Key: uuid of the net/sce_net. Value: vim_net_id
2599 auxNetDict
['scenario'] = {}
2601 logger
.debug("start_scenario 1. Creating new nets (sce_nets) in the VIM")
2602 for sce_net
in scenarioDict
['nets']:
2603 #print "Net name: %s. Description: %s" % (sce_net["name"], sce_net["description"])
2605 myNetName
= "%s.%s" % (instance_scenario_name
, sce_net
['name'])
2606 myNetName
= myNetName
[0:255] #limit length
2607 myNetType
= sce_net
['type']
2609 myNetDict
["name"] = myNetName
2610 myNetDict
["type"] = myNetType
2611 myNetDict
["tenant_id"] = myvim_tenant
2612 myNetIPProfile
= sce_net
.get('ip_profile', None)
2614 #We should use the dictionary as input parameter for new_network
2616 if not sce_net
["external"]:
2617 network_id
= myvim
.new_network(myNetName
, myNetType
, myNetIPProfile
)
2618 #print "New VIM network created for scenario %s. Network id: %s" % (scenarioDict['name'],network_id)
2619 sce_net
['vim_id'] = network_id
2620 auxNetDict
['scenario'][sce_net
['uuid']] = network_id
2621 rollbackList
.append({'what':'network','where':'vim','vim_id':datacenter_id
,'uuid':network_id
})
2622 sce_net
["created"] = True
2624 if sce_net
['vim_id'] == None:
2625 error_text
= "Error, datacenter '%s' does not have external network '%s'." % (datacenter_name
, sce_net
['name'])
2626 _
, message
= rollback(mydb
, vims
, rollbackList
)
2627 logger
.error("nfvo.start_scenario: %s", error_text
)
2628 raise NfvoException(error_text
, httperrors
.Bad_Request
)
2629 logger
.debug("Using existent VIM network for scenario %s. Network id %s", scenarioDict
['name'],sce_net
['vim_id'])
2630 auxNetDict
['scenario'][sce_net
['uuid']] = sce_net
['vim_id']
2632 logger
.debug("start_scenario 2. Creating new nets (vnf internal nets) in the VIM")
2633 #For each vnf net, we create it and we add it to instanceNetlist.
2635 for sce_vnf
in scenarioDict
['vnfs']:
2636 for net
in sce_vnf
['nets']:
2637 #print "Net name: %s. Description: %s" % (net["name"], net["description"])
2639 myNetName
= "%s.%s" % (instance_scenario_name
,net
['name'])
2640 myNetName
= myNetName
[0:255] #limit length
2641 myNetType
= net
['type']
2643 myNetDict
["name"] = myNetName
2644 myNetDict
["type"] = myNetType
2645 myNetDict
["tenant_id"] = myvim_tenant
2646 myNetIPProfile
= net
.get('ip_profile', None)
2649 #We should use the dictionary as input parameter for new_network
2650 network_id
= myvim
.new_network(myNetName
, myNetType
, myNetIPProfile
)
2651 #print "VIM network id for scenario %s: %s" % (scenarioDict['name'],network_id)
2652 net
['vim_id'] = network_id
2653 if sce_vnf
['uuid'] not in auxNetDict
:
2654 auxNetDict
[sce_vnf
['uuid']] = {}
2655 auxNetDict
[sce_vnf
['uuid']][net
['uuid']] = network_id
2656 rollbackList
.append({'what':'network','where':'vim','vim_id':datacenter_id
,'uuid':network_id
})
2657 net
["created"] = True
2659 #print "auxNetDict:"
2660 #print yaml.safe_dump(auxNetDict, indent=4, default_flow_style=False)
2662 logger
.debug("start_scenario 3. Creating new vm instances in the VIM")
2663 #myvim.new_vminstance(self,vimURI,tenant_id,name,description,image_id,flavor_id,net_dict)
2665 for sce_vnf
in scenarioDict
['vnfs']:
2666 vnf_availability_zones
= []
2667 for vm
in sce_vnf
['vms']:
2668 vm_av
= vm
.get('availability_zone')
2669 if vm_av
and vm_av
not in vnf_availability_zones
:
2670 vnf_availability_zones
.append(vm_av
)
2672 # check if there is enough availability zones available at vim level.
2673 if myvims
[datacenter_id
].availability_zone
and vnf_availability_zones
:
2674 if len(vnf_availability_zones
) > len(myvims
[datacenter_id
].availability_zone
):
2675 raise NfvoException('No enough availability zones at VIM for this deployment', httperrors
.Bad_Request
)
2677 for vm
in sce_vnf
['vms']:
2680 #myVMDict['name'] = "%s-%s-%s" % (scenarioDict['name'],sce_vnf['name'], vm['name'])
2681 myVMDict
['name'] = "{}.{}.{}".format(instance_scenario_name
,sce_vnf
['name'],chr(96+i
))
2682 #myVMDict['description'] = vm['description']
2683 myVMDict
['description'] = myVMDict
['name'][0:99]
2685 myVMDict
['start'] = "no"
2686 myVMDict
['name'] = myVMDict
['name'][0:255] #limit name length
2687 #print "VM name: %s. Description: %s" % (myVMDict['name'], myVMDict['name'])
2689 #create image at vim in case it not exist
2690 image_dict
= mydb
.get_table_by_uuid_name("images", vm
['image_id'])
2691 image_id
= create_or_use_image(mydb
, vims
, image_dict
, [], True)
2692 vm
['vim_image_id'] = image_id
2694 #create flavor at vim in case it not exist
2695 flavor_dict
= mydb
.get_table_by_uuid_name("flavors", vm
['flavor_id'])
2696 if flavor_dict
['extended']!=None:
2697 flavor_dict
['extended']= yaml
.load(flavor_dict
['extended'])
2698 flavor_id
= create_or_use_flavor(mydb
, vims
, flavor_dict
, [], True)
2699 vm
['vim_flavor_id'] = flavor_id
2702 myVMDict
['imageRef'] = vm
['vim_image_id']
2703 myVMDict
['flavorRef'] = vm
['vim_flavor_id']
2704 myVMDict
['networks'] = []
2705 for iface
in vm
['interfaces']:
2707 if iface
['type']=="data":
2708 netDict
['type'] = iface
['model']
2709 elif "model" in iface
and iface
["model"]!=None:
2710 netDict
['model']=iface
['model']
2711 #TODO in future, remove this because mac_address will not be set, and the type of PV,VF is obtained from iterface table model
2712 #discover type of interface looking at flavor
2713 for numa
in flavor_dict
.get('extended',{}).get('numas',[]):
2714 for flavor_iface
in numa
.get('interfaces',[]):
2715 if flavor_iface
.get('name') == iface
['internal_name']:
2716 if flavor_iface
['dedicated'] == 'yes':
2717 netDict
['type']="PF" #passthrough
2718 elif flavor_iface
['dedicated'] == 'no':
2719 netDict
['type']="VF" #siov
2720 elif flavor_iface
['dedicated'] == 'yes:sriov':
2721 netDict
['type']="VFnotShared" #sriov but only one sriov on the PF
2722 netDict
["mac_address"] = flavor_iface
.get("mac_address")
2724 netDict
["use"]=iface
['type']
2725 if netDict
["use"]=="data" and not netDict
.get("type"):
2726 #print "netDict", netDict
2727 #print "iface", iface
2728 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'])
2729 if flavor_dict
.get('extended')==None:
2730 raise NfvoException(e_text
+ "After database migration some information is not available. \
2731 Try to delete and create the scenarios and VNFs again", httperrors
.Conflict
)
2733 raise NfvoException(e_text
, httperrors
.Internal_Server_Error
)
2734 if netDict
["use"]=="mgmt" or netDict
["use"]=="bridge":
2735 netDict
["type"]="virtual"
2736 if "vpci" in iface
and iface
["vpci"] is not None:
2737 netDict
['vpci'] = iface
['vpci']
2738 if "mac" in iface
and iface
["mac"] is not None:
2739 netDict
['mac_address'] = iface
['mac']
2740 if "port-security" in iface
and iface
["port-security"] is not None:
2741 netDict
['port_security'] = iface
['port-security']
2742 if "floating-ip" in iface
and iface
["floating-ip"] is not None:
2743 netDict
['floating_ip'] = iface
['floating-ip']
2744 netDict
['name'] = iface
['internal_name']
2745 if iface
['net_id'] is None:
2746 for vnf_iface
in sce_vnf
["interfaces"]:
2749 if vnf_iface
['interface_id']==iface
['uuid']:
2750 netDict
['net_id'] = auxNetDict
['scenario'][ vnf_iface
['sce_net_id'] ]
2753 netDict
['net_id'] = auxNetDict
[ sce_vnf
['uuid'] ][ iface
['net_id'] ]
2754 #skip bridge ifaces not connected to any net
2755 #if 'net_id' not in netDict or netDict['net_id']==None:
2757 myVMDict
['networks'].append(netDict
)
2758 #print ">>>>>>>>>>>>>>>>>>>>>>>>>>>"
2759 #print myVMDict['name']
2760 #print "networks", yaml.safe_dump(myVMDict['networks'], indent=4, default_flow_style=False)
2761 #print "interfaces", yaml.safe_dump(vm['interfaces'], indent=4, default_flow_style=False)
2762 #print ">>>>>>>>>>>>>>>>>>>>>>>>>>>"
2764 if 'availability_zone' in myVMDict
:
2765 av_index
= vnf_availability_zones
.index(myVMDict
['availability_zone'])
2769 vm_id
, _
= myvim
.new_vminstance(myVMDict
['name'], myVMDict
['description'], myVMDict
.get('start', None),
2770 myVMDict
['imageRef'], myVMDict
['flavorRef'], myVMDict
['networks'],
2771 availability_zone_index
=av_index
,
2772 availability_zone_list
=vnf_availability_zones
)
2773 #print "VIM vm instance id (server id) for scenario %s: %s" % (scenarioDict['name'],vm_id)
2774 vm
['vim_id'] = vm_id
2775 rollbackList
.append({'what':'vm','where':'vim','vim_id':datacenter_id
,'uuid':vm_id
})
2776 #put interface uuid back to scenario[vnfs][vms[[interfaces]
2777 for net
in myVMDict
['networks']:
2779 for iface
in vm
['interfaces']:
2780 if net
["name"]==iface
["internal_name"]:
2781 iface
["vim_id"]=net
["vim_id"]
2784 logger
.debug("start scenario Deployment done")
2785 #print yaml.safe_dump(scenarioDict, indent=4, default_flow_style=False)
2786 #r,c = mydb.new_instance_scenario_as_a_whole(nfvo_tenant,scenarioDict['name'],scenarioDict)
2787 instance_id
= mydb
.new_instance_scenario_as_a_whole(tenant_id
,instance_scenario_name
, instance_scenario_description
, scenarioDict
)
2788 return mydb
.get_instance_scenario(instance_id
)
2790 except (db_base_Exception
, vimconn
.vimconnException
) as e
:
2791 _
, message
= rollback(mydb
, vims
, rollbackList
)
2792 if isinstance(e
, db_base_Exception
):
2793 error_text
= "Exception at database"
2795 error_text
= "Exception at VIM"
2796 error_text
+= " {} {}. {}".format(type(e
).__name
__, str(e
), message
)
2797 #logger.error("start_scenario %s", error_text)
2798 raise NfvoException(error_text
, e
.http_code
)
2800 def unify_cloud_config(cloud_config_preserve
, cloud_config
):
2801 """ join the cloud config information into cloud_config_preserve.
2802 In case of conflict cloud_config_preserve preserves
2805 if not cloud_config_preserve
and not cloud_config
:
2808 new_cloud_config
= {"key-pairs":[], "users":[]}
2810 if cloud_config_preserve
:
2811 for key
in cloud_config_preserve
.get("key-pairs", () ):
2812 if key
not in new_cloud_config
["key-pairs"]:
2813 new_cloud_config
["key-pairs"].append(key
)
2815 for key
in cloud_config
.get("key-pairs", () ):
2816 if key
not in new_cloud_config
["key-pairs"]:
2817 new_cloud_config
["key-pairs"].append(key
)
2818 if not new_cloud_config
["key-pairs"]:
2819 del new_cloud_config
["key-pairs"]
2823 new_cloud_config
["users"] += cloud_config
.get("users", () )
2824 if cloud_config_preserve
:
2825 new_cloud_config
["users"] += cloud_config_preserve
.get("users", () )
2826 index_to_delete
= []
2827 users
= new_cloud_config
.get("users", [])
2828 for index0
in range(0,len(users
)):
2829 if index0
in index_to_delete
:
2831 for index1
in range(index0
+1,len(users
)):
2832 if index1
in index_to_delete
:
2834 if users
[index0
]["name"] == users
[index1
]["name"]:
2835 index_to_delete
.append(index1
)
2836 for key
in users
[index1
].get("key-pairs",()):
2837 if "key-pairs" not in users
[index0
]:
2838 users
[index0
]["key-pairs"] = [key
]
2839 elif key
not in users
[index0
]["key-pairs"]:
2840 users
[index0
]["key-pairs"].append(key
)
2841 index_to_delete
.sort(reverse
=True)
2842 for index
in index_to_delete
:
2844 if not new_cloud_config
["users"]:
2845 del new_cloud_config
["users"]
2848 if cloud_config
and cloud_config
.get("boot-data-drive") != None:
2849 new_cloud_config
["boot-data-drive"] = cloud_config
["boot-data-drive"]
2850 if cloud_config_preserve
and cloud_config_preserve
.get("boot-data-drive") != None:
2851 new_cloud_config
["boot-data-drive"] = cloud_config_preserve
["boot-data-drive"]
2854 new_cloud_config
["user-data"] = []
2855 if cloud_config
and cloud_config
.get("user-data"):
2856 if isinstance(cloud_config
["user-data"], list):
2857 new_cloud_config
["user-data"] += cloud_config
["user-data"]
2859 new_cloud_config
["user-data"].append(cloud_config
["user-data"])
2860 if cloud_config_preserve
and cloud_config_preserve
.get("user-data"):
2861 if isinstance(cloud_config_preserve
["user-data"], list):
2862 new_cloud_config
["user-data"] += cloud_config_preserve
["user-data"]
2864 new_cloud_config
["user-data"].append(cloud_config_preserve
["user-data"])
2865 if not new_cloud_config
["user-data"]:
2866 del new_cloud_config
["user-data"]
2869 new_cloud_config
["config-files"] = []
2870 if cloud_config
and cloud_config
.get("config-files") != None:
2871 new_cloud_config
["config-files"] += cloud_config
["config-files"]
2872 if cloud_config_preserve
:
2873 for file in cloud_config_preserve
.get("config-files", ()):
2874 for index
in range(0, len(new_cloud_config
["config-files"])):
2875 if new_cloud_config
["config-files"][index
]["dest"] == file["dest"]:
2876 new_cloud_config
["config-files"][index
] = file
2879 new_cloud_config
["config-files"].append(file)
2880 if not new_cloud_config
["config-files"]:
2881 del new_cloud_config
["config-files"]
2882 return new_cloud_config
2885 def get_vim_thread(mydb
, tenant_id
, datacenter_id_name
=None, datacenter_tenant_id
=None):
2886 datacenter_id
= None
2887 datacenter_name
= None
2890 if datacenter_tenant_id
:
2891 thread_id
= datacenter_tenant_id
2892 thread
= vim_threads
["running"].get(datacenter_tenant_id
)
2894 where_
={"td.nfvo_tenant_id": tenant_id
}
2895 if datacenter_id_name
:
2896 if utils
.check_valid_uuid(datacenter_id_name
):
2897 datacenter_id
= datacenter_id_name
2898 where_
["dt.datacenter_id"] = datacenter_id
2900 datacenter_name
= datacenter_id_name
2901 where_
["d.name"] = datacenter_name
2902 if datacenter_tenant_id
:
2903 where_
["dt.uuid"] = datacenter_tenant_id
2904 datacenters
= mydb
.get_rows(
2905 SELECT
=("dt.uuid as datacenter_tenant_id",),
2906 FROM
="datacenter_tenants as dt join tenants_datacenters as td on dt.uuid=td.datacenter_tenant_id "
2907 "join datacenters as d on d.uuid=dt.datacenter_id",
2909 if len(datacenters
) > 1:
2910 raise NfvoException("More than one datacenters found, try to identify with uuid", httperrors
.Conflict
)
2912 thread_id
= datacenters
[0]["datacenter_tenant_id"]
2913 thread
= vim_threads
["running"].get(thread_id
)
2915 raise NfvoException("datacenter '{}' not found".format(str(datacenter_id_name
)), httperrors
.Not_Found
)
2916 return thread_id
, thread
2917 except db_base_Exception
as e
:
2918 raise NfvoException("{} {}".format(type(e
).__name
__ , str(e
)), e
.http_code
)
2921 def get_datacenter_uuid(mydb
, tenant_id
, datacenter_id_name
):
2923 if utils
.check_valid_uuid(datacenter_id_name
):
2924 WHERE_dict
['d.uuid'] = datacenter_id_name
2926 WHERE_dict
['d.name'] = datacenter_id_name
2929 WHERE_dict
['nfvo_tenant_id'] = tenant_id
2930 from_
= "tenants_datacenters as td join datacenters as d on td.datacenter_id=d.uuid join datacenter_tenants as" \
2931 " dt on td.datacenter_tenant_id=dt.uuid"
2933 from_
= 'datacenters as d'
2934 vimaccounts
= mydb
.get_rows(FROM
=from_
, SELECT
=("d.uuid as uuid, d.name as name",), WHERE
=WHERE_dict
)
2935 if len(vimaccounts
) == 0:
2936 raise NfvoException("datacenter '{}' not found".format(str(datacenter_id_name
)), httperrors
.Not_Found
)
2937 elif len(vimaccounts
)>1:
2938 #print "nfvo.datacenter_action() error. Several datacenters found"
2939 raise NfvoException("More than one datacenters found, try to identify with uuid", httperrors
.Conflict
)
2940 return vimaccounts
[0]["uuid"], vimaccounts
[0]["name"]
2943 def get_datacenter_by_name_uuid(mydb
, tenant_id
, datacenter_id_name
=None, **extra_filter
):
2944 datacenter_id
= None
2945 datacenter_name
= None
2946 if datacenter_id_name
:
2947 if utils
.check_valid_uuid(datacenter_id_name
):
2948 datacenter_id
= datacenter_id_name
2950 datacenter_name
= datacenter_id_name
2951 vims
= get_vim(mydb
, tenant_id
, datacenter_id
, datacenter_name
, **extra_filter
)
2953 raise NfvoException("datacenter '{}' not found".format(str(datacenter_id_name
)), httperrors
.Not_Found
)
2955 #print "nfvo.datacenter_action() error. Several datacenters found"
2956 raise NfvoException("More than one datacenters found, try to identify with uuid", httperrors
.Conflict
)
2957 return vims
.keys()[0], vims
.values()[0]
2961 '''Takes dict d and updates it with the values in dict u.'''
2962 '''It merges all depth levels'''
2963 for k
, v
in u
.iteritems():
2964 if isinstance(v
, collections
.Mapping
):
2965 r
= update(d
.get(k
, {}), v
)
2972 def create_instance(mydb
, tenant_id
, instance_dict
):
2973 # print "Checking that nfvo_tenant_id exists and getting the VIM URI and the VIM tenant_id"
2974 # logger.debug("Creating instance...")
2975 scenario
= instance_dict
["scenario"]
2977 # find main datacenter
2979 myvim_threads_id
= {}
2980 datacenter
= instance_dict
.get("datacenter")
2981 default_datacenter_id
, vim
= get_datacenter_by_name_uuid(mydb
, tenant_id
, datacenter
)
2982 myvims
[default_datacenter_id
] = vim
2983 myvim_threads_id
[default_datacenter_id
], _
= get_vim_thread(mydb
, tenant_id
, default_datacenter_id
)
2984 tenant
= mydb
.get_rows_by_id('nfvo_tenants', tenant_id
)
2985 # myvim_tenant = myvim['tenant_id']
2988 # print "Checking that the scenario exists and getting the scenario dictionary"
2989 if isinstance(scenario
, str):
2990 scenarioDict
= mydb
.get_scenario(scenario
, tenant_id
, datacenter_vim_id
=myvim_threads_id
[default_datacenter_id
],
2991 datacenter_id
=default_datacenter_id
)
2993 scenarioDict
= scenario
2994 scenarioDict
["uuid"] = None
2996 # logger.debug(">>>>>> Dictionaries before merging")
2997 # logger.debug(">>>>>> InstanceDict:\n{}".format(yaml.safe_dump(instance_dict,default_flow_style=False, width=256)))
2998 # logger.debug(">>>>>> ScenarioDict:\n{}".format(yaml.safe_dump(scenarioDict,default_flow_style=False, width=256)))
3000 db_instance_vnfs
= []
3001 db_instance_vms
= []
3002 db_instance_interfaces
= []
3003 db_instance_sfis
= []
3004 db_instance_sfs
= []
3005 db_instance_classifications
= []
3006 db_instance_sfps
= []
3011 instance_name
= instance_dict
["name"]
3012 instance_uuid
= str(uuid4())
3013 uuid_list
.append(instance_uuid
)
3014 db_instance_scenario
= {
3015 "uuid": instance_uuid
,
3016 "name": instance_name
,
3017 "tenant_id": tenant_id
,
3018 "scenario_id": scenarioDict
['uuid'],
3019 "datacenter_id": default_datacenter_id
,
3020 # filled bellow 'datacenter_tenant_id'
3021 "description": instance_dict
.get("description"),
3023 if scenarioDict
.get("cloud-config"):
3024 db_instance_scenario
["cloud_config"] = yaml
.safe_dump(scenarioDict
["cloud-config"],
3025 default_flow_style
=True, width
=256)
3026 instance_action_id
= get_task_id()
3027 db_instance_action
= {
3028 "uuid": instance_action_id
, # same uuid for the instance and the action on create
3029 "tenant_id": tenant_id
,
3030 "instance_id": instance_uuid
,
3031 "description": "CREATE",
3034 # Auxiliary dictionaries from x to y
3035 sce_net2instance
= {}
3036 net2task_id
= {'scenario': {}}
3038 def ip_profile_IM2RO(ip_profile_im
):
3039 # translate from input format to database format
3041 if 'subnet-address' in ip_profile_im
:
3042 ip_profile_ro
['subnet_address'] = ip_profile_im
['subnet-address']
3043 if 'ip-version' in ip_profile_im
:
3044 ip_profile_ro
['ip_version'] = ip_profile_im
['ip-version']
3045 if 'gateway-address' in ip_profile_im
:
3046 ip_profile_ro
['gateway_address'] = ip_profile_im
['gateway-address']
3047 if 'dns-address' in ip_profile_im
:
3048 ip_profile_ro
['dns_address'] = ip_profile_im
['dns-address']
3049 if isinstance(ip_profile_ro
['dns_address'], (list, tuple)):
3050 ip_profile_ro
['dns_address'] = ";".join(ip_profile_ro
['dns_address'])
3051 if 'dhcp' in ip_profile_im
:
3052 ip_profile_ro
['dhcp_start_address'] = ip_profile_im
['dhcp'].get('start-address')
3053 ip_profile_ro
['dhcp_enabled'] = ip_profile_im
['dhcp'].get('enabled', True)
3054 ip_profile_ro
['dhcp_count'] = ip_profile_im
['dhcp'].get('count')
3055 return ip_profile_ro
3057 # logger.debug("Creating instance from scenario-dict:\n%s",
3058 # yaml.safe_dump(scenarioDict, indent=4, default_flow_style=False))
3060 # 0 check correct parameters
3061 for net_name
, net_instance_desc
in instance_dict
.get("networks", {}).iteritems():
3062 for scenario_net
in scenarioDict
['nets']:
3063 if net_name
== scenario_net
.get("name") or net_name
== scenario_net
.get("osm_id") or net_name
== scenario_net
.get("uuid"):
3066 raise NfvoException("Invalid scenario network name or id '{}' at instance:networks".format(net_name
),
3067 httperrors
.Bad_Request
)
3068 if "sites" not in net_instance_desc
:
3069 net_instance_desc
["sites"] = [ {} ]
3070 site_without_datacenter_field
= False
3071 for site
in net_instance_desc
["sites"]:
3072 if site
.get("datacenter"):
3073 site
["datacenter"], _
= get_datacenter_uuid(mydb
, tenant_id
, site
["datacenter"])
3074 if site
["datacenter"] not in myvims
:
3075 # Add this datacenter to myvims
3076 d
, v
= get_datacenter_by_name_uuid(mydb
, tenant_id
, site
["datacenter"])
3078 myvim_threads_id
[d
], _
= get_vim_thread(mydb
, tenant_id
, site
["datacenter"])
3079 site
["datacenter"] = d
# change name to id
3081 if site_without_datacenter_field
:
3082 raise NfvoException("Found more than one entries without datacenter field at "
3083 "instance:networks:{}:sites".format(net_name
), httperrors
.Bad_Request
)
3084 site_without_datacenter_field
= True
3085 site
["datacenter"] = default_datacenter_id
# change name to id
3087 for vnf_name
, vnf_instance_desc
in instance_dict
.get("vnfs",{}).iteritems():
3088 for scenario_vnf
in scenarioDict
['vnfs']:
3089 if vnf_name
== scenario_vnf
['member_vnf_index'] or vnf_name
== scenario_vnf
['uuid'] or vnf_name
== scenario_vnf
['name']:
3092 raise NfvoException("Invalid vnf name '{}' at instance:vnfs".format(vnf_name
), httperrors
.Bad_Request
)
3093 if "datacenter" in vnf_instance_desc
:
3094 # Add this datacenter to myvims
3095 vnf_instance_desc
["datacenter"], _
= get_datacenter_uuid(mydb
, tenant_id
, vnf_instance_desc
["datacenter"])
3096 if vnf_instance_desc
["datacenter"] not in myvims
:
3097 d
, v
= get_datacenter_by_name_uuid(mydb
, tenant_id
, vnf_instance_desc
["datacenter"])
3099 myvim_threads_id
[d
], _
= get_vim_thread(mydb
, tenant_id
, vnf_instance_desc
["datacenter"])
3100 scenario_vnf
["datacenter"] = vnf_instance_desc
["datacenter"]
3102 for net_id
, net_instance_desc
in vnf_instance_desc
.get("networks", {}).iteritems():
3103 for scenario_net
in scenario_vnf
['nets']:
3104 if net_id
== scenario_net
['osm_id'] or net_id
== scenario_net
['uuid'] or net_id
== scenario_net
["name"]:
3107 raise NfvoException("Invalid net id or name '{}' at instance:vnfs:networks".format(net_id
), httperrors
.Bad_Request
)
3108 if net_instance_desc
.get("vim-network-name"):
3109 scenario_net
["vim-network-name"] = net_instance_desc
["vim-network-name"]
3110 if net_instance_desc
.get("name"):
3111 scenario_net
["name"] = net_instance_desc
["name"]
3112 if 'ip-profile' in net_instance_desc
:
3113 ipprofile_db
= ip_profile_IM2RO(net_instance_desc
['ip-profile'])
3114 if 'ip_profile' not in scenario_net
:
3115 scenario_net
['ip_profile'] = ipprofile_db
3117 update(scenario_net
['ip_profile'], ipprofile_db
)
3119 for vdu_id
, vdu_instance_desc
in vnf_instance_desc
.get("vdus", {}).iteritems():
3120 for scenario_vm
in scenario_vnf
['vms']:
3121 if vdu_id
== scenario_vm
['osm_id'] or vdu_id
== scenario_vm
["name"]:
3124 raise NfvoException("Invalid vdu id or name '{}' at instance:vnfs:vdus".format(vdu_id
), httperrors
.Bad_Request
)
3125 scenario_vm
["instance_parameters"] = vdu_instance_desc
3126 for iface_id
, iface_instance_desc
in vdu_instance_desc
.get("interfaces", {}).iteritems():
3127 for scenario_interface
in scenario_vm
['interfaces']:
3128 if iface_id
== scenario_interface
['internal_name'] or iface_id
== scenario_interface
["external_name"]:
3129 scenario_interface
.update(iface_instance_desc
)
3132 raise NfvoException("Invalid vdu id or name '{}' at instance:vnfs:vdus".format(vdu_id
), httperrors
.Bad_Request
)
3134 # 0.1 parse cloud-config parameters
3135 cloud_config
= unify_cloud_config(instance_dict
.get("cloud-config"), scenarioDict
.get("cloud-config"))
3137 # 0.2 merge instance information into scenario
3138 # Ideally, the operation should be as simple as: update(scenarioDict,instance_dict)
3139 # However, this is not possible yet.
3140 for net_name
, net_instance_desc
in instance_dict
.get("networks", {}).iteritems():
3141 for scenario_net
in scenarioDict
['nets']:
3142 if net_name
== scenario_net
["name"]:
3143 if 'ip-profile' in net_instance_desc
:
3144 ipprofile_db
= ip_profile_IM2RO(net_instance_desc
['ip-profile'])
3145 if 'ip_profile' not in scenario_net
:
3146 scenario_net
['ip_profile'] = ipprofile_db
3148 update(scenario_net
['ip_profile'], ipprofile_db
)
3149 for interface
in net_instance_desc
.get('interfaces', ()):
3150 if 'ip_address' in interface
:
3151 for vnf
in scenarioDict
['vnfs']:
3152 if interface
['vnf'] == vnf
['name']:
3153 for vnf_interface
in vnf
['interfaces']:
3154 if interface
['vnf_interface'] == vnf_interface
['external_name']:
3155 vnf_interface
['ip_address'] = interface
['ip_address']
3157 # logger.debug(">>>>>>>> Merged dictionary")
3158 # logger.debug("Creating instance scenario-dict MERGED:\n%s",
3159 # yaml.safe_dump(scenarioDict, indent=4, default_flow_style=False))
3161 # 1. Creating new nets (sce_nets) in the VIM"
3162 number_mgmt_networks
= 0
3163 db_instance_nets
= []
3164 for sce_net
in scenarioDict
['nets']:
3165 sce_net_uuid
= sce_net
.get('uuid', sce_net
["name"])
3166 # get involved datacenters where this network need to be created
3167 involved_datacenters
= []
3168 for sce_vnf
in scenarioDict
.get("vnfs", ()):
3169 vnf_datacenter
= sce_vnf
.get("datacenter", default_datacenter_id
)
3170 if vnf_datacenter
in involved_datacenters
:
3172 if sce_vnf
.get("interfaces"):
3173 for sce_vnf_ifaces
in sce_vnf
["interfaces"]:
3174 if sce_vnf_ifaces
.get("sce_net_id") == sce_net
["uuid"]:
3175 involved_datacenters
.append(vnf_datacenter
)
3177 if not involved_datacenters
:
3178 involved_datacenters
.append(default_datacenter_id
)
3181 if instance_dict
.get("networks") and instance_dict
["networks"].get(sce_net
["name"]):
3182 descriptor_net
= instance_dict
["networks"][sce_net
["name"]]
3183 net_name
= descriptor_net
.get("vim-network-name")
3184 # add datacenters from instantiation parameters
3185 if descriptor_net
.get("sites"):
3186 for site
in descriptor_net
["sites"]:
3187 if site
.get("datacenter") and site
["datacenter"] not in involved_datacenters
:
3188 involved_datacenters
.append(site
["datacenter"])
3189 sce_net2instance
[sce_net_uuid
] = {}
3190 net2task_id
['scenario'][sce_net_uuid
] = {}
3192 if sce_net
["external"]:
3193 number_mgmt_networks
+= 1
3195 for datacenter_id
in involved_datacenters
:
3197 netmap_create
= None
3198 if descriptor_net
.get("sites"):
3199 for site
in descriptor_net
["sites"]:
3200 if site
.get("datacenter") == datacenter_id
:
3201 netmap_use
= site
.get("netmap-use")
3202 netmap_create
= site
.get("netmap-create")
3205 vim
= myvims
[datacenter_id
]
3206 myvim_thread_id
= myvim_threads_id
[datacenter_id
]
3208 net_type
= sce_net
['type']
3210 lookfor_filter
= {'admin_state_up': True, 'status': 'ACTIVE'} # 'shared': True
3213 if sce_net
["external"]:
3214 net_name
= sce_net
["name"]
3216 net_name
= "{}-{}".format(instance_name
, sce_net
["name"])
3217 net_name
= net_name
[:255] # limit length
3219 if netmap_use
or netmap_create
:
3220 create_network
= False
3221 lookfor_network
= False
3223 lookfor_network
= True
3224 if utils
.check_valid_uuid(netmap_use
):
3225 lookfor_filter
["id"] = netmap_use
3227 lookfor_filter
["name"] = netmap_use
3229 create_network
= True
3230 net_vim_name
= net_name
3231 if isinstance(netmap_create
, str):
3232 net_vim_name
= netmap_create
3233 elif sce_net
.get("vim_network_name"):
3234 create_network
= False
3235 lookfor_network
= True
3236 lookfor_filter
["name"] = sce_net
.get("vim_network_name")
3237 elif sce_net
["external"]:
3238 if sce_net
['vim_id'] is not None:
3239 # there is a netmap at datacenter_nets database # TODO REVISE!!!!
3240 create_network
= False
3241 lookfor_network
= True
3242 lookfor_filter
["id"] = sce_net
['vim_id']
3243 elif vim
["config"].get("management_network_id") or vim
["config"].get("management_network_name"):
3244 if number_mgmt_networks
> 1:
3245 raise NfvoException("Found several VLD of type mgmt. "
3246 "You must concrete what vim-network must be use for each one",
3247 httperrors
.Bad_Request
)
3248 create_network
= False
3249 lookfor_network
= True
3250 if vim
["config"].get("management_network_id"):
3251 lookfor_filter
["id"] = vim
["config"]["management_network_id"]
3253 lookfor_filter
["name"] = vim
["config"]["management_network_name"]
3255 # There is not a netmap, look at datacenter for a net with this name and create if not found
3256 create_network
= True
3257 lookfor_network
= True
3258 lookfor_filter
["name"] = sce_net
["name"]
3259 net_vim_name
= sce_net
["name"]
3261 net_vim_name
= net_name
3262 create_network
= True
3263 lookfor_network
= False
3267 task_action
= "CREATE"
3268 task_extra
["params"] = (net_vim_name
, net_type
, sce_net
.get('ip_profile', None))
3270 task_extra
["find"] = (lookfor_filter
,)
3271 elif lookfor_network
:
3272 task_action
= "FIND"
3273 task_extra
["params"] = (lookfor_filter
,)
3275 # fill database content
3276 net_uuid
= str(uuid4())
3277 uuid_list
.append(net_uuid
)
3278 sce_net2instance
[sce_net_uuid
][datacenter_id
] = net_uuid
3282 "vim_name": net_vim_name
,
3283 "instance_scenario_id": instance_uuid
,
3284 "sce_net_id": sce_net
.get("uuid"),
3285 "created": create_network
,
3286 'datacenter_id': datacenter_id
,
3287 'datacenter_tenant_id': myvim_thread_id
,
3288 'status': 'BUILD' # if create_network else "ACTIVE"
3290 db_instance_nets
.append(db_net
)
3292 "instance_action_id": instance_action_id
,
3293 "status": "SCHEDULED",
3294 "task_index": task_index
,
3295 "datacenter_vim_id": myvim_thread_id
,
3296 "action": task_action
,
3297 "item": "instance_nets",
3298 "item_id": net_uuid
,
3299 "extra": yaml
.safe_dump(task_extra
, default_flow_style
=True, width
=256)
3301 net2task_id
['scenario'][sce_net_uuid
][datacenter_id
] = task_index
3303 db_vim_actions
.append(db_vim_action
)
3305 if 'ip_profile' in sce_net
:
3307 'instance_net_id': net_uuid
,
3308 'ip_version': sce_net
['ip_profile']['ip_version'],
3309 'subnet_address': sce_net
['ip_profile']['subnet_address'],
3310 'gateway_address': sce_net
['ip_profile']['gateway_address'],
3311 'dns_address': sce_net
['ip_profile']['dns_address'],
3312 'dhcp_enabled': sce_net
['ip_profile']['dhcp_enabled'],
3313 'dhcp_start_address': sce_net
['ip_profile']['dhcp_start_address'],
3314 'dhcp_count': sce_net
['ip_profile']['dhcp_count'],
3316 db_ip_profiles
.append(db_ip_profile
)
3320 "default_datacenter_id": default_datacenter_id
,
3321 "myvim_threads_id": myvim_threads_id
,
3322 "instance_uuid": instance_uuid
,
3323 "instance_name": instance_name
,
3324 "instance_action_id": instance_action_id
,
3326 "cloud_config": cloud_config
,
3327 "RO_pub_key": tenant
[0].get('RO_pub_key'),
3328 "instance_parameters": instance_dict
,
3331 "task_index": task_index
,
3332 "uuid_list": uuid_list
,
3333 "db_instance_nets": db_instance_nets
,
3334 "db_vim_actions": db_vim_actions
,
3335 "db_ip_profiles": db_ip_profiles
,
3336 "db_instance_vnfs": db_instance_vnfs
,
3337 "db_instance_vms": db_instance_vms
,
3338 "db_instance_interfaces": db_instance_interfaces
,
3339 "net2task_id": net2task_id
,
3340 "sce_net2instance": sce_net2instance
,
3342 # sce_vnf_list = sorted(scenarioDict['vnfs'], key=lambda k: k['name'])
3343 for sce_vnf
in scenarioDict
.get('vnfs', ()): # sce_vnf_list:
3344 instantiate_vnf(mydb
, sce_vnf
, vnf_params
, vnf_params_out
, rollbackList
)
3345 task_index
= vnf_params_out
["task_index"]
3346 uuid_list
= vnf_params_out
["uuid_list"]
3349 # task_depends_on = []
3350 for vnffg
in scenarioDict
.get('vnffgs', ()):
3351 for rsp
in vnffg
['rsps']:
3353 for cp
in rsp
['connection_points']:
3354 count
= mydb
.get_rows(
3355 SELECT
=('vms.count'),
3356 FROM
="vms join interfaces on vms.uuid=interfaces.vm_id join sce_rsp_hops as h on interfaces.uuid=h.interface_id",
3357 WHERE
={'h.uuid': cp
['uuid']})[0]['count']
3358 instance_vnf
= next((item
for item
in db_instance_vnfs
if item
['sce_vnf_id'] == cp
['sce_vnf_id']), None)
3359 instance_vms
= [item
for item
in db_instance_vms
if item
['instance_vnf_id'] == instance_vnf
['uuid']]
3361 for instance_vm
in instance_vms
:
3362 action
= next((item
for item
in db_vim_actions
if item
['item_id'] == instance_vm
['uuid']), None)
3364 dependencies
.append(action
['task_index'])
3365 # TODO: throw exception if count != len(instance_vms)
3366 # TODO: and action shouldn't ever be None
3368 for i
in range(count
):
3370 sfi_uuid
= str(uuid4())
3371 uuid_list
.append(sfi_uuid
)
3374 "instance_scenario_id": instance_uuid
,
3375 'sce_rsp_hop_id': cp
['uuid'],
3376 'datacenter_id': datacenter_id
,
3377 'datacenter_tenant_id': myvim_thread_id
,
3378 "vim_sfi_id": None, # vim thread will populate
3380 db_instance_sfis
.append(db_sfi
)
3382 "instance_action_id": instance_action_id
,
3383 "task_index": task_index
,
3384 "datacenter_vim_id": myvim_thread_id
,
3386 "status": "SCHEDULED",
3387 "item": "instance_sfis",
3388 "item_id": sfi_uuid
,
3389 "extra": yaml
.safe_dump({"params": "", "depends_on": [dependencies
[i
]]},
3390 default_flow_style
=True, width
=256)
3392 sfis_created
.append(task_index
)
3394 db_vim_actions
.append(db_vim_action
)
3396 sf_uuid
= str(uuid4())
3397 uuid_list
.append(sf_uuid
)
3400 "instance_scenario_id": instance_uuid
,
3401 'sce_rsp_hop_id': cp
['uuid'],
3402 'datacenter_id': datacenter_id
,
3403 'datacenter_tenant_id': myvim_thread_id
,
3404 "vim_sf_id": None, # vim thread will populate
3406 db_instance_sfs
.append(db_sf
)
3408 "instance_action_id": instance_action_id
,
3409 "task_index": task_index
,
3410 "datacenter_vim_id": myvim_thread_id
,
3412 "status": "SCHEDULED",
3413 "item": "instance_sfs",
3415 "extra": yaml
.safe_dump({"params": "", "depends_on": sfis_created
},
3416 default_flow_style
=True, width
=256)
3418 sfs_created
.append(task_index
)
3420 db_vim_actions
.append(db_vim_action
)
3421 classifier
= rsp
['classifier']
3423 # TODO the following ~13 lines can be reused for the sfi case
3424 count
= mydb
.get_rows(
3425 SELECT
=('vms.count'),
3426 FROM
="vms join interfaces on vms.uuid=interfaces.vm_id join sce_classifiers as c on interfaces.uuid=c.interface_id",
3427 WHERE
={'c.uuid': classifier
['uuid']})[0]['count']
3428 instance_vnf
= next((item
for item
in db_instance_vnfs
if item
['sce_vnf_id'] == classifier
['sce_vnf_id']), None)
3429 instance_vms
= [item
for item
in db_instance_vms
if item
['instance_vnf_id'] == instance_vnf
['uuid']]
3431 for instance_vm
in instance_vms
:
3432 action
= next((item
for item
in db_vim_actions
if item
['item_id'] == instance_vm
['uuid']), None)
3434 dependencies
.append(action
['task_index'])
3435 # TODO: throw exception if count != len(instance_vms)
3436 # TODO: and action shouldn't ever be None
3437 classifications_created
= []
3438 for i
in range(count
):
3439 for match
in classifier
['matches']:
3440 # create classifications
3441 classification_uuid
= str(uuid4())
3442 uuid_list
.append(classification_uuid
)
3443 db_classification
= {
3444 "uuid": classification_uuid
,
3445 "instance_scenario_id": instance_uuid
,
3446 'sce_classifier_match_id': match
['uuid'],
3447 'datacenter_id': datacenter_id
,
3448 'datacenter_tenant_id': myvim_thread_id
,
3449 "vim_classification_id": None, # vim thread will populate
3451 db_instance_classifications
.append(db_classification
)
3452 classification_params
= {
3453 "ip_proto": match
["ip_proto"],
3454 "source_ip": match
["source_ip"],
3455 "destination_ip": match
["destination_ip"],
3456 "source_port": match
["source_port"],
3457 "destination_port": match
["destination_port"]
3460 "instance_action_id": instance_action_id
,
3461 "task_index": task_index
,
3462 "datacenter_vim_id": myvim_thread_id
,
3464 "status": "SCHEDULED",
3465 "item": "instance_classifications",
3466 "item_id": classification_uuid
,
3467 "extra": yaml
.safe_dump({"params": classification_params
, "depends_on": [dependencies
[i
]]},
3468 default_flow_style
=True, width
=256)
3470 classifications_created
.append(task_index
)
3472 db_vim_actions
.append(db_vim_action
)
3475 sfp_uuid
= str(uuid4())
3476 uuid_list
.append(sfp_uuid
)
3479 "instance_scenario_id": instance_uuid
,
3480 'sce_rsp_id': rsp
['uuid'],
3481 'datacenter_id': datacenter_id
,
3482 'datacenter_tenant_id': myvim_thread_id
,
3483 "vim_sfp_id": None, # vim thread will populate
3485 db_instance_sfps
.append(db_sfp
)
3487 "instance_action_id": instance_action_id
,
3488 "task_index": task_index
,
3489 "datacenter_vim_id": myvim_thread_id
,
3491 "status": "SCHEDULED",
3492 "item": "instance_sfps",
3493 "item_id": sfp_uuid
,
3494 "extra": yaml
.safe_dump({"params": "", "depends_on": sfs_created
+ classifications_created
},
3495 default_flow_style
=True, width
=256)
3498 db_vim_actions
.append(db_vim_action
)
3499 db_instance_action
["number_tasks"] = task_index
3502 wan_links
= wim_engine
.derive_wan_links(db_instance_nets
, tenant_id
)
3503 wim_actions
= wim_engine
.create_actions(wan_links
)
3504 wim_actions
, db_instance_action
= (
3505 wim_engine
.incorporate_actions(wim_actions
, db_instance_action
))
3508 scenarioDict
["datacenter2tenant"] = myvim_threads_id
3510 db_instance_scenario
['datacenter_tenant_id'] = myvim_threads_id
[default_datacenter_id
]
3511 db_instance_scenario
['datacenter_id'] = default_datacenter_id
3513 {"instance_scenarios": db_instance_scenario
},
3514 {"instance_vnfs": db_instance_vnfs
},
3515 {"instance_nets": db_instance_nets
},
3516 {"ip_profiles": db_ip_profiles
},
3517 {"instance_vms": db_instance_vms
},
3518 {"instance_interfaces": db_instance_interfaces
},
3519 {"instance_actions": db_instance_action
},
3520 {"instance_sfis": db_instance_sfis
},
3521 {"instance_sfs": db_instance_sfs
},
3522 {"instance_classifications": db_instance_classifications
},
3523 {"instance_sfps": db_instance_sfps
},
3524 {"instance_wim_nets": wan_links
},
3525 {"vim_wim_actions": db_vim_actions
+ wim_actions
}
3528 logger
.debug("create_instance done DB tables: %s",
3529 yaml
.safe_dump(db_tables
, indent
=4, default_flow_style
=False) )
3530 mydb
.new_rows(db_tables
, uuid_list
)
3531 for myvim_thread_id
in myvim_threads_id
.values():
3532 vim_threads
["running"][myvim_thread_id
].insert_task(db_vim_actions
)
3534 wim_engine
.dispatch(wim_actions
)
3536 returned_instance
= mydb
.get_instance_scenario(instance_uuid
)
3537 returned_instance
["action_id"] = instance_action_id
3538 return returned_instance
3539 except (NfvoException
, vimconn
.vimconnException
, db_base_Exception
) as e
:
3540 message
= rollback(mydb
, myvims
, rollbackList
)
3541 if isinstance(e
, db_base_Exception
):
3542 error_text
= "database Exception"
3543 elif isinstance(e
, vimconn
.vimconnException
):
3544 error_text
= "VIM Exception"
3546 error_text
= "Exception"
3547 error_text
+= " {} {}. {}".format(type(e
).__name
__, str(e
), message
)
3548 # logger.error("create_instance: %s", error_text)
3550 raise NfvoException(error_text
, e
.http_code
)
3553 def instantiate_vnf(mydb
, sce_vnf
, params
, params_out
, rollbackList
):
3554 default_datacenter_id
= params
["default_datacenter_id"]
3555 myvim_threads_id
= params
["myvim_threads_id"]
3556 instance_uuid
= params
["instance_uuid"]
3557 instance_name
= params
["instance_name"]
3558 instance_action_id
= params
["instance_action_id"]
3559 myvims
= params
["myvims"]
3560 cloud_config
= params
["cloud_config"]
3561 RO_pub_key
= params
["RO_pub_key"]
3563 task_index
= params_out
["task_index"]
3564 uuid_list
= params_out
["uuid_list"]
3565 db_instance_nets
= params_out
["db_instance_nets"]
3566 db_vim_actions
= params_out
["db_vim_actions"]
3567 db_ip_profiles
= params_out
["db_ip_profiles"]
3568 db_instance_vnfs
= params_out
["db_instance_vnfs"]
3569 db_instance_vms
= params_out
["db_instance_vms"]
3570 db_instance_interfaces
= params_out
["db_instance_interfaces"]
3571 net2task_id
= params_out
["net2task_id"]
3572 sce_net2instance
= params_out
["sce_net2instance"]
3574 vnf_net2instance
= {}
3576 # 2. Creating new nets (vnf internal nets) in the VIM"
3577 # For each vnf net, we create it and we add it to instanceNetlist.
3578 if sce_vnf
.get("datacenter"):
3579 datacenter_id
= sce_vnf
["datacenter"]
3580 myvim_thread_id
= myvim_threads_id
[sce_vnf
["datacenter"]]
3582 datacenter_id
= default_datacenter_id
3583 myvim_thread_id
= myvim_threads_id
[default_datacenter_id
]
3584 for net
in sce_vnf
['nets']:
3586 # descriptor_net = instance_dict.get("vnfs", {}).get(sce_vnf["name"], {})
3587 # net_name = descriptor_net.get("name")
3590 net_name
= "{}-{}".format(instance_name
, net
["name"])
3591 net_name
= net_name
[:255] # limit length
3592 net_type
= net
['type']
3594 if sce_vnf
['uuid'] not in vnf_net2instance
:
3595 vnf_net2instance
[sce_vnf
['uuid']] = {}
3596 if sce_vnf
['uuid'] not in net2task_id
:
3597 net2task_id
[sce_vnf
['uuid']] = {}
3598 net2task_id
[sce_vnf
['uuid']][net
['uuid']] = task_index
3600 # fill database content
3601 net_uuid
= str(uuid4())
3602 uuid_list
.append(net_uuid
)
3603 vnf_net2instance
[sce_vnf
['uuid']][net
['uuid']] = net_uuid
3607 "vim_name": net_name
,
3608 "instance_scenario_id": instance_uuid
,
3609 "net_id": net
["uuid"],
3611 'datacenter_id': datacenter_id
,
3612 'datacenter_tenant_id': myvim_thread_id
,
3614 db_instance_nets
.append(db_net
)
3616 if net
.get("vim-network-name"):
3617 lookfor_filter
= {"name": net
["vim-network-name"]}
3618 task_action
= "FIND"
3619 task_extra
= {"params": (lookfor_filter
,)}
3621 task_action
= "CREATE"
3622 task_extra
= {"params": (net_name
, net_type
, net
.get('ip_profile', None))}
3625 "instance_action_id": instance_action_id
,
3626 "task_index": task_index
,
3627 "datacenter_vim_id": myvim_thread_id
,
3628 "status": "SCHEDULED",
3629 "action": task_action
,
3630 "item": "instance_nets",
3631 "item_id": net_uuid
,
3632 "extra": yaml
.safe_dump(task_extra
, default_flow_style
=True, width
=256)
3635 db_vim_actions
.append(db_vim_action
)
3637 if 'ip_profile' in net
:
3639 'instance_net_id': net_uuid
,
3640 'ip_version': net
['ip_profile']['ip_version'],
3641 'subnet_address': net
['ip_profile']['subnet_address'],
3642 'gateway_address': net
['ip_profile']['gateway_address'],
3643 'dns_address': net
['ip_profile']['dns_address'],
3644 'dhcp_enabled': net
['ip_profile']['dhcp_enabled'],
3645 'dhcp_start_address': net
['ip_profile']['dhcp_start_address'],
3646 'dhcp_count': net
['ip_profile']['dhcp_count'],
3648 db_ip_profiles
.append(db_ip_profile
)
3650 # print "vnf_net2instance:"
3651 # print yaml.safe_dump(vnf_net2instance, indent=4, default_flow_style=False)
3653 # 3. Creating new vm instances in the VIM
3654 # myvim.new_vminstance(self,vimURI,tenant_id,name,description,image_id,flavor_id,net_dict)
3656 if sce_vnf
.get('mgmt_access'):
3657 ssh_access
= sce_vnf
['mgmt_access'].get('config-access', {}).get('ssh-access')
3658 vnf_availability_zones
= []
3659 for vm
in sce_vnf
.get('vms'):
3660 vm_av
= vm
.get('availability_zone')
3661 if vm_av
and vm_av
not in vnf_availability_zones
:
3662 vnf_availability_zones
.append(vm_av
)
3664 # check if there is enough availability zones available at vim level.
3665 if myvims
[datacenter_id
].availability_zone
and vnf_availability_zones
:
3666 if len(vnf_availability_zones
) > len(myvims
[datacenter_id
].availability_zone
):
3667 raise NfvoException('No enough availability zones at VIM for this deployment', httperrors
.Bad_Request
)
3669 if sce_vnf
.get("datacenter"):
3670 vim
= myvims
[sce_vnf
["datacenter"]]
3671 myvim_thread_id
= myvim_threads_id
[sce_vnf
["datacenter"]]
3672 datacenter_id
= sce_vnf
["datacenter"]
3674 vim
= myvims
[default_datacenter_id
]
3675 myvim_thread_id
= myvim_threads_id
[default_datacenter_id
]
3676 datacenter_id
= default_datacenter_id
3677 sce_vnf
["datacenter_id"] = datacenter_id
3680 vnf_uuid
= str(uuid4())
3681 uuid_list
.append(vnf_uuid
)
3684 'instance_scenario_id': instance_uuid
,
3685 'vnf_id': sce_vnf
['vnf_id'],
3686 'sce_vnf_id': sce_vnf
['uuid'],
3687 'datacenter_id': datacenter_id
,
3688 'datacenter_tenant_id': myvim_thread_id
,
3690 db_instance_vnfs
.append(db_instance_vnf
)
3692 for vm
in sce_vnf
['vms']:
3694 if vm
.get("pdu_type"):
3698 sce_vnf_name
= sce_vnf
['member_vnf_index'] if sce_vnf
['member_vnf_index'] else sce_vnf
['name']
3699 myVMDict
['name'] = "{}-{}-{}".format(instance_name
[:64], sce_vnf_name
[:64], vm
["name"][:64])
3700 myVMDict
['description'] = myVMDict
['name'][0:99]
3702 # myVMDict['start'] = "no"
3703 if vm
.get("instance_parameters") and vm
["instance_parameters"].get("name"):
3704 myVMDict
['name'] = vm
["instance_parameters"].get("name")
3705 myVMDict
['name'] = myVMDict
['name'][0:255] # limit name length
3706 # create image at vim in case it not exist
3707 image_uuid
= vm
['image_id']
3708 if vm
.get("image_list"):
3709 for alternative_image
in vm
["image_list"]:
3710 if alternative_image
["vim_type"] == vim
["config"]["_vim_type_internal"]:
3711 image_uuid
= alternative_image
['image_id']
3713 image_dict
= mydb
.get_table_by_uuid_name("images", image_uuid
)
3714 image_id
= create_or_use_image(mydb
, {datacenter_id
: vim
}, image_dict
, [], True)
3715 vm
['vim_image_id'] = image_id
3717 # create flavor at vim in case it not exist
3718 flavor_dict
= mydb
.get_table_by_uuid_name("flavors", vm
['flavor_id'])
3719 if flavor_dict
['extended'] != None:
3720 flavor_dict
['extended'] = yaml
.load(flavor_dict
['extended'])
3721 flavor_id
= create_or_use_flavor(mydb
, {datacenter_id
: vim
}, flavor_dict
, rollbackList
, True)
3723 # Obtain information for additional disks
3724 extended_flavor_dict
= mydb
.get_rows(FROM
='datacenters_flavors', SELECT
=('extended',),
3725 WHERE
={'vim_id': flavor_id
})
3726 if not extended_flavor_dict
:
3727 raise NfvoException("flavor '{}' not found".format(flavor_id
), httperrors
.Not_Found
)
3729 # extended_flavor_dict_yaml = yaml.load(extended_flavor_dict[0])
3730 myVMDict
['disks'] = None
3731 extended_info
= extended_flavor_dict
[0]['extended']
3732 if extended_info
!= None:
3733 extended_flavor_dict_yaml
= yaml
.load(extended_info
)
3734 if 'disks' in extended_flavor_dict_yaml
:
3735 myVMDict
['disks'] = extended_flavor_dict_yaml
['disks']
3736 if vm
.get("instance_parameters") and vm
["instance_parameters"].get("devices"):
3737 for disk
in myVMDict
['disks']:
3738 if disk
.get("name") in vm
["instance_parameters"]["devices"]:
3739 disk
.update(vm
["instance_parameters"]["devices"][disk
.get("name")])
3741 vm
['vim_flavor_id'] = flavor_id
3742 myVMDict
['imageRef'] = vm
['vim_image_id']
3743 myVMDict
['flavorRef'] = vm
['vim_flavor_id']
3744 myVMDict
['availability_zone'] = vm
.get('availability_zone')
3745 myVMDict
['networks'] = []
3746 task_depends_on
= []
3747 # TODO ALF. connect_mgmt_interfaces. Connect management interfaces if this is true
3748 is_management_vm
= False
3750 for iface
in vm
['interfaces']:
3752 if iface
['type'] == "data":
3753 netDict
['type'] = iface
['model']
3754 elif "model" in iface
and iface
["model"] != None:
3755 netDict
['model'] = iface
['model']
3756 # TODO in future, remove this because mac_address will not be set, and the type of PV,VF
3757 # is obtained from iterface table model
3758 # discover type of interface looking at flavor
3759 for numa
in flavor_dict
.get('extended', {}).get('numas', []):
3760 for flavor_iface
in numa
.get('interfaces', []):
3761 if flavor_iface
.get('name') == iface
['internal_name']:
3762 if flavor_iface
['dedicated'] == 'yes':
3763 netDict
['type'] = "PF" # passthrough
3764 elif flavor_iface
['dedicated'] == 'no':
3765 netDict
['type'] = "VF" # siov
3766 elif flavor_iface
['dedicated'] == 'yes:sriov':
3767 netDict
['type'] = "VFnotShared" # sriov but only one sriov on the PF
3768 netDict
["mac_address"] = flavor_iface
.get("mac_address")
3770 netDict
["use"] = iface
['type']
3771 if netDict
["use"] == "data" and not netDict
.get("type"):
3772 # print "netDict", netDict
3773 # print "iface", iface
3774 e_text
= "Cannot determine the interface type PF or VF of VNF '{}' VM '{}' iface '{}'".fromat(
3775 sce_vnf
['name'], vm
['name'], iface
['internal_name'])
3776 if flavor_dict
.get('extended') == None:
3777 raise NfvoException(e_text
+ "After database migration some information is not available. \
3778 Try to delete and create the scenarios and VNFs again", httperrors
.Conflict
)
3780 raise NfvoException(e_text
, httperrors
.Internal_Server_Error
)
3781 if netDict
["use"] == "mgmt":
3782 is_management_vm
= True
3783 netDict
["type"] = "virtual"
3784 if netDict
["use"] == "bridge":
3785 netDict
["type"] = "virtual"
3786 if iface
.get("vpci"):
3787 netDict
['vpci'] = iface
['vpci']
3788 if iface
.get("mac"):
3789 netDict
['mac_address'] = iface
['mac']
3790 if iface
.get("mac_address"):
3791 netDict
['mac_address'] = iface
['mac_address']
3792 if iface
.get("ip_address"):
3793 netDict
['ip_address'] = iface
['ip_address']
3794 if iface
.get("port-security") is not None:
3795 netDict
['port_security'] = iface
['port-security']
3796 if iface
.get("floating-ip") is not None:
3797 netDict
['floating_ip'] = iface
['floating-ip']
3798 netDict
['name'] = iface
['internal_name']
3799 if iface
['net_id'] is None:
3800 for vnf_iface
in sce_vnf
["interfaces"]:
3803 if vnf_iface
['interface_id'] == iface
['uuid']:
3804 netDict
['net_id'] = "TASK-{}".format(
3805 net2task_id
['scenario'][vnf_iface
['sce_net_id']][datacenter_id
])
3806 instance_net_id
= sce_net2instance
[vnf_iface
['sce_net_id']][datacenter_id
]
3807 task_depends_on
.append(net2task_id
['scenario'][vnf_iface
['sce_net_id']][datacenter_id
])
3810 netDict
['net_id'] = "TASK-{}".format(net2task_id
[sce_vnf
['uuid']][iface
['net_id']])
3811 instance_net_id
= vnf_net2instance
[sce_vnf
['uuid']][iface
['net_id']]
3812 task_depends_on
.append(net2task_id
[sce_vnf
['uuid']][iface
['net_id']])
3813 # skip bridge ifaces not connected to any net
3814 if 'net_id' not in netDict
or netDict
['net_id'] == None:
3816 myVMDict
['networks'].append(netDict
)
3819 # 'instance_vm_id': instance_vm_uuid,
3820 "instance_net_id": instance_net_id
,
3821 'interface_id': iface
['uuid'],
3822 # 'vim_interface_id': ,
3823 'type': 'external' if iface
['external_name'] is not None else 'internal',
3824 'ip_address': iface
.get('ip_address'),
3825 'mac_address': iface
.get('mac'),
3826 'floating_ip': int(iface
.get('floating-ip', False)),
3827 'port_security': int(iface
.get('port-security', True))
3829 db_vm_ifaces
.append(db_vm_iface
)
3830 # print ">>>>>>>>>>>>>>>>>>>>>>>>>>>"
3831 # print myVMDict['name']
3832 # print "networks", yaml.safe_dump(myVMDict['networks'], indent=4, default_flow_style=False)
3833 # print "interfaces", yaml.safe_dump(vm['interfaces'], indent=4, default_flow_style=False)
3834 # print ">>>>>>>>>>>>>>>>>>>>>>>>>>>"
3836 # We add the RO key to cloud_config if vnf will need ssh access
3837 cloud_config_vm
= cloud_config
3838 if is_management_vm
and params
["instance_parameters"].get("mgmt_keys"):
3839 cloud_config_vm
= unify_cloud_config({"key-pairs": params
["instance_parameters"]["mgmt_keys"]},
3842 if vm
.get("instance_parameters") and vm
["instance_parameters"].get("mgmt_keys"):
3843 cloud_config_vm
= unify_cloud_config({"key-pairs": vm
["instance_parameters"]["mgmt_keys"]},
3845 # if ssh_access and ssh_access['required'] and ssh_access['default-user'] and tenant[0].get('RO_pub_key'):
3846 # RO_key = {"key-pairs": [tenant[0]['RO_pub_key']]}
3847 # cloud_config_vm = unify_cloud_config(cloud_config_vm, RO_key)
3848 if vm
.get("boot_data"):
3849 cloud_config_vm
= unify_cloud_config(vm
["boot_data"], cloud_config_vm
)
3851 if myVMDict
.get('availability_zone'):
3852 av_index
= vnf_availability_zones
.index(myVMDict
['availability_zone'])
3855 for vm_index
in range(0, vm
.get('count', 1)):
3856 vm_name
= myVMDict
['name'] + "-" + str(vm_index
+1)
3857 task_params
= (vm_name
, myVMDict
['description'], myVMDict
.get('start', None),
3858 myVMDict
['imageRef'], myVMDict
['flavorRef'], myVMDict
['networks'], cloud_config_vm
,
3859 myVMDict
['disks'], av_index
, vnf_availability_zones
)
3860 # put interface uuid back to scenario[vnfs][vms[[interfaces]
3861 for net
in myVMDict
['networks']:
3863 for iface
in vm
['interfaces']:
3864 if net
["name"] == iface
["internal_name"]:
3865 iface
["vim_id"] = net
["vim_id"]
3867 vm_uuid
= str(uuid4())
3868 uuid_list
.append(vm_uuid
)
3871 'instance_vnf_id': vnf_uuid
,
3872 # TODO delete "vim_vm_id": vm_id,
3873 "vm_id": vm
["uuid"],
3874 "vim_name": vm_name
,
3877 db_instance_vms
.append(db_vm
)
3880 for db_vm_iface
in db_vm_ifaces
:
3881 iface_uuid
= str(uuid4())
3882 uuid_list
.append(iface_uuid
)
3883 db_vm_iface_instance
= {
3885 "instance_vm_id": vm_uuid
3887 db_vm_iface_instance
.update(db_vm_iface
)
3888 if db_vm_iface_instance
.get("ip_address"): # increment ip_address
3889 ip
= db_vm_iface_instance
.get("ip_address")
3894 ip
= ip
[i
:] + str(int(ip
[:i
]) + 1)
3895 db_vm_iface_instance
["ip_address"] = ip
3897 db_vm_iface_instance
["ip_address"] = None
3898 db_instance_interfaces
.append(db_vm_iface_instance
)
3899 myVMDict
['networks'][iface_index
]["uuid"] = iface_uuid
3903 "instance_action_id": instance_action_id
,
3904 "task_index": task_index
,
3905 "datacenter_vim_id": myvim_thread_id
,
3907 "status": "SCHEDULED",
3908 "item": "instance_vms",
3910 "extra": yaml
.safe_dump({"params": task_params
, "depends_on": task_depends_on
},
3911 default_flow_style
=True, width
=256)
3914 db_vim_actions
.append(db_vim_action
)
3915 params_out
["task_index"] = task_index
3916 params_out
["uuid_list"] = uuid_list
3919 def delete_instance(mydb
, tenant_id
, instance_id
):
3920 # print "Checking that the instance_id exists and getting the instance dictionary"
3921 instanceDict
= mydb
.get_instance_scenario(instance_id
, tenant_id
)
3922 # print yaml.safe_dump(instanceDict, indent=4, default_flow_style=False)
3923 tenant_id
= instanceDict
["tenant_id"]
3926 # We need to retrieve the WIM Actions now, before the instance_scenario is
3927 # deleted. The reason for that is that: ON CASCADE rules will delete the
3928 # instance_wim_nets record in the database
3929 wim_actions
= wim_engine
.delete_actions(instance_scenario_id
=instance_id
)
3932 # print "Checking that nfvo_tenant_id exists and getting the VIM URI and the VIM tenant_id"
3933 # 1. Delete from Database
3934 message
= mydb
.delete_instance_scenario(instance_id
, tenant_id
)
3936 # 2. delete from VIM
3940 vimthread_affected
= {}
3941 net2vm_dependencies
= {}
3944 instance_action_id
= get_task_id()
3946 db_instance_action
= {
3947 "uuid": instance_action_id
, # same uuid for the instance and the action on create
3948 "tenant_id": tenant_id
,
3949 "instance_id": instance_id
,
3950 "description": "DELETE",
3951 # "number_tasks": 0 # filled bellow
3954 # 2.1 deleting VNFFGs
3955 for sfp
in instanceDict
.get('sfps', ()):
3956 vimthread_affected
[sfp
["datacenter_tenant_id"]] = None
3957 datacenter_key
= (sfp
["datacenter_id"], sfp
["datacenter_tenant_id"])
3958 if datacenter_key
not in myvims
:
3960 _
, myvim_thread
= get_vim_thread(mydb
, tenant_id
, sfp
["datacenter_id"], sfp
["datacenter_tenant_id"])
3961 except NfvoException
as e
:
3962 logger
.error(str(e
))
3964 myvim_threads
[datacenter_key
] = myvim_thread
3965 vims
= get_vim(mydb
, tenant_id
, datacenter_id
=sfp
["datacenter_id"],
3966 datacenter_tenant_id
=sfp
["datacenter_tenant_id"])
3968 logger
.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(sfp
["datacenter_id"], sfp
["datacenter_tenant_id"]))
3969 myvims
[datacenter_key
] = None
3971 myvims
[datacenter_key
] = vims
.values()[0]
3972 myvim
= myvims
[datacenter_key
]
3973 myvim_thread
= myvim_threads
[datacenter_key
]
3976 error_msg
+= "\n vim_sfp_id={} cannot be deleted because datacenter={} not found".format(sfp
['vim_sfp_id'], sfp
["datacenter_id"])
3978 extra
= {"params": (sfp
['vim_sfp_id'])}
3980 "instance_action_id": instance_action_id
,
3981 "task_index": task_index
,
3982 "datacenter_vim_id": sfp
["datacenter_tenant_id"],
3984 "status": "SCHEDULED",
3985 "item": "instance_sfps",
3986 "item_id": sfp
["uuid"],
3987 "extra": yaml
.safe_dump(extra
, default_flow_style
=True, width
=256)
3990 db_vim_actions
.append(db_vim_action
)
3992 for classification
in instanceDict
['classifications']:
3993 vimthread_affected
[classification
["datacenter_tenant_id"]] = None
3994 datacenter_key
= (classification
["datacenter_id"], classification
["datacenter_tenant_id"])
3995 if datacenter_key
not in myvims
:
3997 _
, myvim_thread
= get_vim_thread(mydb
, tenant_id
, classification
["datacenter_id"], classification
["datacenter_tenant_id"])
3998 except NfvoException
as e
:
3999 logger
.error(str(e
))
4001 myvim_threads
[datacenter_key
] = myvim_thread
4002 vims
= get_vim(mydb
, tenant_id
, datacenter_id
=classification
["datacenter_id"],
4003 datacenter_tenant_id
=classification
["datacenter_tenant_id"])
4005 logger
.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(classification
["datacenter_id"],
4006 classification
["datacenter_tenant_id"]))
4007 myvims
[datacenter_key
] = None
4009 myvims
[datacenter_key
] = vims
.values()[0]
4010 myvim
= myvims
[datacenter_key
]
4011 myvim_thread
= myvim_threads
[datacenter_key
]
4014 error_msg
+= "\n vim_classification_id={} cannot be deleted because datacenter={} not found".format(classification
['vim_classification_id'],
4015 classification
["datacenter_id"])
4017 depends_on
= [action
["task_index"] for action
in db_vim_actions
if action
["item"] == "instance_sfps"]
4018 extra
= {"params": (classification
['vim_classification_id']), "depends_on": depends_on
}
4020 "instance_action_id": instance_action_id
,
4021 "task_index": task_index
,
4022 "datacenter_vim_id": classification
["datacenter_tenant_id"],
4024 "status": "SCHEDULED",
4025 "item": "instance_classifications",
4026 "item_id": classification
["uuid"],
4027 "extra": yaml
.safe_dump(extra
, default_flow_style
=True, width
=256)
4030 db_vim_actions
.append(db_vim_action
)
4032 for sf
in instanceDict
.get('sfs', ()):
4033 vimthread_affected
[sf
["datacenter_tenant_id"]] = None
4034 datacenter_key
= (sf
["datacenter_id"], sf
["datacenter_tenant_id"])
4035 if datacenter_key
not in myvims
:
4037 _
, myvim_thread
= get_vim_thread(mydb
, tenant_id
, sf
["datacenter_id"], sf
["datacenter_tenant_id"])
4038 except NfvoException
as e
:
4039 logger
.error(str(e
))
4041 myvim_threads
[datacenter_key
] = myvim_thread
4042 vims
= get_vim(mydb
, tenant_id
, datacenter_id
=sf
["datacenter_id"],
4043 datacenter_tenant_id
=sf
["datacenter_tenant_id"])
4045 logger
.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(sf
["datacenter_id"], sf
["datacenter_tenant_id"]))
4046 myvims
[datacenter_key
] = None
4048 myvims
[datacenter_key
] = vims
.values()[0]
4049 myvim
= myvims
[datacenter_key
]
4050 myvim_thread
= myvim_threads
[datacenter_key
]
4053 error_msg
+= "\n vim_sf_id={} cannot be deleted because datacenter={} not found".format(sf
['vim_sf_id'], sf
["datacenter_id"])
4055 depends_on
= [action
["task_index"] for action
in db_vim_actions
if action
["item"] == "instance_sfps"]
4056 extra
= {"params": (sf
['vim_sf_id']), "depends_on": depends_on
}
4058 "instance_action_id": instance_action_id
,
4059 "task_index": task_index
,
4060 "datacenter_vim_id": sf
["datacenter_tenant_id"],
4062 "status": "SCHEDULED",
4063 "item": "instance_sfs",
4064 "item_id": sf
["uuid"],
4065 "extra": yaml
.safe_dump(extra
, default_flow_style
=True, width
=256)
4068 db_vim_actions
.append(db_vim_action
)
4070 for sfi
in instanceDict
.get('sfis', ()):
4071 vimthread_affected
[sfi
["datacenter_tenant_id"]] = None
4072 datacenter_key
= (sfi
["datacenter_id"], sfi
["datacenter_tenant_id"])
4073 if datacenter_key
not in myvims
:
4075 _
, myvim_thread
= get_vim_thread(mydb
, tenant_id
, sfi
["datacenter_id"], sfi
["datacenter_tenant_id"])
4076 except NfvoException
as e
:
4077 logger
.error(str(e
))
4079 myvim_threads
[datacenter_key
] = myvim_thread
4080 vims
= get_vim(mydb
, tenant_id
, datacenter_id
=sfi
["datacenter_id"],
4081 datacenter_tenant_id
=sfi
["datacenter_tenant_id"])
4083 logger
.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(sfi
["datacenter_id"], sfi
["datacenter_tenant_id"]))
4084 myvims
[datacenter_key
] = None
4086 myvims
[datacenter_key
] = vims
.values()[0]
4087 myvim
= myvims
[datacenter_key
]
4088 myvim_thread
= myvim_threads
[datacenter_key
]
4091 error_msg
+= "\n vim_sfi_id={} cannot be deleted because datacenter={} not found".format(sfi
['vim_sfi_id'], sfi
["datacenter_id"])
4093 depends_on
= [action
["task_index"] for action
in db_vim_actions
if action
["item"] == "instance_sfs"]
4094 extra
= {"params": (sfi
['vim_sfi_id']), "depends_on": depends_on
}
4096 "instance_action_id": instance_action_id
,
4097 "task_index": task_index
,
4098 "datacenter_vim_id": sfi
["datacenter_tenant_id"],
4100 "status": "SCHEDULED",
4101 "item": "instance_sfis",
4102 "item_id": sfi
["uuid"],
4103 "extra": yaml
.safe_dump(extra
, default_flow_style
=True, width
=256)
4106 db_vim_actions
.append(db_vim_action
)
4110 for sce_vnf
in instanceDict
.get('vnfs', ()):
4111 datacenter_key
= (sce_vnf
["datacenter_id"], sce_vnf
["datacenter_tenant_id"])
4112 vimthread_affected
[sce_vnf
["datacenter_tenant_id"]] = None
4113 if datacenter_key
not in myvims
:
4115 _
, myvim_thread
= get_vim_thread(mydb
, tenant_id
, sce_vnf
["datacenter_id"], sce_vnf
["datacenter_tenant_id"])
4116 except NfvoException
as e
:
4117 logger
.error(str(e
))
4119 myvim_threads
[datacenter_key
] = myvim_thread
4120 vims
= get_vim(mydb
, tenant_id
, datacenter_id
=sce_vnf
["datacenter_id"],
4121 datacenter_tenant_id
=sce_vnf
["datacenter_tenant_id"])
4123 logger
.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(sce_vnf
["datacenter_id"],
4124 sce_vnf
["datacenter_tenant_id"]))
4125 myvims
[datacenter_key
] = None
4127 myvims
[datacenter_key
] = vims
.values()[0]
4128 myvim
= myvims
[datacenter_key
]
4129 myvim_thread
= myvim_threads
[datacenter_key
]
4131 for vm
in sce_vnf
['vms']:
4133 error_msg
+= "\n VM id={} cannot be deleted because datacenter={} not found".format(vm
['vim_vm_id'], sce_vnf
["datacenter_id"])
4135 sfi_dependencies
= [action
["task_index"] for action
in db_vim_actions
if action
["item"] == "instance_sfis"]
4137 "instance_action_id": instance_action_id
,
4138 "task_index": task_index
,
4139 "datacenter_vim_id": sce_vnf
["datacenter_tenant_id"],
4141 "status": "SCHEDULED",
4142 "item": "instance_vms",
4143 "item_id": vm
["uuid"],
4144 "extra": yaml
.safe_dump({"params": vm
["interfaces"], "depends_on": sfi_dependencies
},
4145 default_flow_style
=True, width
=256)
4147 db_vim_actions
.append(db_vim_action
)
4148 for interface
in vm
["interfaces"]:
4149 if not interface
.get("instance_net_id"):
4151 if interface
["instance_net_id"] not in net2vm_dependencies
:
4152 net2vm_dependencies
[interface
["instance_net_id"]] = []
4153 net2vm_dependencies
[interface
["instance_net_id"]].append(task_index
)
4158 for net
in instanceDict
['nets']:
4159 vimthread_affected
[net
["datacenter_tenant_id"]] = None
4160 datacenter_key
= (net
["datacenter_id"], net
["datacenter_tenant_id"])
4161 if datacenter_key
not in myvims
:
4163 _
,myvim_thread
= get_vim_thread(mydb
, tenant_id
, net
["datacenter_id"], net
["datacenter_tenant_id"])
4164 except NfvoException
as e
:
4165 logger
.error(str(e
))
4167 myvim_threads
[datacenter_key
] = myvim_thread
4168 vims
= get_vim(mydb
, tenant_id
, datacenter_id
=net
["datacenter_id"],
4169 datacenter_tenant_id
=net
["datacenter_tenant_id"])
4171 logger
.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(net
["datacenter_id"], net
["datacenter_tenant_id"]))
4172 myvims
[datacenter_key
] = None
4174 myvims
[datacenter_key
] = vims
.values()[0]
4175 myvim
= myvims
[datacenter_key
]
4176 myvim_thread
= myvim_threads
[datacenter_key
]
4179 error_msg
+= "\n Net VIM_id={} cannot be deleted because datacenter={} not found".format(net
['vim_net_id'], net
["datacenter_id"])
4181 extra
= {"params": (net
['vim_net_id'], net
['sdn_net_id'])}
4182 if net2vm_dependencies
.get(net
["uuid"]):
4183 extra
["depends_on"] = net2vm_dependencies
[net
["uuid"]]
4184 sfi_dependencies
= [action
["task_index"] for action
in db_vim_actions
if action
["item"] == "instance_sfis"]
4185 if len(sfi_dependencies
) > 0:
4186 if "depends_on" in extra
:
4187 extra
["depends_on"] += sfi_dependencies
4189 extra
["depends_on"] = sfi_dependencies
4191 "instance_action_id": instance_action_id
,
4192 "task_index": task_index
,
4193 "datacenter_vim_id": net
["datacenter_tenant_id"],
4195 "status": "SCHEDULED",
4196 "item": "instance_nets",
4197 "item_id": net
["uuid"],
4198 "extra": yaml
.safe_dump(extra
, default_flow_style
=True, width
=256)
4201 db_vim_actions
.append(db_vim_action
)
4203 db_instance_action
["number_tasks"] = task_index
4206 wim_actions
, db_instance_action
= (
4207 wim_engine
.incorporate_actions(wim_actions
, db_instance_action
))
4211 {"instance_actions": db_instance_action
},
4212 {"vim_wim_actions": db_vim_actions
+ wim_actions
}
4215 logger
.debug("delete_instance done DB tables: %s",
4216 yaml
.safe_dump(db_tables
, indent
=4, default_flow_style
=False))
4217 mydb
.new_rows(db_tables
, ())
4218 for myvim_thread_id
in vimthread_affected
.keys():
4219 vim_threads
["running"][myvim_thread_id
].insert_task(db_vim_actions
)
4221 wim_engine
.dispatch(wim_actions
)
4223 if len(error_msg
) > 0:
4224 return 'action_id={} instance {} deleted but some elements could not be deleted, or already deleted '\
4225 '(error: 404) from VIM: {}'.format(instance_action_id
, message
, error_msg
)
4227 return "action_id={} instance {} deleted".format(instance_action_id
, message
)
4229 def get_instance_id(mydb
, tenant_id
, instance_id
):
4231 #check valid tenant_id
4232 check_tenant(mydb
, tenant_id
)
4235 instance_dict
= mydb
.get_instance_scenario(instance_id
, tenant_id
, verbose
=True)
4236 for net
in instance_dict
["nets"]:
4237 if net
.get("sdn_net_id"):
4238 net_sdn
= ovim
.show_network(net
["sdn_net_id"])
4240 "admin_state_up": net_sdn
.get("admin_state_up"),
4241 "flows": net_sdn
.get("flows"),
4242 "last_error": net_sdn
.get("last_error"),
4243 "ports": net_sdn
.get("ports"),
4244 "type": net_sdn
.get("type"),
4245 "status": net_sdn
.get("status"),
4246 "vlan": net_sdn
.get("vlan"),
4248 return instance_dict
4250 @deprecated("Instance is automatically refreshed by vim_threads")
4251 def refresh_instance(mydb
, nfvo_tenant
, instanceDict
, datacenter
=None, vim_tenant
=None):
4252 '''Refreshes a scenario instance. It modifies instanceDict'''
4254 - 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
4257 # # Assumption: nfvo_tenant and instance_id were checked before entering into this function
4258 # #print "nfvo.refresh_instance begins"
4259 # #print json.dumps(instanceDict, indent=4)
4261 # #print "Getting the VIM URL and the VIM tenant_id"
4264 # # 1. Getting VIM vm and net list
4265 # vms_updated = [] #List of VM instance uuids in openmano that were updated
4268 # for sce_vnf in instanceDict['vnfs']:
4269 # datacenter_key = (sce_vnf["datacenter_id"], sce_vnf["datacenter_tenant_id"])
4270 # if datacenter_key not in vm_list:
4271 # vm_list[datacenter_key] = []
4272 # if datacenter_key not in myvims:
4273 # vims = get_vim(mydb, nfvo_tenant, datacenter_id=sce_vnf["datacenter_id"],
4274 # datacenter_tenant_id=sce_vnf["datacenter_tenant_id"])
4275 # if len(vims) == 0:
4276 # logger.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(sce_vnf["datacenter_id"], sce_vnf["datacenter_tenant_id"]))
4277 # myvims[datacenter_key] = None
4279 # myvims[datacenter_key] = vims.values()[0]
4280 # for vm in sce_vnf['vms']:
4281 # vm_list[datacenter_key].append(vm['vim_vm_id'])
4282 # vms_notupdated.append(vm["uuid"])
4284 # nets_updated = [] #List of VM instance uuids in openmano that were updated
4285 # nets_notupdated=[]
4287 # for net in instanceDict['nets']:
4288 # datacenter_key = (net["datacenter_id"], net["datacenter_tenant_id"])
4289 # if datacenter_key not in net_list:
4290 # net_list[datacenter_key] = []
4291 # if datacenter_key not in myvims:
4292 # vims = get_vim(mydb, nfvo_tenant, datacenter_id=net["datacenter_id"],
4293 # datacenter_tenant_id=net["datacenter_tenant_id"])
4294 # if len(vims) == 0:
4295 # logger.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(net["datacenter_id"], net["datacenter_tenant_id"]))
4296 # myvims[datacenter_key] = None
4298 # myvims[datacenter_key] = vims.values()[0]
4300 # net_list[datacenter_key].append(net['vim_net_id'])
4301 # nets_notupdated.append(net["uuid"])
4303 # # 1. Getting the status of all VMs
4305 # for datacenter_key in myvims:
4306 # if not vm_list.get(datacenter_key):
4310 # if not myvims[datacenter_key]:
4311 # failed_message = "datacenter '{}' with datacenter_tenant_id '{}' not found".format(net["datacenter_id"], net["datacenter_tenant_id"])
4314 # vm_dict.update(myvims[datacenter_key].refresh_vms_status(vm_list[datacenter_key]) )
4316 # except vimconn.vimconnException as e:
4317 # logger.error("VIM exception %s %s", type(e).__name__, str(e))
4318 # failed_message = str(e)
4320 # for vm in vm_list[datacenter_key]:
4321 # vm_dict[vm] = {'status': "VIM_ERROR", 'error_msg': failed_message}
4323 # # 2. Update the status of VMs in the instanceDict, while collects the VMs whose status changed
4324 # for sce_vnf in instanceDict['vnfs']:
4325 # for vm in sce_vnf['vms']:
4326 # vm_id = vm['vim_vm_id']
4327 # interfaces = vm_dict[vm_id].pop('interfaces', [])
4328 # #2.0 look if contain manamgement interface, and if not change status from ACTIVE:NoMgmtIP to ACTIVE
4329 # has_mgmt_iface = False
4330 # for iface in vm["interfaces"]:
4331 # if iface["type"]=="mgmt":
4332 # has_mgmt_iface = True
4333 # if vm_dict[vm_id]['status'] == "ACTIVE:NoMgmtIP" and not has_mgmt_iface:
4334 # vm_dict[vm_id]['status'] = "ACTIVE"
4335 # if vm_dict[vm_id].get('error_msg') and len(vm_dict[vm_id]['error_msg']) >= 1024:
4336 # vm_dict[vm_id]['error_msg'] = vm_dict[vm_id]['error_msg'][:516] + " ... " + vm_dict[vm_id]['error_msg'][-500:]
4337 # 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'):
4338 # vm['status'] = vm_dict[vm_id]['status']
4339 # vm['error_msg'] = vm_dict[vm_id].get('error_msg')
4340 # vm['vim_info'] = vm_dict[vm_id].get('vim_info')
4341 # # 2.1. Update in openmano DB the VMs whose status changed
4343 # updates = mydb.update_rows('instance_vms', UPDATE=vm_dict[vm_id], WHERE={'uuid':vm["uuid"]})
4344 # vms_notupdated.remove(vm["uuid"])
4346 # vms_updated.append(vm["uuid"])
4347 # except db_base_Exception as e:
4348 # logger.error("nfvo.refresh_instance error database update: %s", str(e))
4349 # # 2.2. Update in openmano DB the interface VMs
4350 # for interface in interfaces:
4351 # #translate from vim_net_id to instance_net_id
4352 # network_id_list=[]
4353 # for net in instanceDict['nets']:
4354 # if net["vim_net_id"] == interface["vim_net_id"]:
4355 # network_id_list.append(net["uuid"])
4356 # if not network_id_list:
4358 # del interface["vim_net_id"]
4360 # for network_id in network_id_list:
4361 # mydb.update_rows('instance_interfaces', UPDATE=interface, WHERE={'instance_vm_id':vm["uuid"], "instance_net_id":network_id})
4362 # except db_base_Exception as e:
4363 # logger.error( "nfvo.refresh_instance error with vm=%s, interface_net_id=%s", vm["uuid"], network_id)
4365 # # 3. Getting the status of all nets
4367 # for datacenter_key in myvims:
4368 # if not net_list.get(datacenter_key):
4371 # failed_message = ""
4372 # if not myvims[datacenter_key]:
4373 # failed_message = "datacenter '{}' with datacenter_tenant_id '{}' not found".format(net["datacenter_id"], net["datacenter_tenant_id"])
4376 # net_dict.update(myvims[datacenter_key].refresh_nets_status(net_list[datacenter_key]) )
4378 # except vimconn.vimconnException as e:
4379 # logger.error("VIM exception %s %s", type(e).__name__, str(e))
4380 # failed_message = str(e)
4382 # for net in net_list[datacenter_key]:
4383 # net_dict[net] = {'status': "VIM_ERROR", 'error_msg': failed_message}
4385 # # 4. Update the status of nets in the instanceDict, while collects the nets whose status changed
4386 # # TODO: update nets inside a vnf
4387 # for net in instanceDict['nets']:
4388 # net_id = net['vim_net_id']
4389 # if net_dict[net_id].get('error_msg') and len(net_dict[net_id]['error_msg']) >= 1024:
4390 # net_dict[net_id]['error_msg'] = net_dict[net_id]['error_msg'][:516] + " ... " + net_dict[vm_id]['error_msg'][-500:]
4391 # 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'):
4392 # net['status'] = net_dict[net_id]['status']
4393 # net['error_msg'] = net_dict[net_id].get('error_msg')
4394 # net['vim_info'] = net_dict[net_id].get('vim_info')
4395 # # 5.1. Update in openmano DB the nets whose status changed
4397 # updated = mydb.update_rows('instance_nets', UPDATE=net_dict[net_id], WHERE={'uuid':net["uuid"]})
4398 # nets_notupdated.remove(net["uuid"])
4400 # nets_updated.append(net["uuid"])
4401 # except db_base_Exception as e:
4402 # logger.error("nfvo.refresh_instance error database update: %s", str(e))
4404 # # Returns appropriate output
4405 # #print "nfvo.refresh_instance finishes"
4406 # logger.debug("VMs updated in the database: %s; nets updated in the database %s; VMs not updated: %s; nets not updated: %s",
4407 # str(vms_updated), str(nets_updated), str(vms_notupdated), str(nets_notupdated))
4408 instance_id
= instanceDict
['uuid']
4409 # if len(vms_notupdated)+len(nets_notupdated)>0:
4410 # error_msg = "VMs not updated: " + str(vms_notupdated) + "; nets not updated: " + str(nets_notupdated)
4411 # return len(vms_notupdated)+len(nets_notupdated), 'Scenario instance ' + instance_id + ' refreshed but some elements could not be updated in the database: ' + error_msg
4413 return 0, 'Scenario instance ' + instance_id
+ ' refreshed.'
4415 def instance_action(mydb
,nfvo_tenant
,instance_id
, action_dict
):
4416 #print "Checking that the instance_id exists and getting the instance dictionary"
4417 instanceDict
= mydb
.get_instance_scenario(instance_id
, nfvo_tenant
)
4418 #print yaml.safe_dump(instanceDict, indent=4, default_flow_style=False)
4420 #print "Checking that nfvo_tenant_id exists and getting the VIM URI and the VIM tenant_id"
4421 vims
= get_vim(mydb
, nfvo_tenant
, instanceDict
['datacenter_id'])
4423 raise NfvoException("datacenter '{}' not found".format(str(instanceDict
['datacenter_id'])), httperrors
.Not_Found
)
4424 myvim
= vims
.values()[0]
4429 myvim_threads_id
= {}
4430 if action_dict
.get("vdu-scaling"):
4431 db_instance_vms
= []
4433 db_instance_interfaces
= []
4434 instance_action_id
= get_task_id()
4435 db_instance_action
= {
4436 "uuid": instance_action_id
, # same uuid for the instance and the action on create
4437 "tenant_id": nfvo_tenant
,
4438 "instance_id": instance_id
,
4439 "description": "SCALE",
4441 vm_result
["instance_action_id"] = instance_action_id
4442 vm_result
["created"] = []
4443 vm_result
["deleted"] = []
4445 for vdu
in action_dict
["vdu-scaling"]:
4446 vdu_id
= vdu
.get("vdu-id")
4447 osm_vdu_id
= vdu
.get("osm_vdu_id")
4448 member_vnf_index
= vdu
.get("member-vnf-index")
4449 vdu_count
= vdu
.get("count", 1)
4451 target_vms
= mydb
.get_rows(
4452 FROM
="instance_vms as vms join instance_vnfs as vnfs on vms.instance_vnf_id=vnfs.uuid",
4453 WHERE
={"vms.uuid": vdu_id
},
4454 ORDER_BY
="vms.created_at"
4457 raise NfvoException("Cannot find the vdu with id {}".format(vdu_id
), httperrors
.Not_Found
)
4459 if not osm_vdu_id
and not member_vnf_index
:
4460 raise NfvoException("Invalid input vdu parameters. Must supply either 'vdu-id' of 'osm_vdu_id','member-vnf-index'")
4461 target_vms
= mydb
.get_rows(
4462 # SELECT=("ivms.uuid", "ivnfs.datacenter_id", "ivnfs.datacenter_tenant_id"),
4463 FROM
="instance_vms as ivms join instance_vnfs as ivnfs on ivms.instance_vnf_id=ivnfs.uuid"\
4464 " join sce_vnfs as svnfs on ivnfs.sce_vnf_id=svnfs.uuid"\
4465 " join vms on ivms.vm_id=vms.uuid",
4466 WHERE
={"vms.osm_id": osm_vdu_id
, "svnfs.member_vnf_index": member_vnf_index
,
4467 "ivnfs.instance_scenario_id": instance_id
},
4468 ORDER_BY
="ivms.created_at"
4471 raise NfvoException("Cannot find the vdu with osm_vdu_id {} and member-vnf-index {}".format(osm_vdu_id
, member_vnf_index
), httperrors
.Not_Found
)
4472 vdu_id
= target_vms
[-1]["uuid"]
4473 target_vm
= target_vms
[-1]
4474 datacenter
= target_vm
["datacenter_id"]
4475 myvim_threads_id
[datacenter
], _
= get_vim_thread(mydb
, nfvo_tenant
, datacenter
)
4477 if vdu
["type"] == "delete":
4478 for index
in range(0, vdu_count
):
4479 target_vm
= target_vms
[-1-index
]
4480 vdu_id
= target_vm
["uuid"]
4482 vm_interfaces
= None
4483 for sce_vnf
in instanceDict
['vnfs']:
4484 for vm
in sce_vnf
['vms']:
4485 if vm
["uuid"] == vdu_id
:
4486 vm_interfaces
= vm
["interfaces"]
4490 "instance_action_id": instance_action_id
,
4491 "task_index": task_index
,
4492 "datacenter_vim_id": target_vm
["datacenter_tenant_id"],
4494 "status": "SCHEDULED",
4495 "item": "instance_vms",
4497 "extra": yaml
.safe_dump({"params": vm_interfaces
},
4498 default_flow_style
=True, width
=256)
4501 db_vim_actions
.append(db_vim_action
)
4502 vm_result
["deleted"].append(vdu_id
)
4503 # delete from database
4504 db_instance_vms
.append({"TO-DELETE": vdu_id
})
4506 else: # vdu["type"] == "create":
4508 where
= {"item": "instance_vms", "item_id": target_vm
["uuid"], "action": "CREATE"}
4510 vim_action_to_clone
= mydb
.get_rows(FROM
="vim_actions", WHERE
=where
)
4511 if not vim_action_to_clone
:
4512 raise NfvoException("Cannot find the vim_action at database with {}".format(where
), httperrors
.Internal_Server_Error
)
4513 vim_action_to_clone
= vim_action_to_clone
[0]
4514 extra
= yaml
.safe_load(vim_action_to_clone
["extra"])
4516 # generate a new depends_on. Convert format TASK-Y into new format TASK-ACTION-XXXX.XXXX.Y
4517 # TODO do the same for flavor and image when available
4518 task_depends_on
= []
4519 task_params
= extra
["params"]
4520 task_params_networks
= deepcopy(task_params
[5])
4521 for iface
in task_params
[5]:
4522 if iface
["net_id"].startswith("TASK-"):
4523 if "." not in iface
["net_id"]:
4524 task_depends_on
.append("{}.{}".format(vim_action_to_clone
["instance_action_id"],
4525 iface
["net_id"][5:]))
4526 iface
["net_id"] = "TASK-{}.{}".format(vim_action_to_clone
["instance_action_id"],
4527 iface
["net_id"][5:])
4529 task_depends_on
.append(iface
["net_id"][5:])
4530 if "mac_address" in iface
:
4531 del iface
["mac_address"]
4533 vm_ifaces_to_clone
= mydb
.get_rows(FROM
="instance_interfaces", WHERE
={"instance_vm_id": target_vm
["uuid"]})
4534 for index
in range(0, vdu_count
):
4535 vm_uuid
= str(uuid4())
4536 vm_name
= target_vm
.get('vim_name')
4538 suffix
= vm_name
.rfind("-")
4539 vm_name
= vm_name
[:suffix
+1] + str(index
+ 1 + int(vm_name
[suffix
+1:]))
4544 'instance_vnf_id': target_vm
['instance_vnf_id'],
4545 'vm_id': target_vm
['vm_id'],
4548 db_instance_vms
.append(db_instance_vm
)
4550 for vm_iface
in vm_ifaces_to_clone
:
4551 iface_uuid
= str(uuid4())
4552 iface2iface
[vm_iface
["uuid"]] = iface_uuid
4555 'instance_vm_id': vm_uuid
,
4556 "instance_net_id": vm_iface
["instance_net_id"],
4557 'interface_id': vm_iface
['interface_id'],
4558 'type': vm_iface
['type'],
4559 'floating_ip': vm_iface
['floating_ip'],
4560 'port_security': vm_iface
['port_security']
4562 db_instance_interfaces
.append(db_vm_iface
)
4563 task_params_copy
= deepcopy(task_params
)
4564 for iface
in task_params_copy
[5]:
4565 iface
["uuid"] = iface2iface
[iface
["uuid"]]
4566 # increment ip_address
4567 if "ip_address" in iface
:
4568 ip
= iface
.get("ip_address")
4573 ip
= ip
[i
:] + str(int(ip
[:i
]) + 1)
4574 iface
["ip_address"] = ip
4576 iface
["ip_address"] = None
4578 task_params_copy
[0] = vm_name
4580 "instance_action_id": instance_action_id
,
4581 "task_index": task_index
,
4582 "datacenter_vim_id": vim_action_to_clone
["datacenter_vim_id"],
4584 "status": "SCHEDULED",
4585 "item": "instance_vms",
4589 # TODO examinar parametros, quitar MAC o incrementar. Incrementar IP y colocar las dependencias con ACTION-asdfasd.
4592 "extra": yaml
.safe_dump({"params": task_params_copy
, "depends_on": task_depends_on
}, default_flow_style
=True, width
=256)
4595 db_vim_actions
.append(db_vim_action
)
4596 vm_result
["created"].append(vm_uuid
)
4598 db_instance_action
["number_tasks"] = task_index
4600 {"instance_vms": db_instance_vms
},
4601 {"instance_interfaces": db_instance_interfaces
},
4602 {"instance_actions": db_instance_action
},
4604 # {"instance_sfis": db_instance_sfis},
4605 # {"instance_sfs": db_instance_sfs},
4606 # {"instance_classifications": db_instance_classifications},
4607 # {"instance_sfps": db_instance_sfps},
4608 {"vim_actions": db_vim_actions
}
4610 logger
.debug("create_vdu done DB tables: %s",
4611 yaml
.safe_dump(db_tables
, indent
=4, default_flow_style
=False))
4612 mydb
.new_rows(db_tables
, [])
4613 for myvim_thread
in myvim_threads_id
.values():
4614 vim_threads
["running"][myvim_thread
].insert_task(db_vim_actions
)
4618 input_vnfs
= action_dict
.pop("vnfs", [])
4619 input_vms
= action_dict
.pop("vms", [])
4620 action_over_all
= True if not input_vnfs
and not input_vms
else False
4621 for sce_vnf
in instanceDict
['vnfs']:
4622 for vm
in sce_vnf
['vms']:
4623 if not action_over_all
and sce_vnf
['uuid'] not in input_vnfs
and sce_vnf
['vnf_name'] not in input_vnfs
and \
4624 sce_vnf
['member_vnf_index'] not in input_vnfs
and \
4625 vm
['uuid'] not in input_vms
and vm
['name'] not in input_vms
:
4628 if "add_public_key" in action_dict
:
4630 if sce_vnf
.get('mgmt_access'):
4631 mgmt_access
= yaml
.load(sce_vnf
['mgmt_access'])
4632 ssh_access
= mgmt_access
['config-access']['ssh-access']
4633 tenant
= mydb
.get_rows_by_id('nfvo_tenants', nfvo_tenant
)
4635 if ssh_access
['required'] and ssh_access
['default-user']:
4636 if 'ip_address' in vm
:
4637 mgmt_ip
= vm
['ip_address'].split(';')
4638 password
= mgmt_access
['config-access'].get('password')
4639 priv_RO_key
= decrypt_key(tenant
[0]['encrypted_RO_priv_key'], tenant
[0]['uuid'])
4640 myvim
.inject_user_key(mgmt_ip
[0], ssh_access
['default-user'],
4641 action_dict
['add_public_key'],
4642 password
=password
, ro_key
=priv_RO_key
)
4644 raise NfvoException("Unable to inject ssh key in vm: {} - Aborting".format(vm
['uuid']),
4645 httperrors
.Internal_Server_Error
)
4647 raise NfvoException("Unable to inject ssh key in vm: {} - Aborting".format(vm
['uuid']),
4648 httperrors
.Internal_Server_Error
)
4650 raise NfvoException("Unable to inject ssh key in vm: {} - Aborting".format(vm
['uuid']),
4651 httperrors
.Internal_Server_Error
)
4653 data
= myvim
.action_vminstance(vm
['vim_vm_id'], action_dict
)
4654 if "console" in action_dict
:
4655 if not global_config
["http_console_proxy"]:
4656 vm_result
[ vm
['uuid'] ] = {"vim_result": 200,
4657 "description": "{protocol}//{ip}:{port}/{suffix}".format(
4658 protocol
=data
["protocol"],
4659 ip
= data
["server"],
4660 port
= data
["port"],
4661 suffix
= data
["suffix"]),
4665 elif data
["server"]=="127.0.0.1" or data
["server"]=="localhost":
4666 vm_result
[ vm
['uuid'] ] = {"vim_result": -httperrors
.Unauthorized
,
4667 "description": "this console is only reachable by local interface",
4672 #print "console data", data
4674 console_thread
= create_or_use_console_proxy_thread(data
["server"], data
["port"])
4675 vm_result
[ vm
['uuid'] ] = {"vim_result": 200,
4676 "description": "{protocol}//{ip}:{port}/{suffix}".format(
4677 protocol
=data
["protocol"],
4678 ip
= global_config
["http_console_host"],
4679 port
= console_thread
.port
,
4680 suffix
= data
["suffix"]),
4684 except NfvoException
as e
:
4685 vm_result
[ vm
['uuid'] ] = {"vim_result": e
.http_code
, "name":vm
['name'], "description": str(e
)}
4689 vm_result
[ vm
['uuid'] ] = {"vim_result": 200, "description": "ok", "name":vm
['name']}
4691 except vimconn
.vimconnException
as e
:
4692 vm_result
[ vm
['uuid'] ] = {"vim_result": e
.http_code
, "name":vm
['name'], "description": str(e
)}
4695 if vm_ok
==0: #all goes wrong
4700 def instance_action_get(mydb
, nfvo_tenant
, instance_id
, action_id
):
4702 if nfvo_tenant
and nfvo_tenant
!= "any":
4703 filter["tenant_id"] = nfvo_tenant
4704 if instance_id
and instance_id
!= "any":
4705 filter["instance_id"] = instance_id
4707 filter["uuid"] = action_id
4708 rows
= mydb
.get_rows(FROM
="instance_actions", WHERE
=filter)
4711 raise NfvoException("Not found any action with this criteria", httperrors
.Not_Found
)
4712 vim_wim_actions
= mydb
.get_rows(FROM
="vim_wim_actions", WHERE
={"instance_action_id": action_id
})
4713 rows
[0]["vim_wim_actions"] = vim_wim_actions
4714 return {"actions": rows
}
4717 def create_or_use_console_proxy_thread(console_server
, console_port
):
4718 #look for a non-used port
4719 console_thread_key
= console_server
+ ":" + str(console_port
)
4720 if console_thread_key
in global_config
["console_thread"]:
4721 #global_config["console_thread"][console_thread_key].start_timeout()
4722 return global_config
["console_thread"][console_thread_key
]
4724 for port
in global_config
["console_port_iterator"]():
4725 #print "create_or_use_console_proxy_thread() port:", port
4726 if port
in global_config
["console_ports"]:
4729 clithread
= cli
.ConsoleProxyThread(global_config
['http_host'], port
, console_server
, console_port
)
4731 global_config
["console_thread"][console_thread_key
] = clithread
4732 global_config
["console_ports"][port
] = console_thread_key
4734 except cli
.ConsoleProxyExceptionPortUsed
as e
:
4735 #port used, try with onoher
4737 except cli
.ConsoleProxyException
as e
:
4738 raise NfvoException(str(e
), httperrors
.Bad_Request
)
4739 raise NfvoException("Not found any free 'http_console_ports'", httperrors
.Conflict
)
4742 def check_tenant(mydb
, tenant_id
):
4743 '''check that tenant exists at database'''
4744 tenant
= mydb
.get_rows(FROM
='nfvo_tenants', SELECT
=('uuid',), WHERE
={'uuid': tenant_id
})
4746 raise NfvoException("tenant '{}' not found".format(tenant_id
), httperrors
.Not_Found
)
4749 def new_tenant(mydb
, tenant_dict
):
4751 tenant_uuid
= str(uuid4())
4752 tenant_dict
['uuid'] = tenant_uuid
4754 pub_key
, priv_key
= create_RO_keypair(tenant_uuid
)
4755 tenant_dict
['RO_pub_key'] = pub_key
4756 tenant_dict
['encrypted_RO_priv_key'] = priv_key
4757 mydb
.new_row("nfvo_tenants", tenant_dict
, confidential_data
=True)
4758 except db_base_Exception
as e
:
4759 raise NfvoException("Error creating the new tenant: {} ".format(tenant_dict
['name']) + str(e
), e
.http_code
)
4762 def delete_tenant(mydb
, tenant
):
4763 #get nfvo_tenant info
4765 tenant_dict
= mydb
.get_table_by_uuid_name('nfvo_tenants', tenant
, 'tenant')
4766 mydb
.delete_row_by_id("nfvo_tenants", tenant_dict
['uuid'])
4767 return tenant_dict
['uuid'] + " " + tenant_dict
["name"]
4770 def new_datacenter(mydb
, datacenter_descriptor
):
4771 sdn_port_mapping
= None
4772 if "config" in datacenter_descriptor
:
4773 sdn_port_mapping
= datacenter_descriptor
["config"].pop("sdn-port-mapping", None)
4774 datacenter_descriptor
["config"] = yaml
.safe_dump(datacenter_descriptor
["config"], default_flow_style
=True,
4776 # Check that datacenter-type is correct
4777 datacenter_type
= datacenter_descriptor
.get("type", "openvim");
4778 # module_info = None
4780 module
= "vimconn_" + datacenter_type
4781 pkg
= __import__("osm_ro." + module
)
4782 # vim_conn = getattr(pkg, module)
4783 # module_info = imp.find_module(module, [__file__[:__file__.rfind("/")]])
4784 except (IOError, ImportError):
4785 # if module_info and module_info[0]:
4786 # file.close(module_info[0])
4787 raise NfvoException("Incorrect datacenter type '{}'. Plugin '{}.py' not installed".format(datacenter_type
,
4789 httperrors
.Bad_Request
)
4791 datacenter_id
= mydb
.new_row("datacenters", datacenter_descriptor
, add_uuid
=True, confidential_data
=True)
4792 if sdn_port_mapping
:
4794 datacenter_sdn_port_mapping_set(mydb
, None, datacenter_id
, sdn_port_mapping
)
4795 except Exception as e
:
4796 mydb
.delete_row_by_id("datacenters", datacenter_id
) # Rollback
4798 return datacenter_id
4801 def edit_datacenter(mydb
, datacenter_id_name
, datacenter_descriptor
):
4802 # obtain data, check that only one exist
4803 datacenter
= mydb
.get_table_by_uuid_name('datacenters', datacenter_id_name
)
4806 datacenter_id
= datacenter
['uuid']
4807 where
= {'uuid': datacenter
['uuid']}
4808 remove_port_mapping
= False
4809 new_sdn_port_mapping
= None
4810 if "config" in datacenter_descriptor
:
4811 if datacenter_descriptor
['config'] != None:
4813 new_config_dict
= datacenter_descriptor
["config"]
4814 if "sdn-port-mapping" in new_config_dict
:
4815 remove_port_mapping
= True
4816 new_sdn_port_mapping
= new_config_dict
.pop("sdn-port-mapping")
4817 # delete null fields
4819 for k
in new_config_dict
:
4820 if new_config_dict
[k
] is None:
4822 if k
== 'sdn-controller':
4823 remove_port_mapping
= True
4825 config_text
= datacenter
.get("config")
4828 config_dict
= yaml
.load(config_text
)
4829 config_dict
.update(new_config_dict
)
4830 # delete null fields
4833 except Exception as e
:
4834 raise NfvoException("Bad format at datacenter:config " + str(e
), httperrors
.Bad_Request
)
4836 datacenter_descriptor
["config"] = yaml
.safe_dump(config_dict
, default_flow_style
=True, width
=256)
4838 datacenter_descriptor
["config"] = None
4839 if remove_port_mapping
:
4841 datacenter_sdn_port_mapping_delete(mydb
, None, datacenter_id
)
4842 except ovimException
as e
:
4843 raise NfvoException("Error deleting datacenter-port-mapping " + str(e
), httperrors
.Conflict
)
4845 mydb
.update_rows('datacenters', datacenter_descriptor
, where
)
4846 if new_sdn_port_mapping
:
4848 datacenter_sdn_port_mapping_set(mydb
, None, datacenter_id
, new_sdn_port_mapping
)
4849 except ovimException
as e
:
4851 mydb
.update_rows('datacenters', datacenter
, where
)
4852 raise NfvoException("Error adding datacenter-port-mapping " + str(e
), httperrors
.Conflict
)
4853 return datacenter_id
4856 def delete_datacenter(mydb
, datacenter
):
4857 #get nfvo_tenant info
4858 datacenter_dict
= mydb
.get_table_by_uuid_name('datacenters', datacenter
, 'datacenter')
4859 mydb
.delete_row_by_id("datacenters", datacenter_dict
['uuid'])
4861 datacenter_sdn_port_mapping_delete(mydb
, None, datacenter_dict
['uuid'])
4862 except ovimException
as e
:
4863 raise NfvoException("Error deleting datacenter-port-mapping " + str(e
))
4864 return datacenter_dict
['uuid'] + " " + datacenter_dict
['name']
4867 def create_vim_account(mydb
, nfvo_tenant
, datacenter_id
, name
=None, vim_id
=None, vim_tenant
=None, vim_tenant_name
=None,
4868 vim_username
=None, vim_password
=None, config
=None):
4869 # get datacenter info
4871 if not datacenter_id
:
4873 raise NfvoException("You must provide 'vim_id", http_code
=httperrors
.Bad_Request
)
4874 datacenter_id
= vim_id
4875 datacenter_id
, datacenter_name
= get_datacenter_uuid(mydb
, None, datacenter_id
)
4877 create_vim_tenant
= True if not vim_tenant
and not vim_tenant_name
else False
4879 # get nfvo_tenant info
4880 tenant_dict
= mydb
.get_table_by_uuid_name('nfvo_tenants', nfvo_tenant
)
4881 if vim_tenant_name
==None:
4882 vim_tenant_name
=tenant_dict
['name']
4884 tenants_datacenter_dict
={"nfvo_tenant_id":tenant_dict
['uuid'], "datacenter_id":datacenter_id
}
4885 # #check that this association does not exist before
4886 # tenants_datacenters = mydb.get_rows(FROM='tenants_datacenters', WHERE=tenants_datacenter_dict)
4887 # if len(tenants_datacenters)>0:
4888 # raise NfvoException("datacenter '{}' and tenant'{}' are already attached".format(datacenter_id, tenant_dict['uuid']), httperrors.Conflict)
4890 vim_tenant_id_exist_atdb
=False
4891 if not create_vim_tenant
:
4892 where_
={"datacenter_id": datacenter_id
}
4893 if vim_tenant
!=None:
4894 where_
["vim_tenant_id"] = vim_tenant
4895 if vim_tenant_name
!=None:
4896 where_
["vim_tenant_name"] = vim_tenant_name
4897 #check if vim_tenant_id is already at database
4898 datacenter_tenants_dict
= mydb
.get_rows(FROM
='datacenter_tenants', WHERE
=where_
)
4899 if len(datacenter_tenants_dict
)>=1:
4900 datacenter_tenants_dict
= datacenter_tenants_dict
[0]
4901 vim_tenant_id_exist_atdb
=True
4902 #TODO check if a field has changed and edit entry at datacenter_tenants at DB
4904 datacenter_tenants_dict
= {}
4905 #insert at table datacenter_tenants
4906 else: #if vim_tenant==None:
4907 #create tenant at VIM if not provided
4909 _
, myvim
= get_datacenter_by_name_uuid(mydb
, None, datacenter
, vim_user
=vim_username
,
4910 vim_passwd
=vim_password
)
4911 datacenter_name
= myvim
["name"]
4912 vim_tenant
= myvim
.new_tenant(vim_tenant_name
, "created by openmano for datacenter "+datacenter_name
)
4913 except vimconn
.vimconnException
as e
:
4914 raise NfvoException("Not possible to create vim_tenant {} at VIM: {}".format(vim_tenant_id
, str(e
)), httperrors
.Internal_Server_Error
)
4915 datacenter_tenants_dict
= {}
4916 datacenter_tenants_dict
["created"]="true"
4918 #fill datacenter_tenants table
4919 if not vim_tenant_id_exist_atdb
:
4920 datacenter_tenants_dict
["vim_tenant_id"] = vim_tenant
4921 datacenter_tenants_dict
["vim_tenant_name"] = vim_tenant_name
4922 datacenter_tenants_dict
["user"] = vim_username
4923 datacenter_tenants_dict
["passwd"] = vim_password
4924 datacenter_tenants_dict
["datacenter_id"] = datacenter_id
4926 datacenter_tenants_dict
["name"] = name
4928 datacenter_tenants_dict
["name"] = datacenter_name
4930 datacenter_tenants_dict
["config"] = yaml
.safe_dump(config
, default_flow_style
=True, width
=256)
4931 id_
= mydb
.new_row('datacenter_tenants', datacenter_tenants_dict
, add_uuid
=True, confidential_data
=True)
4932 datacenter_tenants_dict
["uuid"] = id_
4934 #fill tenants_datacenters table
4935 datacenter_tenant_id
= datacenter_tenants_dict
["uuid"]
4936 tenants_datacenter_dict
["datacenter_tenant_id"] = datacenter_tenant_id
4937 mydb
.new_row('tenants_datacenters', tenants_datacenter_dict
)
4940 thread_name
= get_non_used_vim_name(datacenter_name
, datacenter_id
, tenant_dict
['name'], tenant_dict
['uuid'])
4941 new_thread
= vim_thread
.vim_thread(task_lock
, thread_name
, datacenter_name
, datacenter_tenant_id
,
4942 db
=db
, db_lock
=db_lock
, ovim
=ovim
)
4944 thread_id
= datacenter_tenants_dict
["uuid"]
4945 vim_threads
["running"][thread_id
] = new_thread
4947 except vimconn
.vimconnException
as e
:
4948 raise NfvoException(str(e
), httperrors
.Bad_Request
)
4951 def edit_vim_account(mydb
, nfvo_tenant
, datacenter_tenant_id
, datacenter_id
=None, name
=None, vim_tenant
=None,
4952 vim_tenant_name
=None, vim_username
=None, vim_password
=None, config
=None):
4954 # get vim_account; check is valid for this tenant
4955 from_
= "datacenter_tenants as dt JOIN tenants_datacenters as td ON dt.uuid=td.datacenter_tenant_id"
4956 where_
= {"td.nfvo_tenant_id": nfvo_tenant
}
4957 if datacenter_tenant_id
:
4958 where_
["dt.uuid"] = datacenter_tenant_id
4960 where_
["dt.datacenter_id"] = datacenter_id
4961 vim_accounts
= mydb
.get_rows(SELECT
="dt.uuid as uuid, config", FROM
=from_
, WHERE
=where_
)
4962 if not vim_accounts
:
4963 raise NfvoException("vim_account not found for this tenant", http_code
=httperrors
.Not_Found
)
4964 elif len(vim_accounts
) > 1:
4965 raise NfvoException("found more than one vim_account for this tenant", http_code
=httperrors
.Conflict
)
4966 datacenter_tenant_id
= vim_accounts
[0]["uuid"]
4967 original_config
= vim_accounts
[0]["config"]
4971 original_config_dict
= yaml
.load(original_config
)
4972 original_config_dict
.update(config
)
4973 update
["config"] = yaml
.safe_dump(original_config_dict
, default_flow_style
=True, width
=256)
4975 update_
['name'] = name
4977 update_
['vim_tenant_id'] = vim_tenant
4979 update_
['vim_tenant_name'] = vim_tenant_name
4981 update_
['user'] = vim_username
4983 update_
['passwd'] = vim_password
4985 mydb
.update_rows("datacenter_tenants", UPDATE
=update_
, WHERE
={"uuid": datacenter_tenant_id
})
4987 vim_threads
["running"][datacenter_tenant_id
].insert_task("reload")
4988 return datacenter_tenant_id
4990 def delete_vim_account(mydb
, tenant_id
, vim_account_id
, datacenter
=None):
4991 #get nfvo_tenant info
4992 if not tenant_id
or tenant_id
=="any":
4995 tenant_dict
= mydb
.get_table_by_uuid_name('nfvo_tenants', tenant_id
)
4996 tenant_uuid
= tenant_dict
['uuid']
4998 #check that this association exist before
4999 tenants_datacenter_dict
= {}
5001 datacenter_id
, _
= get_datacenter_uuid(mydb
, tenant_uuid
, datacenter
)
5002 tenants_datacenter_dict
["datacenter_id"] = datacenter_id
5003 elif vim_account_id
:
5004 tenants_datacenter_dict
["datacenter_tenant_id"] = vim_account_id
5006 tenants_datacenter_dict
["nfvo_tenant_id"] = tenant_uuid
5007 tenant_datacenter_list
= mydb
.get_rows(FROM
='tenants_datacenters', WHERE
=tenants_datacenter_dict
)
5008 if len(tenant_datacenter_list
)==0 and tenant_uuid
:
5009 raise NfvoException("datacenter '{}' and tenant '{}' are not attached".format(datacenter_id
, tenant_dict
['uuid']), httperrors
.Not_Found
)
5011 #delete this association
5012 mydb
.delete_row(FROM
='tenants_datacenters', WHERE
=tenants_datacenter_dict
)
5014 #get vim_tenant info and deletes
5016 for tenant_datacenter_item
in tenant_datacenter_list
:
5017 vim_tenant_dict
= mydb
.get_table_by_uuid_name('datacenter_tenants', tenant_datacenter_item
['datacenter_tenant_id'])
5018 #try to delete vim:tenant
5020 mydb
.delete_row_by_id('datacenter_tenants', tenant_datacenter_item
['datacenter_tenant_id'])
5021 if vim_tenant_dict
['created']=='true':
5022 #delete tenant at VIM if created by NFVO
5024 datacenter_id
, myvim
= get_datacenter_by_name_uuid(mydb
, tenant_id
, datacenter
)
5025 myvim
.delete_tenant(vim_tenant_dict
['vim_tenant_id'])
5026 except vimconn
.vimconnException
as e
:
5027 warning
= "Not possible to delete vim_tenant_id {} from VIM: {} ".format(vim_tenant_dict
['vim_tenant_id'], str(e
))
5028 logger
.warn(warning
)
5029 except db_base_Exception
as e
:
5030 logger
.error("Cannot delete datacenter_tenants " + str(e
))
5031 pass # the error will be caused because dependencies, vim_tenant can not be deleted
5032 thread_id
= tenant_datacenter_item
["datacenter_tenant_id"]
5033 thread
= vim_threads
["running"].get(thread_id
)
5035 thread
.insert_task("exit")
5036 vim_threads
["deleting"][thread_id
] = thread
5037 return "datacenter {} detached. {}".format(datacenter_id
, warning
)
5040 def datacenter_action(mydb
, tenant_id
, datacenter
, action_dict
):
5042 #get datacenter info
5043 datacenter_id
, myvim
= get_datacenter_by_name_uuid(mydb
, tenant_id
, datacenter
)
5045 if 'net-update' in action_dict
:
5047 nets
= myvim
.get_network_list(filter_dict
={'shared': True, 'admin_state_up': True, 'status': 'ACTIVE'})
5049 except vimconn
.vimconnException
as e
:
5050 #logger.error("nfvo.datacenter_action() Not possible to get_network_list from VIM: %s ", str(e))
5051 raise NfvoException(str(e
), httperrors
.Internal_Server_Error
)
5052 #update nets Change from VIM format to NFVO format
5055 net_nfvo
={'datacenter_id': datacenter_id
}
5056 net_nfvo
['name'] = net
['name']
5057 #net_nfvo['description']= net['name']
5058 net_nfvo
['vim_net_id'] = net
['id']
5059 net_nfvo
['type'] = net
['type'][0:6] #change from ('ptp','data','bridge_data','bridge_man') to ('bridge','data','ptp')
5060 net_nfvo
['shared'] = net
['shared']
5061 net_nfvo
['multipoint'] = False if net
['type']=='ptp' else True
5062 net_list
.append(net_nfvo
)
5063 inserted
, deleted
= mydb
.update_datacenter_nets(datacenter_id
, net_list
)
5064 logger
.info("Inserted %d nets, deleted %d old nets", inserted
, deleted
)
5066 elif 'net-edit' in action_dict
:
5067 net
= action_dict
['net-edit'].pop('net')
5068 what
= 'vim_net_id' if utils
.check_valid_uuid(net
) else 'name'
5069 result
= mydb
.update_rows('datacenter_nets', action_dict
['net-edit'],
5070 WHERE
={'datacenter_id':datacenter_id
, what
: net
})
5072 elif 'net-delete' in action_dict
:
5073 net
= action_dict
['net-deelte'].get('net')
5074 what
= 'vim_net_id' if utils
.check_valid_uuid(net
) else 'name'
5075 result
= mydb
.delete_row(FROM
='datacenter_nets',
5076 WHERE
={'datacenter_id':datacenter_id
, what
: net
})
5080 raise NfvoException("Unknown action " + str(action_dict
), httperrors
.Bad_Request
)
5083 def datacenter_edit_netmap(mydb
, tenant_id
, datacenter
, netmap
, action_dict
):
5084 #get datacenter info
5085 datacenter_id
, _
= get_datacenter_by_name_uuid(mydb
, tenant_id
, datacenter
)
5087 what
= 'uuid' if utils
.check_valid_uuid(netmap
) else 'name'
5088 result
= mydb
.update_rows('datacenter_nets', action_dict
['netmap'],
5089 WHERE
={'datacenter_id':datacenter_id
, what
: netmap
})
5093 def datacenter_new_netmap(mydb
, tenant_id
, datacenter
, action_dict
=None):
5094 #get datacenter info
5095 datacenter_id
, myvim
= get_datacenter_by_name_uuid(mydb
, tenant_id
, datacenter
)
5098 action_dict
= action_dict
["netmap"]
5099 if 'vim_id' in action_dict
:
5100 filter_dict
["id"] = action_dict
['vim_id']
5101 if 'vim_name' in action_dict
:
5102 filter_dict
["name"] = action_dict
['vim_name']
5104 filter_dict
["shared"] = True
5107 vim_nets
= myvim
.get_network_list(filter_dict
=filter_dict
)
5108 except vimconn
.vimconnException
as e
:
5109 #logger.error("nfvo.datacenter_new_netmap() Not possible to get_network_list from VIM: %s ", str(e))
5110 raise NfvoException(str(e
), httperrors
.Internal_Server_Error
)
5111 if len(vim_nets
)>1 and action_dict
:
5112 raise NfvoException("more than two networks found, specify with vim_id", httperrors
.Conflict
)
5113 elif len(vim_nets
)==0: # and action_dict:
5114 raise NfvoException("Not found a network at VIM with " + str(filter_dict
), httperrors
.Not_Found
)
5116 for net
in vim_nets
:
5117 net_nfvo
={'datacenter_id': datacenter_id
}
5118 if action_dict
and "name" in action_dict
:
5119 net_nfvo
['name'] = action_dict
['name']
5121 net_nfvo
['name'] = net
['name']
5122 #net_nfvo['description']= net['name']
5123 net_nfvo
['vim_net_id'] = net
['id']
5124 net_nfvo
['type'] = net
['type'][0:6] #change from ('ptp','data','bridge_data','bridge_man') to ('bridge','data','ptp')
5125 net_nfvo
['shared'] = net
['shared']
5126 net_nfvo
['multipoint'] = False if net
['type']=='ptp' else True
5128 net_id
= mydb
.new_row("datacenter_nets", net_nfvo
, add_uuid
=True)
5129 net_nfvo
["status"] = "OK"
5130 net_nfvo
["uuid"] = net_id
5131 except db_base_Exception
as e
:
5135 net_nfvo
["status"] = "FAIL: " + str(e
)
5136 net_list
.append(net_nfvo
)
5139 def get_sdn_net_id(mydb
, tenant_id
, datacenter
, network_id
):
5140 # obtain all network data
5142 if utils
.check_valid_uuid(network_id
):
5143 filter_dict
= {"id": network_id
}
5145 filter_dict
= {"name": network_id
}
5147 datacenter_id
, myvim
= get_datacenter_by_name_uuid(mydb
, tenant_id
, datacenter
)
5148 network
= myvim
.get_network_list(filter_dict
=filter_dict
)
5149 except vimconn
.vimconnException
as e
:
5150 raise NfvoException("Not possible to get_sdn_net_id from VIM: {}".format(str(e
)), e
.http_code
)
5152 # ensure the network is defined
5153 if len(network
) == 0:
5154 raise NfvoException("Network {} is not present in the system".format(network_id
),
5155 httperrors
.Bad_Request
)
5157 # ensure there is only one network with the provided name
5158 if len(network
) > 1:
5159 raise NfvoException("Multiple networks present in vim identified by {}".format(network_id
), httperrors
.Bad_Request
)
5161 # ensure it is a dataplane network
5162 if network
[0]['type'] != 'data':
5165 # ensure we use the id
5166 network_id
= network
[0]['id']
5168 # search in dabase mano_db in table instance nets for the sdn_net_id that corresponds to the vim_net_id==network_id
5169 # and with instance_scenario_id==NULL
5170 #search_dict = {'vim_net_id': network_id, 'instance_scenario_id': None}
5171 search_dict
= {'vim_net_id': network_id
}
5174 #sdn_network_id = mydb.get_rows(SELECT=('sdn_net_id',), FROM='instance_nets', WHERE=search_dict)[0]['sdn_net_id']
5175 result
= mydb
.get_rows(SELECT
=('sdn_net_id',), FROM
='instance_nets', WHERE
=search_dict
)
5176 except db_base_Exception
as e
:
5177 raise NfvoException("db_base_Exception obtaining SDN network to associated to vim network {}".format(
5178 network_id
) + str(e
), e
.http_code
)
5182 if net
['sdn_net_id'] != None:
5184 sdn_net_id
= net
['sdn_net_id']
5186 if sdn_net_counter
== 0:
5188 elif sdn_net_counter
== 1:
5191 raise NfvoException("More than one SDN network is associated to vim network {}".format(
5192 network_id
), httperrors
.Internal_Server_Error
)
5194 def get_sdn_controller_id(mydb
, datacenter
):
5195 # Obtain sdn controller id
5196 config
= mydb
.get_rows(SELECT
=('config',), FROM
='datacenters', WHERE
={'uuid': datacenter
})[0].get('config', '{}')
5200 return yaml
.load(config
).get('sdn-controller')
5202 def vim_net_sdn_attach(mydb
, tenant_id
, datacenter
, network_id
, descriptor
):
5204 sdn_network_id
= get_sdn_net_id(mydb
, tenant_id
, datacenter
, network_id
)
5205 if not sdn_network_id
:
5206 raise NfvoException("No SDN network is associated to vim-network {}".format(network_id
), httperrors
.Internal_Server_Error
)
5208 #Obtain sdn controller id
5209 controller_id
= get_sdn_controller_id(mydb
, datacenter
)
5210 if not controller_id
:
5211 raise NfvoException("No SDN controller is set for datacenter {}".format(datacenter
), httperrors
.Internal_Server_Error
)
5213 #Obtain sdn controller info
5214 sdn_controller
= ovim
.show_of_controller(controller_id
)
5217 'name': 'external_port',
5218 'net_id': sdn_network_id
,
5219 'ofc_id': controller_id
,
5220 'switch_dpid': sdn_controller
['dpid'],
5221 'switch_port': descriptor
['port']
5224 if 'vlan' in descriptor
:
5225 port_data
['vlan'] = descriptor
['vlan']
5226 if 'mac' in descriptor
:
5227 port_data
['mac'] = descriptor
['mac']
5229 result
= ovim
.new_port(port_data
)
5230 except ovimException
as e
:
5231 raise NfvoException("ovimException attaching SDN network {} to vim network {}".format(
5232 sdn_network_id
, network_id
) + str(e
), httperrors
.Internal_Server_Error
)
5233 except db_base_Exception
as e
:
5234 raise NfvoException("db_base_Exception attaching SDN network to vim network {}".format(
5235 network_id
) + str(e
), e
.http_code
)
5237 return 'Port uuid: '+ result
5239 def vim_net_sdn_detach(mydb
, tenant_id
, datacenter
, network_id
, port_id
=None):
5241 filter = {'uuid': port_id
}
5243 sdn_network_id
= get_sdn_net_id(mydb
, tenant_id
, datacenter
, network_id
)
5244 if not sdn_network_id
:
5245 raise NfvoException("No SDN network is associated to vim-network {}".format(network_id
),
5246 httperrors
.Internal_Server_Error
)
5247 #in case no port_id is specified only ports marked as 'external_port' will be detached
5248 filter = {'name': 'external_port', 'net_id': sdn_network_id
}
5251 port_list
= ovim
.get_ports(columns
={'uuid'}, filter=filter)
5252 except ovimException
as e
:
5253 raise NfvoException("ovimException obtaining external ports for net {}. ".format(network_id
) + str(e
),
5254 httperrors
.Internal_Server_Error
)
5256 if len(port_list
) == 0:
5257 raise NfvoException("No ports attached to the network {} were found with the requested criteria".format(network_id
),
5258 httperrors
.Bad_Request
)
5261 for port
in port_list
:
5263 port_uuid_list
.append(port
['uuid'])
5264 ovim
.delete_port(port
['uuid'])
5265 except ovimException
as e
:
5266 raise NfvoException("ovimException deleting port {} for net {}. ".format(port
['uuid'], network_id
) + str(e
), httperrors
.Internal_Server_Error
)
5268 return 'Detached ports uuid: {}'.format(','.join(port_uuid_list
))
5270 def vim_action_get(mydb
, tenant_id
, datacenter
, item
, name
):
5271 #get datacenter info
5272 datacenter_id
, myvim
= get_datacenter_by_name_uuid(mydb
, tenant_id
, datacenter
)
5275 if utils
.check_valid_uuid(name
):
5276 filter_dict
["id"] = name
5278 filter_dict
["name"] = name
5280 if item
=="networks":
5281 #filter_dict['tenant_id'] = myvim['tenant_id']
5282 content
= myvim
.get_network_list(filter_dict
=filter_dict
)
5284 if len(content
) == 0:
5285 raise NfvoException("Network {} is not present in the system. ".format(name
),
5286 httperrors
.Bad_Request
)
5288 #Update the networks with the attached ports
5290 sdn_network_id
= get_sdn_net_id(mydb
, tenant_id
, datacenter
, net
['id'])
5291 if sdn_network_id
!= None:
5293 #port_list = ovim.get_ports(columns={'uuid', 'switch_port', 'vlan'}, filter={'name': 'external_port', 'net_id': sdn_network_id})
5294 port_list
= ovim
.get_ports(columns
={'uuid', 'switch_port', 'vlan','name'}, filter={'net_id': sdn_network_id
})
5295 except ovimException
as e
:
5296 raise NfvoException("ovimException obtaining external ports for net {}. ".format(network_id
) + str(e
), httperrors
.Internal_Server_Error
)
5297 #Remove field name and if port name is external_port save it as 'type'
5298 for port
in port_list
:
5299 if port
['name'] == 'external_port':
5300 port
['type'] = "External"
5302 net
['sdn_network_id'] = sdn_network_id
5303 net
['sdn_attached_ports'] = port_list
5305 elif item
=="tenants":
5306 content
= myvim
.get_tenant_list(filter_dict
=filter_dict
)
5307 elif item
== "images":
5309 content
= myvim
.get_image_list(filter_dict
=filter_dict
)
5311 raise NfvoException(item
+ "?", httperrors
.Method_Not_Allowed
)
5312 logger
.debug("vim_action response %s", content
) #update nets Change from VIM format to NFVO format
5313 if name
and len(content
)==1:
5314 return {item
[:-1]: content
[0]}
5315 elif name
and len(content
)==0:
5316 raise NfvoException("No {} found with ".format(item
[:-1]) + " and ".join(map(lambda x
: str(x
[0])+": "+str(x
[1]), filter_dict
.iteritems())),
5319 return {item
: content
}
5320 except vimconn
.vimconnException
as e
:
5321 print "vim_action Not possible to get_%s_list from VIM: %s " % (item
, str(e
))
5322 raise NfvoException("Not possible to get_{}_list from VIM: {}".format(item
, str(e
)), e
.http_code
)
5325 def vim_action_delete(mydb
, tenant_id
, datacenter
, item
, name
):
5326 #get datacenter info
5327 if tenant_id
== "any":
5330 datacenter_id
, myvim
= get_datacenter_by_name_uuid(mydb
, tenant_id
, datacenter
)
5332 content
= vim_action_get(mydb
, tenant_id
, datacenter
, item
, name
)
5333 logger
.debug("vim_action_delete vim response: " + str(content
))
5334 items
= content
.values()[0]
5335 if type(items
)==list and len(items
)==0:
5336 raise NfvoException("Not found " + item
, httperrors
.Not_Found
)
5337 elif type(items
)==list and len(items
)>1:
5338 raise NfvoException("Found more than one {} with this name. Use uuid.".format(item
), httperrors
.Not_Found
)
5339 else: # it is a dict
5340 item_id
= items
["id"]
5341 item_name
= str(items
.get("name"))
5344 if item
=="networks":
5345 # If there is a SDN network associated to the vim-network, proceed to clear the relationship and delete it
5346 sdn_network_id
= get_sdn_net_id(mydb
, tenant_id
, datacenter
, item_id
)
5347 if sdn_network_id
!= None:
5348 #Delete any port attachment to this network
5350 port_list
= ovim
.get_ports(columns
={'uuid'}, filter={'net_id': sdn_network_id
})
5351 except ovimException
as e
:
5352 raise NfvoException(
5353 "ovimException obtaining external ports for net {}. ".format(network_id
) + str(e
),
5354 httperrors
.Internal_Server_Error
)
5356 # By calling one by one all ports to be detached we ensure that not only the external_ports get detached
5357 for port
in port_list
:
5358 vim_net_sdn_detach(mydb
, tenant_id
, datacenter
, item_id
, port
['uuid'])
5360 #Delete from 'instance_nets' the correspondence between the vim-net-id and the sdn-net-id
5362 mydb
.delete_row(FROM
='instance_nets', WHERE
={'instance_scenario_id': None, 'sdn_net_id': sdn_network_id
, 'vim_net_id': item_id
})
5363 except db_base_Exception
as e
:
5364 raise NfvoException("Error deleting correspondence for VIM/SDN dataplane networks{}: ".format(correspondence
) +
5365 str(e
), e
.http_code
)
5367 #Delete the SDN network
5369 ovim
.delete_network(sdn_network_id
)
5370 except ovimException
as e
:
5371 logger
.error("ovimException deleting SDN network={} ".format(sdn_network_id
) + str(e
), exc_info
=True)
5372 raise NfvoException("ovimException deleting SDN network={} ".format(sdn_network_id
) + str(e
),
5373 httperrors
.Internal_Server_Error
)
5375 content
= myvim
.delete_network(item_id
)
5376 elif item
=="tenants":
5377 content
= myvim
.delete_tenant(item_id
)
5378 elif item
== "images":
5379 content
= myvim
.delete_image(item_id
)
5381 raise NfvoException(item
+ "?", httperrors
.Method_Not_Allowed
)
5382 except vimconn
.vimconnException
as e
:
5383 #logger.error( "vim_action Not possible to delete_{} {}from VIM: {} ".format(item, name, str(e)))
5384 raise NfvoException("Not possible to delete_{} {} from VIM: {}".format(item
, name
, str(e
)), e
.http_code
)
5386 return "{} {} {} deleted".format(item
[:-1], item_id
,item_name
)
5389 def vim_action_create(mydb
, tenant_id
, datacenter
, item
, descriptor
):
5390 #get datacenter info
5391 logger
.debug("vim_action_create descriptor %s", str(descriptor
))
5392 if tenant_id
== "any":
5394 datacenter_id
, myvim
= get_datacenter_by_name_uuid(mydb
, tenant_id
, datacenter
)
5396 if item
=="networks":
5397 net
= descriptor
["network"]
5398 net_name
= net
.pop("name")
5399 net_type
= net
.pop("type", "bridge")
5400 net_public
= net
.pop("shared", False)
5401 net_ipprofile
= net
.pop("ip_profile", None)
5402 net_vlan
= net
.pop("vlan", None)
5403 content
= myvim
.new_network(net_name
, net_type
, net_ipprofile
, shared
=net_public
, vlan
=net_vlan
) #, **net)
5405 #If the datacenter has a SDN controller defined and the network is of dataplane type, then create the sdn network
5406 if get_sdn_controller_id(mydb
, datacenter
) != None and (net_type
== 'data' or net_type
== 'ptp'):
5407 #obtain datacenter_tenant_id
5408 datacenter_tenant_id
= mydb
.get_rows(SELECT
=('uuid',),
5409 FROM
='datacenter_tenants',
5410 WHERE
={'datacenter_id': datacenter
})[0]['uuid']
5413 sdn_network
['vlan'] = net_vlan
5414 sdn_network
['type'] = net_type
5415 sdn_network
['name'] = net_name
5416 sdn_network
['region'] = datacenter_tenant_id
5417 ovim_content
= ovim
.new_network(sdn_network
)
5418 except ovimException
as e
:
5419 logger
.error("ovimException creating SDN network={} ".format(
5420 sdn_network
) + str(e
), exc_info
=True)
5421 raise NfvoException("ovimException creating SDN network={} ".format(sdn_network
) + str(e
),
5422 httperrors
.Internal_Server_Error
)
5424 # Save entry in in dabase mano_db in table instance_nets to stablish a dictionary vim_net_id <->sdn_net_id
5425 # use instance_scenario_id=None to distinguish from real instaces of nets
5426 correspondence
= {'instance_scenario_id': None,
5427 'sdn_net_id': ovim_content
,
5428 'vim_net_id': content
,
5429 'datacenter_tenant_id': datacenter_tenant_id
5432 mydb
.new_row('instance_nets', correspondence
, add_uuid
=True)
5433 except db_base_Exception
as e
:
5434 raise NfvoException("Error saving correspondence for VIM/SDN dataplane networks{}: {}".format(
5435 correspondence
, e
), e
.http_code
)
5436 elif item
=="tenants":
5437 tenant
= descriptor
["tenant"]
5438 content
= myvim
.new_tenant(tenant
["name"], tenant
.get("description"))
5440 raise NfvoException(item
+ "?", httperrors
.Method_Not_Allowed
)
5441 except vimconn
.vimconnException
as e
:
5442 raise NfvoException("Not possible to create {} at VIM: {}".format(item
, str(e
)), e
.http_code
)
5444 return vim_action_get(mydb
, tenant_id
, datacenter
, item
, content
)
5446 def sdn_controller_create(mydb
, tenant_id
, sdn_controller
):
5447 data
= ovim
.new_of_controller(sdn_controller
)
5448 logger
.debug('New SDN controller created with uuid {}'.format(data
))
5451 def sdn_controller_update(mydb
, tenant_id
, controller_id
, sdn_controller
):
5452 data
= ovim
.edit_of_controller(controller_id
, sdn_controller
)
5453 msg
= 'SDN controller {} updated'.format(data
)
5457 def sdn_controller_list(mydb
, tenant_id
, controller_id
=None):
5458 if controller_id
== None:
5459 data
= ovim
.get_of_controllers()
5461 data
= ovim
.show_of_controller(controller_id
)
5463 msg
= 'SDN controller list:\n {}'.format(data
)
5467 def sdn_controller_delete(mydb
, tenant_id
, controller_id
):
5468 select_
= ('uuid', 'config')
5469 datacenters
= mydb
.get_rows(FROM
='datacenters', SELECT
=select_
)
5470 for datacenter
in datacenters
:
5471 if datacenter
['config']:
5472 config
= yaml
.load(datacenter
['config'])
5473 if 'sdn-controller' in config
and config
['sdn-controller'] == controller_id
:
5474 raise NfvoException("SDN controller {} is in use by datacenter {}".format(controller_id
, datacenter
['uuid']), httperrors
.Conflict
)
5476 data
= ovim
.delete_of_controller(controller_id
)
5477 msg
= 'SDN controller {} deleted'.format(data
)
5481 def datacenter_sdn_port_mapping_set(mydb
, tenant_id
, datacenter_id
, sdn_port_mapping
):
5482 controller
= mydb
.get_rows(FROM
="datacenters", SELECT
=("config",), WHERE
={"uuid":datacenter_id
})
5483 if len(controller
) < 1:
5484 raise NfvoException("Datacenter {} not present in the database".format(datacenter_id
), httperrors
.Not_Found
)
5487 sdn_controller_id
= yaml
.load(controller
[0]["config"])["sdn-controller"]
5489 raise NfvoException("The datacenter {} has not an SDN controller associated".format(datacenter_id
), httperrors
.Bad_Request
)
5491 sdn_controller
= ovim
.show_of_controller(sdn_controller_id
)
5492 switch_dpid
= sdn_controller
["dpid"]
5495 for compute_node
in sdn_port_mapping
:
5496 #element = {"ofc_id": sdn_controller_id, "region": datacenter_id, "switch_dpid": switch_dpid}
5498 element
["compute_node"] = compute_node
["compute_node"]
5499 for port
in compute_node
["ports"]:
5500 pci
= port
.get("pci")
5501 element
["switch_port"] = port
.get("switch_port")
5502 element
["switch_mac"] = port
.get("switch_mac")
5503 if not pci
or not (element
["switch_port"] or element
["switch_mac"]):
5504 raise NfvoException ("The mapping must contain the 'pci' and at least one of the elements 'switch_port'"
5505 " or 'switch_mac'", httperrors
.Bad_Request
)
5506 for pci_expanded
in utils
.expand_brackets(pci
):
5507 element
["pci"] = pci_expanded
5508 maps
.append(dict(element
))
5510 return ovim
.set_of_port_mapping(maps
, ofc_id
=sdn_controller_id
, switch_dpid
=switch_dpid
, region
=datacenter_id
)
5512 def datacenter_sdn_port_mapping_list(mydb
, tenant_id
, datacenter_id
):
5513 maps
= ovim
.get_of_port_mappings(db_filter
={"region": datacenter_id
})
5516 "sdn-controller": None,
5517 "datacenter-id": datacenter_id
,
5519 "ports_mapping": list()
5522 datacenter
= mydb
.get_table_by_uuid_name('datacenters', datacenter_id
)
5523 if datacenter
['config']:
5524 config
= yaml
.load(datacenter
['config'])
5525 if 'sdn-controller' in config
:
5526 controller_id
= config
['sdn-controller']
5527 sdn_controller
= sdn_controller_list(mydb
, tenant_id
, controller_id
)
5528 result
["sdn-controller"] = controller_id
5529 result
["dpid"] = sdn_controller
["dpid"]
5531 if result
["sdn-controller"] == None:
5532 raise NfvoException("SDN controller is not defined for datacenter {}".format(datacenter_id
), httperrors
.Bad_Request
)
5533 if result
["dpid"] == None:
5534 raise NfvoException("It was not possible to determine DPID for SDN controller {}".format(result
["sdn-controller"]),
5535 httperrors
.Internal_Server_Error
)
5540 ports_correspondence_dict
= dict()
5542 if result
["sdn-controller"] != link
["ofc_id"]:
5543 raise NfvoException("The sdn-controller specified for different port mappings differ", httperrors
.Internal_Server_Error
)
5544 if result
["dpid"] != link
["switch_dpid"]:
5545 raise NfvoException("The dpid specified for different port mappings differ", httperrors
.Internal_Server_Error
)
5547 element
["pci"] = link
["pci"]
5548 if link
["switch_port"]:
5549 element
["switch_port"] = link
["switch_port"]
5550 if link
["switch_mac"]:
5551 element
["switch_mac"] = link
["switch_mac"]
5553 if not link
["compute_node"] in ports_correspondence_dict
:
5555 content
["compute_node"] = link
["compute_node"]
5556 content
["ports"] = list()
5557 ports_correspondence_dict
[link
["compute_node"]] = content
5559 ports_correspondence_dict
[link
["compute_node"]]["ports"].append(element
)
5561 for key
in sorted(ports_correspondence_dict
):
5562 result
["ports_mapping"].append(ports_correspondence_dict
[key
])
5566 def datacenter_sdn_port_mapping_delete(mydb
, tenant_id
, datacenter_id
):
5567 return ovim
.clear_of_port_mapping(db_filter
={"region":datacenter_id
})
5569 def create_RO_keypair(tenant_id
):
5571 Creates a public / private keys for a RO tenant and returns their values
5573 tenant_id: ID of the tenant
5575 public_key: Public key for the RO tenant
5576 private_key: Encrypted private key for RO tenant
5580 key
= RSA
.generate(bits
)
5582 public_key
= key
.publickey().exportKey('OpenSSH')
5583 if isinstance(public_key
, ValueError):
5584 raise NfvoException("Unable to create public key: {}".format(public_key
), httperrors
.Internal_Server_Error
)
5585 private_key
= key
.exportKey(passphrase
=tenant_id
, pkcs
=8)
5586 except (ValueError, NameError) as e
:
5587 raise NfvoException("Unable to create private key: {}".format(e
), httperrors
.Internal_Server_Error
)
5588 return public_key
, private_key
5590 def decrypt_key (key
, tenant_id
):
5592 Decrypts an encrypted RSA key
5594 key: Private key to be decrypted
5595 tenant_id: ID of the tenant
5597 unencrypted_key: Unencrypted private key for RO tenant
5600 key
= RSA
.importKey(key
,tenant_id
)
5601 unencrypted_key
= key
.exportKey('PEM')
5602 if isinstance(unencrypted_key
, ValueError):
5603 raise NfvoException("Unable to decrypt the private key: {}".format(unencrypted_key
), httperrors
.Internal_Server_Error
)
5604 except ValueError as e
:
5605 raise NfvoException("Unable to decrypt the private key: {}".format(e
), httperrors
.Internal_Server_Error
)
5606 return unencrypted_key