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"] and 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
)
1072 if not db_vm
.get("image_id"):
1073 if not db_vm
["pdu_type"]:
1074 raise NfvoException("Not defined image for VDU")
1075 # create a fake image
1079 if vdu
.get("cloud-init"):
1080 boot_data
["user-data"] = str(vdu
["cloud-init"])
1081 elif vdu
.get("cloud-init-file"):
1082 # TODO Where this file content is present???
1083 # boot_data["user-data"] = vnfd_yang.files[vdu["cloud-init-file"]]
1084 boot_data
["user-data"] = str(vdu
["cloud-init-file"])
1086 if vdu
.get("supplemental-boot-data"):
1087 if vdu
["supplemental-boot-data"].get('boot-data-drive'):
1088 boot_data
['boot-data-drive'] = True
1089 if vdu
["supplemental-boot-data"].get('config-file'):
1090 om_cfgfile_list
= list()
1091 for custom_config_file
in vdu
["supplemental-boot-data"]['config-file'].itervalues():
1092 # TODO Where this file content is present???
1093 cfg_source
= str(custom_config_file
["source"])
1094 om_cfgfile_list
.append({"dest": custom_config_file
["dest"],
1095 "content": cfg_source
})
1096 boot_data
['config-files'] = om_cfgfile_list
1098 db_vm
["boot_data"] = yaml
.safe_dump(boot_data
, default_flow_style
=True, width
=256)
1100 db_vms
.append(db_vm
)
1103 # table interfaces (internal/external interfaces)
1104 flavor_epa_interfaces
= []
1105 # for iface in chain(vdu.get("internal-interface").itervalues(), vdu.get("external-interface").itervalues()):
1106 for iface
in vdu
.get("interface").itervalues():
1107 flavor_epa_interface
= {}
1108 iface_uuid
= str(uuid4())
1109 uuid_list
.append(iface_uuid
)
1112 "internal_name": get_str(iface
, "name", 255),
1115 flavor_epa_interface
["name"] = db_interface
["internal_name"]
1116 if iface
.get("virtual-interface").get("vpci"):
1117 db_interface
["vpci"] = get_str(iface
.get("virtual-interface"), "vpci", 12)
1118 flavor_epa_interface
["vpci"] = db_interface
["vpci"]
1120 if iface
.get("virtual-interface").get("bandwidth"):
1121 bps
= int(iface
.get("virtual-interface").get("bandwidth"))
1122 db_interface
["bw"] = int(math
.ceil(bps
/1000000.0))
1123 flavor_epa_interface
["bandwidth"] = "{} Mbps".format(db_interface
["bw"])
1125 if iface
.get("virtual-interface").get("type") == "OM-MGMT":
1126 db_interface
["type"] = "mgmt"
1127 elif iface
.get("virtual-interface").get("type") in ("VIRTIO", "E1000", "PARAVIRT"):
1128 db_interface
["type"] = "bridge"
1129 db_interface
["model"] = get_str(iface
.get("virtual-interface"), "type", 12)
1130 elif iface
.get("virtual-interface").get("type") in ("SR-IOV", "PCI-PASSTHROUGH"):
1131 db_interface
["type"] = "data"
1132 db_interface
["model"] = get_str(iface
.get("virtual-interface"), "type", 12)
1133 flavor_epa_interface
["dedicated"] = "no" if iface
["virtual-interface"]["type"] == "SR-IOV" \
1135 flavor_epa_interfaces
.append(flavor_epa_interface
)
1137 raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{}]':'vdu[{}]':'interface':'virtual"
1138 "-interface':'type':'{}'. Interface type is not supported".format(
1139 vnfd_id
, vdu_id
, iface
.get("virtual-interface").get("type")),
1140 httperrors
.Bad_Request
)
1142 if iface
.get("mgmt-interface"):
1143 db_interface
["type"] = "mgmt"
1145 if iface
.get("external-connection-point-ref"):
1147 cp
= vnfd
.get("connection-point")[iface
.get("external-connection-point-ref")]
1148 db_interface
["external_name"] = get_str(cp
, "name", 255)
1149 cp_name2iface_uuid
[db_interface
["external_name"]] = iface_uuid
1150 cp_name2vm_uuid
[db_interface
["external_name"]] = vm_uuid
1151 cp_name2db_interface
[db_interface
["external_name"]] = db_interface
1152 for cp_descriptor
in vnfd_descriptor
["connection-point"]:
1153 if cp_descriptor
["name"] == db_interface
["external_name"]:
1158 if vdu_id
in vdu_id2cp_name
:
1159 vdu_id2cp_name
[vdu_id
] = None # more than two connecdtion point for this VDU
1161 vdu_id2cp_name
[vdu_id
] = db_interface
["external_name"]
1164 if str(cp_descriptor
.get("port-security-enabled")).lower() == "false":
1165 db_interface
["port_security"] = 0
1166 elif str(cp_descriptor
.get("port-security-enabled")).lower() == "true":
1167 db_interface
["port_security"] = 1
1169 raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{vnf}]':'vdu[{vdu}]':"
1170 "'interface[{iface}]':'vnfd-connection-point-ref':'{cp}' is not present"
1171 " at connection-point".format(
1172 vnf
=vnfd_id
, vdu
=vdu_id
, iface
=iface
["name"],
1173 cp
=iface
.get("vnfd-connection-point-ref")),
1174 httperrors
.Bad_Request
)
1175 elif iface
.get("internal-connection-point-ref"):
1177 for icp_descriptor
in vdu_descriptor
["internal-connection-point"]:
1178 if icp_descriptor
["id"] == str(iface
.get("internal-connection-point-ref")):
1181 raise KeyError("does not exist at vdu:internal-connection-point")
1184 for vld
in vnfd
.get("internal-vld").itervalues():
1185 for cp
in vld
.get("internal-connection-point").itervalues():
1186 if cp
.get("id-ref") == iface
.get("internal-connection-point-ref"):
1188 raise KeyError("is referenced by more than one 'internal-vld'")
1192 raise KeyError("is not referenced by any 'internal-vld'")
1194 db_interface
["net_id"] = net_id2uuid
[icp_vld
.get("id")]
1195 if str(icp_descriptor
.get("port-security-enabled")).lower() == "false":
1196 db_interface
["port_security"] = 0
1197 elif str(icp_descriptor
.get("port-security-enabled")).lower() == "true":
1198 db_interface
["port_security"] = 1
1199 if icp
.get("ip-address"):
1200 if not icp_vld
.get("ip-profile-ref"):
1202 db_interface
["ip_address"] = str(icp
.get("ip-address"))
1203 except KeyError as e
:
1204 raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{vnf}]':'vdu[{vdu}]':"
1205 "'interface[{iface}]':'internal-connection-point-ref':'{cp}'"
1207 vnf
=vnfd_id
, vdu
=vdu_id
, iface
=iface
["name"],
1208 cp
=iface
.get("internal-connection-point-ref"), msg
=str(e
)),
1209 httperrors
.Bad_Request
)
1210 if iface
.get("position"):
1211 db_interface
["created_at"] = int(iface
.get("position")) * 50
1212 if iface
.get("mac-address"):
1213 db_interface
["mac"] = str(iface
.get("mac-address"))
1214 db_interfaces
.append(db_interface
)
1218 "name": get_str(vdu
, "name", 250) + "-flv",
1219 "vcpus": int(vdu
["vm-flavor"].get("vcpu-count", 1)),
1220 "ram": int(vdu
["vm-flavor"].get("memory-mb", 1)),
1221 "disk": int(vdu
["vm-flavor"].get("storage-gb", 0)),
1223 # TODO revise the case of several numa-node-policy node
1227 extended
["devices"] = devices
1228 if flavor_epa_interfaces
:
1229 numa
["interfaces"] = flavor_epa_interfaces
1230 if vdu
.get("guest-epa"): # TODO or dedicated_int:
1231 epa_vcpu_set
= False
1232 if vdu
["guest-epa"].get("numa-node-policy"): # TODO or dedicated_int:
1233 numa_node_policy
= vdu
["guest-epa"].get("numa-node-policy")
1234 if numa_node_policy
.get("node"):
1235 numa_node
= numa_node_policy
["node"].values()[0]
1236 if numa_node
.get("num-cores"):
1237 numa
["cores"] = numa_node
["num-cores"]
1239 if numa_node
.get("paired-threads"):
1240 if numa_node
["paired-threads"].get("num-paired-threads"):
1241 numa
["paired-threads"] = int(numa_node
["paired-threads"]["num-paired-threads"])
1243 if len(numa_node
["paired-threads"].get("paired-thread-ids")):
1244 numa
["paired-threads-id"] = []
1245 for pair
in numa_node
["paired-threads"]["paired-thread-ids"].itervalues():
1246 numa
["paired-threads-id"].append(
1247 (str(pair
["thread-a"]), str(pair
["thread-b"]))
1249 if numa_node
.get("num-threads"):
1250 numa
["threads"] = int(numa_node
["num-threads"])
1252 if numa_node
.get("memory-mb"):
1253 numa
["memory"] = max(int(numa_node
["memory-mb"] / 1024), 1)
1254 if vdu
["guest-epa"].get("mempage-size"):
1255 if vdu
["guest-epa"]["mempage-size"] != "SMALL":
1256 numa
["memory"] = max(int(db_flavor
["ram"] / 1024), 1)
1257 if vdu
["guest-epa"].get("cpu-pinning-policy") and not epa_vcpu_set
:
1258 if vdu
["guest-epa"]["cpu-pinning-policy"] == "DEDICATED":
1259 if vdu
["guest-epa"].get("cpu-thread-pinning-policy") and \
1260 vdu
["guest-epa"]["cpu-thread-pinning-policy"] != "PREFER":
1261 numa
["cores"] = max(db_flavor
["vcpus"], 1)
1263 numa
["threads"] = max(db_flavor
["vcpus"], 1)
1265 extended
["numas"] = [numa
]
1267 extended_text
= yaml
.safe_dump(extended
, default_flow_style
=True, width
=256)
1268 db_flavor
["extended"] = extended_text
1269 # look if flavor exist
1270 temp_flavor_dict
= {'disk': db_flavor
.get('disk', 0),
1271 'ram': db_flavor
.get('ram'),
1272 'vcpus': db_flavor
.get('vcpus'),
1273 'extended': db_flavor
.get('extended')
1275 existing_flavors
= mydb
.get_rows(FROM
="flavors", WHERE
=temp_flavor_dict
)
1276 if existing_flavors
:
1277 flavor_uuid
= existing_flavors
[0]["uuid"]
1279 flavor_uuid
= str(uuid4())
1280 uuid_list
.append(flavor_uuid
)
1281 db_flavor
["uuid"] = flavor_uuid
1282 db_flavors
.append(db_flavor
)
1283 db_vm
["flavor_id"] = flavor_uuid
1285 # VNF affinity and antiaffinity
1286 for pg
in vnfd
.get("placement-groups").itervalues():
1287 pg_name
= get_str(pg
, "name", 255)
1288 for vdu
in pg
.get("member-vdus").itervalues():
1289 vdu_id
= get_str(vdu
, "member-vdu-ref", 255)
1290 if vdu_id
not in vdu_id2db_table_index
:
1291 raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{vnf}]':'placement-groups[{pg}]':"
1292 "'member-vdus':'{vdu}'. Reference to a non-existing vdu".format(
1293 vnf
=vnfd_id
, pg
=pg_name
, vdu
=vdu_id
),
1294 httperrors
.Bad_Request
)
1295 if vdu_id2db_table_index
[vdu_id
]:
1296 db_vms
[vdu_id2db_table_index
[vdu_id
]]["availability_zone"] = pg_name
1297 # TODO consider the case of isolation and not colocation
1298 # if pg.get("strategy") == "ISOLATION":
1300 # VNF mgmt configuration
1302 if vnfd
["mgmt-interface"].get("vdu-id"):
1303 mgmt_vdu_id
= get_str(vnfd
["mgmt-interface"], "vdu-id", 255)
1304 if mgmt_vdu_id
not in vdu_id2uuid
:
1305 raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{vnf}]':'mgmt-interface':'vdu-id':"
1306 "'{vdu}'. Reference to a non-existing vdu".format(
1307 vnf
=vnfd_id
, vdu
=mgmt_vdu_id
),
1308 httperrors
.Bad_Request
)
1309 mgmt_access
["vm_id"] = vdu_id2uuid
[vnfd
["mgmt-interface"]["vdu-id"]]
1310 # if only one cp is defined by this VDU, mark this interface as of type "mgmt"
1311 if vdu_id2cp_name
.get(mgmt_vdu_id
):
1312 if cp_name2db_interface
[vdu_id2cp_name
[mgmt_vdu_id
]]:
1313 cp_name2db_interface
[vdu_id2cp_name
[mgmt_vdu_id
]]["type"] = "mgmt"
1315 if vnfd
["mgmt-interface"].get("ip-address"):
1316 mgmt_access
["ip-address"] = str(vnfd
["mgmt-interface"].get("ip-address"))
1317 if vnfd
["mgmt-interface"].get("cp"):
1318 if vnfd
["mgmt-interface"]["cp"] not in cp_name2iface_uuid
:
1319 raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{vnf}]':'mgmt-interface':'cp'['{cp}']. "
1320 "Reference to a non-existing connection-point".format(
1321 vnf
=vnfd_id
, cp
=vnfd
["mgmt-interface"]["cp"]),
1322 httperrors
.Bad_Request
)
1323 mgmt_access
["vm_id"] = cp_name2vm_uuid
[vnfd
["mgmt-interface"]["cp"]]
1324 mgmt_access
["interface_id"] = cp_name2iface_uuid
[vnfd
["mgmt-interface"]["cp"]]
1325 # mark this interface as of type mgmt
1326 if cp_name2db_interface
[vnfd
["mgmt-interface"]["cp"]]:
1327 cp_name2db_interface
[vnfd
["mgmt-interface"]["cp"]]["type"] = "mgmt"
1329 default_user
= get_str(vnfd
.get("vnf-configuration", {}).get("config-access", {}).get("ssh-access", {}),
1333 mgmt_access
["default_user"] = default_user
1334 required
= get_str(vnfd
.get("vnf-configuration", {}).get("config-access", {}).get("ssh-access", {}),
1337 mgmt_access
["required"] = required
1340 db_vnf
["mgmt_access"] = yaml
.safe_dump(mgmt_access
, default_flow_style
=True, width
=256)
1342 db_vnfs
.append(db_vnf
)
1346 {"images": db_images
},
1347 {"flavors": db_flavors
},
1348 {"ip_profiles": db_ip_profiles
},
1350 {"interfaces": db_interfaces
},
1353 logger
.debug("create_vnf Deployment done vnfDict: %s",
1354 yaml
.safe_dump(db_tables
, indent
=4, default_flow_style
=False) )
1355 mydb
.new_rows(db_tables
, uuid_list
)
1356 return vnfd_uuid_list
1357 except NfvoException
:
1359 except Exception as e
:
1360 logger
.error("Exception {}".format(e
))
1361 raise # NfvoException("Exception {}".format(e), httperrors.Bad_Request)
1364 @deprecated("Use new_vnfd_v3")
1365 def new_vnf(mydb
, tenant_id
, vnf_descriptor
):
1366 global global_config
1368 # Step 1. Check the VNF descriptor
1369 check_vnf_descriptor(vnf_descriptor
, vnf_descriptor_version
=1)
1370 # Step 2. Check tenant exist
1372 if tenant_id
!= "any":
1373 check_tenant(mydb
, tenant_id
)
1374 if "tenant_id" in vnf_descriptor
["vnf"]:
1375 if vnf_descriptor
["vnf"]["tenant_id"] != tenant_id
:
1376 raise NfvoException("VNF can not have a different tenant owner '{}', must be '{}'".format(vnf_descriptor
["vnf"]["tenant_id"], tenant_id
),
1377 httperrors
.Unauthorized
)
1379 vnf_descriptor
['vnf']['tenant_id'] = tenant_id
1380 # Step 3. Get the URL of the VIM from the nfvo_tenant and the datacenter
1381 if global_config
["auto_push_VNF_to_VIMs"]:
1382 vims
= get_vim(mydb
, tenant_id
, ignore_errors
=True)
1384 # Step 4. Review the descriptor and add missing fields
1385 #print vnf_descriptor
1386 #logger.debug("Refactoring VNF descriptor with fields: description, public (default: true)")
1387 vnf_name
= vnf_descriptor
['vnf']['name']
1388 vnf_descriptor
['vnf']['description'] = vnf_descriptor
['vnf'].get("description", vnf_name
)
1389 if "physical" in vnf_descriptor
['vnf']:
1390 del vnf_descriptor
['vnf']['physical']
1391 #print vnf_descriptor
1393 # Step 6. For each VNFC in the descriptor, flavors and images are created in the VIM
1394 logger
.debug('BEGIN creation of VNF "%s"' % vnf_name
)
1395 logger
.debug("VNF %s: consisting of %d VNFC(s)" % (vnf_name
,len(vnf_descriptor
['vnf']['VNFC'])))
1397 #For each VNFC, we add it to the VNFCDict and we create a flavor.
1398 VNFCDict
= {} # Dictionary, key: VNFC name, value: dict with the relevant information to create the VNF and VMs in the MANO database
1399 rollback_list
= [] # It will contain the new images created in mano. It is used for rollback
1401 logger
.debug("Creating additional disk images and new flavors in the VIM for each VNFC")
1402 for vnfc
in vnf_descriptor
['vnf']['VNFC']:
1404 VNFCitem
["name"] = vnfc
['name']
1405 VNFCitem
["availability_zone"] = vnfc
.get('availability_zone')
1406 VNFCitem
["description"] = vnfc
.get("description", 'VM %s of the VNF %s' %(vnfc
['name'],vnf_name
))
1408 #print "Flavor name: %s. Description: %s" % (VNFCitem["name"]+"-flv", VNFCitem["description"])
1411 myflavorDict
["name"] = vnfc
['name']+"-flv" #Maybe we could rename the flavor by using the field "image name" if exists
1412 myflavorDict
["description"] = VNFCitem
["description"]
1413 myflavorDict
["ram"] = vnfc
.get("ram", 0)
1414 myflavorDict
["vcpus"] = vnfc
.get("vcpus", 0)
1415 myflavorDict
["disk"] = vnfc
.get("disk", 0)
1416 myflavorDict
["extended"] = {}
1418 devices
= vnfc
.get("devices")
1420 myflavorDict
["extended"]["devices"] = devices
1423 # 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
1424 # Another option is that the processor in the VNF descriptor specifies directly the ranking of the host
1426 # Previous code has been commented
1427 #if vnfc['processor']['model'] == "Intel(R) Xeon(R) CPU E5-4620 0 @ 2.20GHz" :
1428 # myflavorDict["flavor"]['extended']['processor_ranking'] = 200
1429 #elif vnfc['processor']['model'] == "Intel(R) Xeon(R) CPU E5-2697 v2 @ 2.70GHz" :
1430 # myflavorDict["flavor"]['extended']['processor_ranking'] = 300
1432 # result2, message = rollback(myvim, myvimURL, myvim_tenant, flavorList, imageList)
1434 # print "Error creating flavor: unknown processor model. Rollback successful."
1435 # return -httperrors.Bad_Request, "Error creating flavor: unknown processor model. Rollback successful."
1437 # return -httperrors.Bad_Request, "Error creating flavor: unknown processor model. Rollback fail: you need to access VIM and delete the following %s" % message
1438 myflavorDict
['extended']['processor_ranking'] = 100 #Hardcoded value, while we decide when the mapping is done
1440 if 'numas' in vnfc
and len(vnfc
['numas'])>0:
1441 myflavorDict
['extended']['numas'] = vnfc
['numas']
1445 # Step 6.2 New flavors are created in the VIM
1446 flavor_id
= create_or_use_flavor(mydb
, vims
, myflavorDict
, rollback_list
)
1448 #print "Flavor id for VNFC %s: %s" % (vnfc['name'],flavor_id)
1449 VNFCitem
["flavor_id"] = flavor_id
1450 VNFCDict
[vnfc
['name']] = VNFCitem
1452 logger
.debug("Creating new images in the VIM for each VNFC")
1453 # Step 6.3 New images are created in the VIM
1454 #For each VNFC, we must create the appropriate image.
1455 #This "for" loop might be integrated with the previous one
1456 #In case this integration is made, the VNFCDict might become a VNFClist.
1457 for vnfc
in vnf_descriptor
['vnf']['VNFC']:
1458 #print "Image name: %s. Description: %s" % (vnfc['name']+"-img", VNFCDict[vnfc['name']]['description'])
1460 image_dict
['name']=vnfc
.get('image name',vnf_name
+"-"+vnfc
['name']+"-img")
1461 image_dict
['universal_name']=vnfc
.get('image name')
1462 image_dict
['description']=vnfc
.get('image name', VNFCDict
[vnfc
['name']]['description'])
1463 image_dict
['location']=vnfc
.get('VNFC image')
1464 #image_dict['new_location']=vnfc.get('image location')
1465 image_dict
['checksum']=vnfc
.get('image checksum')
1466 image_metadata_dict
= vnfc
.get('image metadata', None)
1467 image_metadata_str
= None
1468 if image_metadata_dict
is not None:
1469 image_metadata_str
= yaml
.safe_dump(image_metadata_dict
,default_flow_style
=True,width
=256)
1470 image_dict
['metadata']=image_metadata_str
1471 #print "create_or_use_image", mydb, vims, image_dict, rollback_list
1472 image_id
= create_or_use_image(mydb
, vims
, image_dict
, rollback_list
)
1473 #print "Image id for VNFC %s: %s" % (vnfc['name'],image_id)
1474 VNFCDict
[vnfc
['name']]["image_id"] = image_id
1475 VNFCDict
[vnfc
['name']]["image_path"] = vnfc
.get('VNFC image')
1476 VNFCDict
[vnfc
['name']]["count"] = vnfc
.get('count', 1)
1477 if vnfc
.get("boot-data"):
1478 VNFCDict
[vnfc
['name']]["boot_data"] = yaml
.safe_dump(vnfc
["boot-data"], default_flow_style
=True, width
=256)
1481 # Step 7. Storing the VNF descriptor in the repository
1482 if "descriptor" not in vnf_descriptor
["vnf"]:
1483 vnf_descriptor
["vnf"]["descriptor"] = yaml
.safe_dump(vnf_descriptor
, indent
=4, explicit_start
=True, default_flow_style
=False)
1485 # Step 8. Adding the VNF to the NFVO DB
1486 vnf_id
= mydb
.new_vnf_as_a_whole(tenant_id
,vnf_name
,vnf_descriptor
,VNFCDict
)
1488 except (db_base_Exception
, vimconn
.vimconnException
, KeyError) as e
:
1489 _
, message
= rollback(mydb
, vims
, rollback_list
)
1490 if isinstance(e
, db_base_Exception
):
1491 error_text
= "Exception at database"
1492 elif isinstance(e
, KeyError):
1493 error_text
= "KeyError exception "
1494 e
.http_code
= httperrors
.Internal_Server_Error
1496 error_text
= "Exception at VIM"
1497 error_text
+= " {} {}. {}".format(type(e
).__name
__, str(e
), message
)
1498 #logger.error("start_scenario %s", error_text)
1499 raise NfvoException(error_text
, e
.http_code
)
1502 @deprecated("Use new_vnfd_v3")
1503 def new_vnf_v02(mydb
, tenant_id
, vnf_descriptor
):
1504 global global_config
1506 # Step 1. Check the VNF descriptor
1507 check_vnf_descriptor(vnf_descriptor
, vnf_descriptor_version
=2)
1508 # Step 2. Check tenant exist
1510 if tenant_id
!= "any":
1511 check_tenant(mydb
, tenant_id
)
1512 if "tenant_id" in vnf_descriptor
["vnf"]:
1513 if vnf_descriptor
["vnf"]["tenant_id"] != tenant_id
:
1514 raise NfvoException("VNF can not have a different tenant owner '{}', must be '{}'".format(vnf_descriptor
["vnf"]["tenant_id"], tenant_id
),
1515 httperrors
.Unauthorized
)
1517 vnf_descriptor
['vnf']['tenant_id'] = tenant_id
1518 # Step 3. Get the URL of the VIM from the nfvo_tenant and the datacenter
1519 if global_config
["auto_push_VNF_to_VIMs"]:
1520 vims
= get_vim(mydb
, tenant_id
, ignore_errors
=True)
1522 # Step 4. Review the descriptor and add missing fields
1523 #print vnf_descriptor
1524 #logger.debug("Refactoring VNF descriptor with fields: description, public (default: true)")
1525 vnf_name
= vnf_descriptor
['vnf']['name']
1526 vnf_descriptor
['vnf']['description'] = vnf_descriptor
['vnf'].get("description", vnf_name
)
1527 if "physical" in vnf_descriptor
['vnf']:
1528 del vnf_descriptor
['vnf']['physical']
1529 #print vnf_descriptor
1531 # Step 6. For each VNFC in the descriptor, flavors and images are created in the VIM
1532 logger
.debug('BEGIN creation of VNF "%s"' % vnf_name
)
1533 logger
.debug("VNF %s: consisting of %d VNFC(s)" % (vnf_name
,len(vnf_descriptor
['vnf']['VNFC'])))
1535 #For each VNFC, we add it to the VNFCDict and we create a flavor.
1536 VNFCDict
= {} # Dictionary, key: VNFC name, value: dict with the relevant information to create the VNF and VMs in the MANO database
1537 rollback_list
= [] # It will contain the new images created in mano. It is used for rollback
1539 logger
.debug("Creating additional disk images and new flavors in the VIM for each VNFC")
1540 for vnfc
in vnf_descriptor
['vnf']['VNFC']:
1542 VNFCitem
["name"] = vnfc
['name']
1543 VNFCitem
["description"] = vnfc
.get("description", 'VM %s of the VNF %s' %(vnfc
['name'],vnf_name
))
1545 #print "Flavor name: %s. Description: %s" % (VNFCitem["name"]+"-flv", VNFCitem["description"])
1548 myflavorDict
["name"] = vnfc
['name']+"-flv" #Maybe we could rename the flavor by using the field "image name" if exists
1549 myflavorDict
["description"] = VNFCitem
["description"]
1550 myflavorDict
["ram"] = vnfc
.get("ram", 0)
1551 myflavorDict
["vcpus"] = vnfc
.get("vcpus", 0)
1552 myflavorDict
["disk"] = vnfc
.get("disk", 0)
1553 myflavorDict
["extended"] = {}
1555 devices
= vnfc
.get("devices")
1557 myflavorDict
["extended"]["devices"] = devices
1560 # 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
1561 # Another option is that the processor in the VNF descriptor specifies directly the ranking of the host
1563 # Previous code has been commented
1564 #if vnfc['processor']['model'] == "Intel(R) Xeon(R) CPU E5-4620 0 @ 2.20GHz" :
1565 # myflavorDict["flavor"]['extended']['processor_ranking'] = 200
1566 #elif vnfc['processor']['model'] == "Intel(R) Xeon(R) CPU E5-2697 v2 @ 2.70GHz" :
1567 # myflavorDict["flavor"]['extended']['processor_ranking'] = 300
1569 # result2, message = rollback(myvim, myvimURL, myvim_tenant, flavorList, imageList)
1571 # print "Error creating flavor: unknown processor model. Rollback successful."
1572 # return -httperrors.Bad_Request, "Error creating flavor: unknown processor model. Rollback successful."
1574 # return -httperrors.Bad_Request, "Error creating flavor: unknown processor model. Rollback fail: you need to access VIM and delete the following %s" % message
1575 myflavorDict
['extended']['processor_ranking'] = 100 #Hardcoded value, while we decide when the mapping is done
1577 if 'numas' in vnfc
and len(vnfc
['numas'])>0:
1578 myflavorDict
['extended']['numas'] = vnfc
['numas']
1582 # Step 6.2 New flavors are created in the VIM
1583 flavor_id
= create_or_use_flavor(mydb
, vims
, myflavorDict
, rollback_list
)
1585 #print "Flavor id for VNFC %s: %s" % (vnfc['name'],flavor_id)
1586 VNFCitem
["flavor_id"] = flavor_id
1587 VNFCDict
[vnfc
['name']] = VNFCitem
1589 logger
.debug("Creating new images in the VIM for each VNFC")
1590 # Step 6.3 New images are created in the VIM
1591 #For each VNFC, we must create the appropriate image.
1592 #This "for" loop might be integrated with the previous one
1593 #In case this integration is made, the VNFCDict might become a VNFClist.
1594 for vnfc
in vnf_descriptor
['vnf']['VNFC']:
1595 #print "Image name: %s. Description: %s" % (vnfc['name']+"-img", VNFCDict[vnfc['name']]['description'])
1597 image_dict
['name']=vnfc
.get('image name',vnf_name
+"-"+vnfc
['name']+"-img")
1598 image_dict
['universal_name']=vnfc
.get('image name')
1599 image_dict
['description']=vnfc
.get('image name', VNFCDict
[vnfc
['name']]['description'])
1600 image_dict
['location']=vnfc
.get('VNFC image')
1601 #image_dict['new_location']=vnfc.get('image location')
1602 image_dict
['checksum']=vnfc
.get('image checksum')
1603 image_metadata_dict
= vnfc
.get('image metadata', None)
1604 image_metadata_str
= None
1605 if image_metadata_dict
is not None:
1606 image_metadata_str
= yaml
.safe_dump(image_metadata_dict
,default_flow_style
=True,width
=256)
1607 image_dict
['metadata']=image_metadata_str
1608 #print "create_or_use_image", mydb, vims, image_dict, rollback_list
1609 image_id
= create_or_use_image(mydb
, vims
, image_dict
, rollback_list
)
1610 #print "Image id for VNFC %s: %s" % (vnfc['name'],image_id)
1611 VNFCDict
[vnfc
['name']]["image_id"] = image_id
1612 VNFCDict
[vnfc
['name']]["image_path"] = vnfc
.get('VNFC image')
1613 VNFCDict
[vnfc
['name']]["count"] = vnfc
.get('count', 1)
1614 if vnfc
.get("boot-data"):
1615 VNFCDict
[vnfc
['name']]["boot_data"] = yaml
.safe_dump(vnfc
["boot-data"], default_flow_style
=True, width
=256)
1617 # Step 7. Storing the VNF descriptor in the repository
1618 if "descriptor" not in vnf_descriptor
["vnf"]:
1619 vnf_descriptor
["vnf"]["descriptor"] = yaml
.safe_dump(vnf_descriptor
, indent
=4, explicit_start
=True, default_flow_style
=False)
1621 # Step 8. Adding the VNF to the NFVO DB
1622 vnf_id
= mydb
.new_vnf_as_a_whole2(tenant_id
,vnf_name
,vnf_descriptor
,VNFCDict
)
1624 except (db_base_Exception
, vimconn
.vimconnException
, KeyError) as e
:
1625 _
, message
= rollback(mydb
, vims
, rollback_list
)
1626 if isinstance(e
, db_base_Exception
):
1627 error_text
= "Exception at database"
1628 elif isinstance(e
, KeyError):
1629 error_text
= "KeyError exception "
1630 e
.http_code
= httperrors
.Internal_Server_Error
1632 error_text
= "Exception at VIM"
1633 error_text
+= " {} {}. {}".format(type(e
).__name
__, str(e
), message
)
1634 #logger.error("start_scenario %s", error_text)
1635 raise NfvoException(error_text
, e
.http_code
)
1638 def get_vnf_id(mydb
, tenant_id
, vnf_id
):
1639 #check valid tenant_id
1640 check_tenant(mydb
, tenant_id
)
1643 if tenant_id
!= "any":
1644 where_or
["tenant_id"] = tenant_id
1645 where_or
["public"] = True
1646 vnf
= mydb
.get_table_by_uuid_name('vnfs', vnf_id
, "VNF", WHERE_OR
=where_or
, WHERE_AND_OR
="AND")
1648 vnf_id
= vnf
["uuid"]
1649 filter_keys
= ('uuid', 'name', 'description', 'public', "tenant_id", "osm_id", "created_at")
1650 filtered_content
= dict( (k
,v
) for k
,v
in vnf
.iteritems() if k
in filter_keys
)
1651 #change_keys_http2db(filtered_content, http2db_vnf, reverse=True)
1652 data
={'vnf' : filtered_content
}
1654 content
= mydb
.get_rows(FROM
='vnfs join vms on vnfs.uuid=vms.vnf_id',
1655 SELECT
=('vms.uuid as uuid', 'vms.osm_id as osm_id', 'vms.name as name', 'vms.description as description',
1657 WHERE
={'vnfs.uuid': vnf_id
} )
1658 if len(content
) != 0:
1659 #raise NfvoException("vnf '{}' not found".format(vnf_id), httperrors.Not_Found)
1660 # change boot_data into boot-data
1662 if vm
.get("boot_data"):
1663 vm
["boot-data"] = yaml
.safe_load(vm
["boot_data"])
1666 data
['vnf']['VNFC'] = content
1667 #TODO: GET all the information from a VNFC and include it in the output.
1670 content
= mydb
.get_rows(FROM
='vnfs join nets on vnfs.uuid=nets.vnf_id',
1671 SELECT
=('nets.uuid as uuid','nets.name as name','nets.description as description', 'nets.type as type', 'nets.multipoint as multipoint'),
1672 WHERE
={'vnfs.uuid': vnf_id
} )
1673 data
['vnf']['nets'] = content
1675 #GET ip-profile for each net
1676 for net
in data
['vnf']['nets']:
1677 ipprofiles
= mydb
.get_rows(FROM
='ip_profiles',
1678 SELECT
=('ip_version','subnet_address','gateway_address','dns_address','dhcp_enabled','dhcp_start_address','dhcp_count'),
1679 WHERE
={'net_id': net
["uuid"]} )
1680 if len(ipprofiles
)==1:
1681 net
["ip_profile"] = ipprofiles
[0]
1682 elif len(ipprofiles
)>1:
1683 raise NfvoException("More than one ip-profile found with this criteria: net_id='{}'".format(net
['uuid']), httperrors
.Bad_Request
)
1686 #TODO: For each net, GET its elements and relevant info per element (VNFC, iface, ip_address) and include them in the output.
1688 #GET External Interfaces
1689 content
= mydb
.get_rows(FROM
='vnfs join vms on vnfs.uuid=vms.vnf_id join interfaces on vms.uuid=interfaces.vm_id',\
1690 SELECT
=('interfaces.uuid as uuid','interfaces.external_name as external_name', 'vms.name as vm_name', 'interfaces.vm_id as vm_id', \
1691 'interfaces.internal_name as internal_name', 'interfaces.type as type', 'interfaces.vpci as vpci','interfaces.bw as bw'),\
1692 WHERE
={'vnfs.uuid': vnf_id
, 'interfaces.external_name<>': None} )
1694 data
['vnf']['external-connections'] = content
1699 def delete_vnf(mydb
,tenant_id
,vnf_id
,datacenter
=None,vim_tenant
=None):
1700 # Check tenant exist
1701 if tenant_id
!= "any":
1702 check_tenant(mydb
, tenant_id
)
1703 # Get the URL of the VIM from the nfvo_tenant and the datacenter
1704 vims
= get_vim(mydb
, tenant_id
, ignore_errors
=True)
1708 # Checking if it is a valid uuid and, if not, getting the uuid assuming that the name was provided"
1710 if tenant_id
!= "any":
1711 where_or
["tenant_id"] = tenant_id
1712 where_or
["public"] = True
1713 vnf
= mydb
.get_table_by_uuid_name('vnfs', vnf_id
, "VNF", WHERE_OR
=where_or
, WHERE_AND_OR
="AND")
1714 vnf_id
= vnf
["uuid"]
1716 # "Getting the list of flavors and tenants of the VNF"
1717 flavorList
= get_flavorlist(mydb
, vnf_id
)
1718 if len(flavorList
)==0:
1719 logger
.warn("delete_vnf error. No flavors found for the VNF id '%s'", vnf_id
)
1721 imageList
= get_imagelist(mydb
, vnf_id
)
1722 if len(imageList
)==0:
1723 logger
.warn( "delete_vnf error. No images found for the VNF id '%s'", vnf_id
)
1725 deleted
= mydb
.delete_row_by_id('vnfs', vnf_id
)
1727 raise NfvoException("vnf '{}' not found".format(vnf_id
), httperrors
.Not_Found
)
1730 for flavor
in flavorList
:
1731 #check if flavor is used by other vnf
1733 c
= mydb
.get_rows(FROM
='vms', WHERE
={'flavor_id':flavor
} )
1735 logger
.debug("Flavor '%s' not deleted because it is being used by another VNF", flavor
)
1737 #flavor not used, must be deleted
1739 c
= mydb
.get_rows(FROM
='datacenters_flavors', WHERE
={'flavor_id': flavor
})
1740 for flavor_vim
in c
:
1741 if not flavor_vim
['created']: # skip this flavor because not created by openmano
1745 for vim
in vims
.values():
1746 if vim
["config"]["datacenter_tenant_id"] == flavor_vim
["datacenter_vim_id"]:
1752 myvim
.delete_flavor(flavor_vim
["vim_id"])
1753 except vimconn
.vimconnNotFoundException
:
1754 logger
.warn("VIM flavor %s not exist at datacenter %s", flavor_vim
["vim_id"],
1755 flavor_vim
["datacenter_vim_id"] )
1756 except vimconn
.vimconnException
as e
:
1757 logger
.error("Not possible to delete VIM flavor %s from datacenter %s: %s %s",
1758 flavor_vim
["vim_id"], flavor_vim
["datacenter_vim_id"], type(e
).__name
__, str(e
))
1759 undeletedItems
.append("flavor {} from VIM {}".format(flavor_vim
["vim_id"],
1760 flavor_vim
["datacenter_vim_id"]))
1761 # delete flavor from Database, using table flavors and with cascade foreign key also at datacenters_flavors
1762 mydb
.delete_row_by_id('flavors', flavor
)
1763 except db_base_Exception
as e
:
1764 logger
.error("delete_vnf_error. Not possible to get flavor details and delete '%s'. %s", flavor
, str(e
))
1765 undeletedItems
.append("flavor {}".format(flavor
))
1768 for image
in imageList
:
1770 #check if image is used by other vnf
1771 c
= mydb
.get_rows(FROM
='vms', WHERE
=[{'image_id': image
}, {'image_list LIKE ': '%' + image
+ '%'}])
1773 logger
.debug("Image '%s' not deleted because it is being used by another VNF", image
)
1775 #image not used, must be deleted
1777 c
= mydb
.get_rows(FROM
='datacenters_images', WHERE
={'image_id':image
})
1779 if image_vim
["datacenter_vim_id"] not in vims
: # TODO change to datacenter_tenant_id
1781 if image_vim
['created']=='false': #skip this image because not created by openmano
1783 myvim
=vims
[ image_vim
["datacenter_id"] ]
1785 myvim
.delete_image(image_vim
["vim_id"])
1786 except vimconn
.vimconnNotFoundException
as e
:
1787 logger
.warn("VIM image %s not exist at datacenter %s", image_vim
["vim_id"], image_vim
["datacenter_id"] )
1788 except vimconn
.vimconnException
as e
:
1789 logger
.error("Not possible to delete VIM image %s from datacenter %s: %s %s",
1790 image_vim
["vim_id"], image_vim
["datacenter_id"], type(e
).__name
__, str(e
))
1791 undeletedItems
.append("image {} from VIM {}".format(image_vim
["vim_id"], image_vim
["datacenter_id"] ))
1792 #delete image from Database, using table images and with cascade foreign key also at datacenters_images
1793 mydb
.delete_row_by_id('images', image
)
1794 except db_base_Exception
as e
:
1795 logger
.error("delete_vnf_error. Not possible to get image details and delete '%s'. %s", image
, str(e
))
1796 undeletedItems
.append("image %s" % image
)
1798 return vnf_id
+ " " + vnf
["name"]
1800 # return "delete_vnf. Undeleted: %s" %(undeletedItems)
1803 @deprecated("Not used")
1804 def get_hosts_info(mydb
, nfvo_tenant_id
, datacenter_name
=None):
1805 result
, vims
= get_vim(mydb
, nfvo_tenant_id
, None, datacenter_name
)
1809 return -httperrors
.Not_Found
, "datacenter '%s' not found" % datacenter_name
1810 myvim
= vims
.values()[0]
1811 result
,servers
= myvim
.get_hosts_info()
1813 return result
, servers
1814 topology
= {'name':myvim
['name'] , 'servers': servers
}
1815 return result
, topology
1818 def get_hosts(mydb
, nfvo_tenant_id
):
1819 vims
= get_vim(mydb
, nfvo_tenant_id
)
1821 raise NfvoException("No datacenter found for tenant '{}'".format(str(nfvo_tenant_id
)), httperrors
.Not_Found
)
1823 #print "nfvo.datacenter_action() error. Several datacenters found"
1824 raise NfvoException("More than one datacenters found, try to identify with uuid", httperrors
.Conflict
)
1825 myvim
= vims
.values()[0]
1827 hosts
= myvim
.get_hosts()
1828 logger
.debug('VIM hosts response: '+ yaml
.safe_dump(hosts
, indent
=4, default_flow_style
=False))
1830 datacenter
= {'Datacenters': [ {'name':myvim
['name'],'servers':[]} ] }
1832 server
={'name':host
['name'], 'vms':[]}
1833 for vm
in host
['instances']:
1834 #get internal name and model
1836 c
= mydb
.get_rows(SELECT
=('name',), FROM
='instance_vms as iv join vms on iv.vm_id=vms.uuid',\
1837 WHERE
={'vim_vm_id':vm
['id']} )
1839 logger
.warn("nfvo.get_hosts virtual machine at VIM '{}' not found at tidnfvo".format(vm
['id']))
1841 server
['vms'].append( {'name':vm
['name'] , 'model':c
[0]['name']} )
1843 except db_base_Exception
as e
:
1844 logger
.warn("nfvo.get_hosts virtual machine at VIM '{}' error {}".format(vm
['id'], str(e
)))
1845 datacenter
['Datacenters'][0]['servers'].append(server
)
1846 #return -400, "en construccion"
1848 #print 'datacenters '+ json.dumps(datacenter, indent=4)
1850 except vimconn
.vimconnException
as e
:
1851 raise NfvoException("Not possible to get_host_list from VIM: {}".format(str(e
)), e
.http_code
)
1854 @deprecated("Use new_nsd_v3")
1855 def new_scenario(mydb
, tenant_id
, topo
):
1857 # result, vims = get_vim(mydb, tenant_id)
1859 # return result, vims
1861 if tenant_id
!= "any":
1862 check_tenant(mydb
, tenant_id
)
1863 if "tenant_id" in topo
:
1864 if topo
["tenant_id"] != tenant_id
:
1865 raise NfvoException("VNF can not have a different tenant owner '{}', must be '{}'".format(topo
["tenant_id"], tenant_id
),
1866 httperrors
.Unauthorized
)
1870 #1.1: get VNFs and external_networks (other_nets).
1872 other_nets
={} #external_networks, bridge_networks and data_networkds
1873 nodes
= topo
['topology']['nodes']
1874 for k
in nodes
.keys():
1875 if nodes
[k
]['type'] == 'VNF':
1877 vnfs
[k
]['ifaces'] = {}
1878 elif nodes
[k
]['type'] == 'other_network' or nodes
[k
]['type'] == 'external_network':
1879 other_nets
[k
] = nodes
[k
]
1880 other_nets
[k
]['external']=True
1881 elif nodes
[k
]['type'] == 'network':
1882 other_nets
[k
] = nodes
[k
]
1883 other_nets
[k
]['external']=False
1886 #1.2: Check that VNF are present at database table vnfs. Insert uuid, description and external interfaces
1887 for name
,vnf
in vnfs
.items():
1888 where
= {"OR": {"tenant_id": tenant_id
, 'public': "true"}}
1890 error_pos
= "'topology':'nodes':'" + name
+ "'"
1892 error_text
+= " 'vnf_id' " + vnf
['vnf_id']
1893 where
['uuid'] = vnf
['vnf_id']
1894 if 'VNF model' in vnf
:
1895 error_text
+= " 'VNF model' " + vnf
['VNF model']
1896 where
['name'] = vnf
['VNF model']
1898 raise NfvoException("Descriptor need a 'vnf_id' or 'VNF model' field at " + error_pos
, httperrors
.Bad_Request
)
1900 vnf_db
= mydb
.get_rows(SELECT
=('uuid','name','description'),
1904 raise NfvoException("unknown" + error_text
+ " at " + error_pos
, httperrors
.Not_Found
)
1906 raise NfvoException("more than one" + error_text
+ " at " + error_pos
+ " Concrete with 'vnf_id'", httperrors
.Conflict
)
1907 vnf
['uuid']=vnf_db
[0]['uuid']
1908 vnf
['description']=vnf_db
[0]['description']
1909 #get external interfaces
1910 ext_ifaces
= mydb
.get_rows(SELECT
=('external_name as name','i.uuid as iface_uuid', 'i.type as type'),
1911 FROM
='vnfs join vms on vnfs.uuid=vms.vnf_id join interfaces as i on vms.uuid=i.vm_id',
1912 WHERE
={'vnfs.uuid':vnf
['uuid'], 'external_name<>': None} )
1913 for ext_iface
in ext_ifaces
:
1914 vnf
['ifaces'][ ext_iface
['name'] ] = {'uuid':ext_iface
['iface_uuid'], 'type':ext_iface
['type']}
1916 #1.4 get list of connections
1917 conections
= topo
['topology']['connections']
1918 conections_list
= []
1919 conections_list_name
= []
1920 for k
in conections
.keys():
1921 if type(conections
[k
]['nodes'])==dict: #dict with node:iface pairs
1922 ifaces_list
= conections
[k
]['nodes'].items()
1923 elif type(conections
[k
]['nodes'])==list: #list with dictionary
1925 conection_pair_list
= map(lambda x
: x
.items(), conections
[k
]['nodes'] )
1926 for k2
in conection_pair_list
:
1929 con_type
= conections
[k
].get("type", "link")
1930 if con_type
!= "link":
1932 raise NfvoException("Format error. Reapeted network name at 'topology':'connections':'{}'".format(str(k
)), httperrors
.Bad_Request
)
1933 other_nets
[k
] = {'external': False}
1934 if conections
[k
].get("graph"):
1935 other_nets
[k
]["graph"] = conections
[k
]["graph"]
1936 ifaces_list
.append( (k
, None) )
1939 if con_type
== "external_network":
1940 other_nets
[k
]['external'] = True
1941 if conections
[k
].get("model"):
1942 other_nets
[k
]["model"] = conections
[k
]["model"]
1944 other_nets
[k
]["model"] = k
1945 if con_type
== "dataplane_net" or con_type
== "bridge_net":
1946 other_nets
[k
]["model"] = con_type
1948 conections_list_name
.append(k
)
1949 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)
1950 #print set(ifaces_list)
1951 #check valid VNF and iface names
1952 for iface
in ifaces_list
:
1953 if iface
[0] not in vnfs
and iface
[0] not in other_nets
:
1954 raise NfvoException("format error. Invalid VNF name at 'topology':'connections':'{}':'nodes':'{}'".format(
1955 str(k
), iface
[0]), httperrors
.Not_Found
)
1956 if iface
[0] in vnfs
and iface
[1] not in vnfs
[ iface
[0] ]['ifaces']:
1957 raise NfvoException("format error. Invalid interface name at 'topology':'connections':'{}':'nodes':'{}':'{}'".format(
1958 str(k
), iface
[0], iface
[1]), httperrors
.Not_Found
)
1960 #1.5 unify connections from the pair list to a consolidated list
1962 while index
< len(conections_list
):
1964 while index2
< len(conections_list
):
1965 if len(conections_list
[index
] & conections_list
[index2
])>0: #common interface, join nets
1966 conections_list
[index
] |
= conections_list
[index2
]
1967 del conections_list
[index2
]
1968 del conections_list_name
[index2
]
1971 conections_list
[index
] = list(conections_list
[index
]) # from set to list again
1973 #for k in conections_list:
1978 #1.6 Delete non external nets
1979 # for k in other_nets.keys():
1980 # if other_nets[k]['model']=='bridge' or other_nets[k]['model']=='dataplane_net' or other_nets[k]['model']=='bridge_net':
1981 # for con in conections_list:
1983 # for index in range(0,len(con)):
1984 # if con[index][0] == k: delete_indexes.insert(0,index) #order from higher to lower
1985 # for index in delete_indexes:
1988 #1.7: Check external_ports are present at database table datacenter_nets
1989 for k
,net
in other_nets
.items():
1990 error_pos
= "'topology':'nodes':'" + k
+ "'"
1991 if net
['external']==False:
1992 if 'name' not in net
:
1994 if 'model' not in net
:
1995 raise NfvoException("needed a 'model' at " + error_pos
, httperrors
.Bad_Request
)
1996 if net
['model']=='bridge_net':
1997 net
['type']='bridge';
1998 elif net
['model']=='dataplane_net':
2001 raise NfvoException("unknown 'model' '"+ net
['model'] +"' at " + error_pos
, httperrors
.Not_Found
)
2003 #IF we do not want to check that external network exist at datacenter
2008 # if 'net_id' in net:
2009 # error_text += " 'net_id' " + net['net_id']
2010 # WHERE_['uuid'] = net['net_id']
2011 # if 'model' in net:
2012 # error_text += " 'model' " + net['model']
2013 # WHERE_['name'] = net['model']
2014 # if len(WHERE_) == 0:
2015 # return -httperrors.Bad_Request, "needed a 'net_id' or 'model' at " + error_pos
2016 # r,net_db = mydb.get_table(SELECT=('uuid','name','description','type','shared'),
2017 # FROM='datacenter_nets', WHERE=WHERE_ )
2019 # print "nfvo.new_scenario Error getting datacenter_nets",r,net_db
2021 # print "nfvo.new_scenario Error" +error_text+ " is not present at database"
2022 # return -httperrors.Bad_Request, "unknown " +error_text+ " at " + error_pos
2024 # print "nfvo.new_scenario Error more than one external_network for " +error_text+ " is present at database"
2025 # return -httperrors.Bad_Request, "more than one external_network for " +error_text+ "at "+ error_pos + " Concrete with 'net_id'"
2026 # other_nets[k].update(net_db[0])
2029 net_nb
=0 #Number of nets
2030 for con
in conections_list
:
2031 #check if this is connected to a external net
2035 for index
in range(0,len(con
)):
2036 #check if this is connected to a external net
2037 for net_key
in other_nets
.keys():
2038 if con
[index
][0]==net_key
:
2039 if other_net_index
>=0:
2040 error_text
="There is some interface connected both to net '%s' and net '%s'" % (con
[other_net_index
][0], net_key
)
2041 #print "nfvo.new_scenario " + error_text
2042 raise NfvoException(error_text
, httperrors
.Bad_Request
)
2044 other_net_index
= index
2045 net_target
= net_key
2047 #print "other_net_index", other_net_index
2049 if other_net_index
>=0:
2050 del con
[other_net_index
]
2051 #IF we do not want to check that external network exist at datacenter
2052 if other_nets
[net_target
]['external'] :
2053 if "name" not in other_nets
[net_target
]:
2054 other_nets
[net_target
]['name'] = other_nets
[net_target
]['model']
2055 if other_nets
[net_target
]["type"] == "external_network":
2056 if vnfs
[ con
[0][0] ]['ifaces'][ con
[0][1] ]["type"] == "data":
2057 other_nets
[net_target
]["type"] = "data"
2059 other_nets
[net_target
]["type"] = "bridge"
2061 # if other_nets[net_target]['external'] :
2062 # 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
2063 # if type_=='data' and other_nets[net_target]['type']=="ptp":
2064 # error_text = "Error connecting %d nodes on a not multipoint net %s" % (len(con), net_target)
2065 # print "nfvo.new_scenario " + error_text
2066 # return -httperrors.Bad_Request, error_text
2069 vnfs
[ iface
[0] ]['ifaces'][ iface
[1] ]['net_key'] = net_target
2072 net_type_bridge
=False
2074 net_target
= "__-__net"+str(net_nb
)
2075 net_list
[net_target
] = {'name': conections_list_name
[net_nb
], #"net-"+str(net_nb),
2076 'description':"net-%s in scenario %s" %(net_nb
,topo
['name']),
2079 vnfs
[ iface
[0] ]['ifaces'][ iface
[1] ]['net_key'] = net_target
2080 iface_type
= vnfs
[ iface
[0] ]['ifaces'][ iface
[1] ]['type']
2081 if iface_type
=='mgmt' or iface_type
=='bridge':
2082 net_type_bridge
= True
2084 net_type_data
= True
2085 if net_type_bridge
and net_type_data
:
2086 error_text
= "Error connection interfaces of bridge type with data type. Firs node %s, iface %s" % (iface
[0], iface
[1])
2087 #print "nfvo.new_scenario " + error_text
2088 raise NfvoException(error_text
, httperrors
.Bad_Request
)
2089 elif net_type_bridge
:
2092 type_
='data' if len(con
)>2 else 'ptp'
2093 net_list
[net_target
]['type'] = type_
2096 error_text
= "Error connection node %s : %s does not match any VNF or interface" % (iface
[0], iface
[1])
2097 #print "nfvo.new_scenario " + error_text
2099 raise NfvoException(error_text
, httperrors
.Bad_Request
)
2101 #1.8: Connect to management net all not already connected interfaces of type 'mgmt'
2102 #1.8.1 obtain management net
2103 mgmt_net
= mydb
.get_rows(SELECT
=('uuid','name','description','type','shared'),
2104 FROM
='datacenter_nets', WHERE
={'name':'mgmt'} )
2105 #1.8.2 check all interfaces from all vnfs
2107 add_mgmt_net
= False
2108 for vnf
in vnfs
.values():
2109 for iface
in vnf
['ifaces'].values():
2110 if iface
['type']=='mgmt' and 'net_key' not in iface
:
2111 #iface not connected
2112 iface
['net_key'] = 'mgmt'
2114 if add_mgmt_net
and 'mgmt' not in net_list
:
2115 net_list
['mgmt']=mgmt_net
[0]
2116 net_list
['mgmt']['external']=True
2117 net_list
['mgmt']['graph']={'visible':False}
2119 net_list
.update(other_nets
)
2121 #print 'net_list', net_list
2126 #2: insert scenario. filling tables scenarios,sce_vnfs,sce_interfaces,sce_nets
2127 c
= mydb
.new_scenario( { 'vnfs':vnfs
, 'nets':net_list
,
2128 'tenant_id':tenant_id
, 'name':topo
['name'],
2129 'description':topo
.get('description',topo
['name']),
2130 'public': topo
.get('public', False)
2136 @deprecated("Use new_nsd_v3")
2137 def new_scenario_v02(mydb
, tenant_id
, scenario_dict
, version
):
2138 """ This creates a new scenario for version 0.2 and 0.3"""
2139 scenario
= scenario_dict
["scenario"]
2140 if tenant_id
!= "any":
2141 check_tenant(mydb
, tenant_id
)
2142 if "tenant_id" in scenario
:
2143 if scenario
["tenant_id"] != tenant_id
:
2144 # print "nfvo.new_scenario_v02() tenant '%s' not found" % tenant_id
2145 raise NfvoException("VNF can not have a different tenant owner '{}', must be '{}'".format(
2146 scenario
["tenant_id"], tenant_id
), httperrors
.Unauthorized
)
2150 # 1: Check that VNF are present at database table vnfs and update content into scenario dict
2151 for name
,vnf
in scenario
["vnfs"].iteritems():
2152 where
= {"OR": {"tenant_id": tenant_id
, 'public': "true"}}
2154 error_pos
= "'scenario':'vnfs':'" + name
+ "'"
2156 error_text
+= " 'vnf_id' " + vnf
['vnf_id']
2157 where
['uuid'] = vnf
['vnf_id']
2158 if 'vnf_name' in vnf
:
2159 error_text
+= " 'vnf_name' " + vnf
['vnf_name']
2160 where
['name'] = vnf
['vnf_name']
2162 raise NfvoException("Needed a 'vnf_id' or 'vnf_name' at " + error_pos
, httperrors
.Bad_Request
)
2163 vnf_db
= mydb
.get_rows(SELECT
=('uuid', 'name', 'description'),
2166 if len(vnf_db
) == 0:
2167 raise NfvoException("Unknown" + error_text
+ " at " + error_pos
, httperrors
.Not_Found
)
2168 elif len(vnf_db
) > 1:
2169 raise NfvoException("More than one" + error_text
+ " at " + error_pos
+ " Concrete with 'vnf_id'", httperrors
.Conflict
)
2170 vnf
['uuid'] = vnf_db
[0]['uuid']
2171 vnf
['description'] = vnf_db
[0]['description']
2173 # get external interfaces
2174 ext_ifaces
= mydb
.get_rows(SELECT
=('external_name as name', 'i.uuid as iface_uuid', 'i.type as type'),
2175 FROM
='vnfs join vms on vnfs.uuid=vms.vnf_id join interfaces as i on vms.uuid=i.vm_id',
2176 WHERE
={'vnfs.uuid':vnf
['uuid'], 'external_name<>': None} )
2177 for ext_iface
in ext_ifaces
:
2178 vnf
['ifaces'][ ext_iface
['name'] ] = {'uuid':ext_iface
['iface_uuid'], 'type': ext_iface
['type']}
2179 # TODO? get internal-connections from db.nets and their profiles, and update scenario[vnfs][internal-connections] accordingly
2181 # 2: Insert net_key and ip_address at every vnf interface
2182 for net_name
, net
in scenario
["networks"].items():
2183 net_type_bridge
= False
2184 net_type_data
= False
2185 for iface_dict
in net
["interfaces"]:
2186 if version
== "0.2":
2187 temp_dict
= iface_dict
2189 elif version
== "0.3":
2190 temp_dict
= {iface_dict
["vnf"] : iface_dict
["vnf_interface"]}
2191 ip_address
= iface_dict
.get('ip_address', None)
2192 for vnf
, iface
in temp_dict
.items():
2193 if vnf
not in scenario
["vnfs"]:
2194 error_text
= "Error at 'networks':'{}':'interfaces' VNF '{}' not match any VNF at 'vnfs'".format(
2196 # logger.debug("nfvo.new_scenario_v02 " + error_text)
2197 raise NfvoException(error_text
, httperrors
.Not_Found
)
2198 if iface
not in scenario
["vnfs"][vnf
]['ifaces']:
2199 error_text
= "Error at 'networks':'{}':'interfaces':'{}' interface not match any VNF interface"\
2200 .format(net_name
, iface
)
2201 # logger.debug("nfvo.new_scenario_v02 " + error_text)
2202 raise NfvoException(error_text
, httperrors
.Bad_Request
)
2203 if "net_key" in scenario
["vnfs"][vnf
]['ifaces'][iface
]:
2204 error_text
= "Error at 'networks':'{}':'interfaces':'{}' interface already connected at network"\
2205 "'{}'".format(net_name
, iface
,scenario
["vnfs"][vnf
]['ifaces'][iface
]['net_key'])
2206 # logger.debug("nfvo.new_scenario_v02 " + error_text)
2207 raise NfvoException(error_text
, httperrors
.Bad_Request
)
2208 scenario
["vnfs"][vnf
]['ifaces'][ iface
]['net_key'] = net_name
2209 scenario
["vnfs"][vnf
]['ifaces'][iface
]['ip_address'] = ip_address
2210 iface_type
= scenario
["vnfs"][vnf
]['ifaces'][iface
]['type']
2211 if iface_type
== 'mgmt' or iface_type
== 'bridge':
2212 net_type_bridge
= True
2214 net_type_data
= True
2216 if net_type_bridge
and net_type_data
:
2217 error_text
= "Error connection interfaces of 'bridge' type and 'data' type at 'networks':'{}':'interfaces'"\
2219 # logger.debug("nfvo.new_scenario " + error_text)
2220 raise NfvoException(error_text
, httperrors
.Bad_Request
)
2221 elif net_type_bridge
:
2224 type_
= 'data' if len(net
["interfaces"]) > 2 else 'ptp'
2226 if net
.get("implementation"): # for v0.3
2227 if type_
== "bridge" and net
["implementation"] == "underlay":
2228 error_text
= "Error connecting interfaces of data type to a network declared as 'underlay' at "\
2229 "'network':'{}'".format(net_name
)
2230 # logger.debug(error_text)
2231 raise NfvoException(error_text
, httperrors
.Bad_Request
)
2232 elif type_
!= "bridge" and net
["implementation"] == "overlay":
2233 error_text
= "Error connecting interfaces of data type to a network declared as 'overlay' at "\
2234 "'network':'{}'".format(net_name
)
2235 # logger.debug(error_text)
2236 raise NfvoException(error_text
, httperrors
.Bad_Request
)
2237 net
.pop("implementation")
2238 if "type" in net
and version
== "0.3": # for v0.3
2239 if type_
== "data" and net
["type"] == "e-line":
2240 error_text
= "Error connecting more than 2 interfaces of data type to a network declared as type "\
2241 "'e-line' at 'network':'{}'".format(net_name
)
2242 # logger.debug(error_text)
2243 raise NfvoException(error_text
, httperrors
.Bad_Request
)
2244 elif type_
== "ptp" and net
["type"] == "e-lan":
2248 net
['name'] = net_name
2249 net
['external'] = net
.get('external', False)
2251 # 3: insert at database
2252 scenario
["nets"] = scenario
["networks"]
2253 scenario
['tenant_id'] = tenant_id
2254 scenario_id
= mydb
.new_scenario(scenario
)
2258 def new_nsd_v3(mydb
, tenant_id
, nsd_descriptor
):
2260 Parses an OSM IM nsd_catalog and insert at DB
2263 :param nsd_descriptor:
2264 :return: The list of created NSD ids
2267 mynsd
= nsd_catalog
.nsd()
2269 pybindJSONDecoder
.load_ietf_json(nsd_descriptor
, None, None, obj
=mynsd
)
2270 except Exception as e
:
2271 raise NfvoException("Error. Invalid NS descriptor format: " + str(e
), httperrors
.Bad_Request
)
2275 db_sce_interfaces
= []
2278 db_sce_rsp_hops
= []
2279 db_sce_classifiers
= []
2280 db_sce_classifier_matches
= []
2282 db_ip_profiles_index
= 0
2285 for nsd_yang
in mynsd
.nsd_catalog
.nsd
.itervalues():
2286 nsd
= nsd_yang
.get()
2289 scenario_uuid
= str(uuid4())
2290 uuid_list
.append(scenario_uuid
)
2291 nsd_uuid_list
.append(scenario_uuid
)
2293 "uuid": scenario_uuid
,
2294 "osm_id": get_str(nsd
, "id", 255),
2295 "name": get_str(nsd
, "name", 255),
2296 "description": get_str(nsd
, "description", 255),
2297 "tenant_id": tenant_id
,
2298 "vendor": get_str(nsd
, "vendor", 255),
2299 "short_name": get_str(nsd
, "short-name", 255),
2300 "descriptor": str(nsd_descriptor
)[:60000],
2302 db_scenarios
.append(db_scenario
)
2304 # table sce_vnfs (constituent-vnfd)
2305 vnf_index2scevnf_uuid
= {}
2306 vnf_index2vnf_uuid
= {}
2307 for vnf
in nsd
.get("constituent-vnfd").itervalues():
2308 existing_vnf
= mydb
.get_rows(FROM
="vnfs", WHERE
={'osm_id': str(vnf
["vnfd-id-ref"])[:255],
2309 'tenant_id': tenant_id
})
2310 if not existing_vnf
:
2311 raise NfvoException("Error. Invalid NS descriptor at 'nsd[{}]':'constituent-vnfd':'vnfd-id-ref':"
2312 "'{}'. Reference to a non-existing VNFD in the catalog".format(
2313 str(nsd
["id"]), str(vnf
["vnfd-id-ref"])[:255]),
2314 httperrors
.Bad_Request
)
2315 sce_vnf_uuid
= str(uuid4())
2316 uuid_list
.append(sce_vnf_uuid
)
2318 "uuid": sce_vnf_uuid
,
2319 "scenario_id": scenario_uuid
,
2320 # "name": get_str(vnf, "member-vnf-index", 255),
2321 "name": existing_vnf
[0]["name"][:200] + "." + get_str(vnf
, "member-vnf-index", 50),
2322 "vnf_id": existing_vnf
[0]["uuid"],
2323 "member_vnf_index": str(vnf
["member-vnf-index"]),
2324 # TODO 'start-by-default': True
2326 vnf_index2scevnf_uuid
[str(vnf
['member-vnf-index'])] = sce_vnf_uuid
2327 vnf_index2vnf_uuid
[str(vnf
['member-vnf-index'])] = existing_vnf
[0]["uuid"]
2328 db_sce_vnfs
.append(db_sce_vnf
)
2330 # table ip_profiles (ip-profiles)
2331 ip_profile_name2db_table_index
= {}
2332 for ip_profile
in nsd
.get("ip-profiles").itervalues():
2334 "ip_version": str(ip_profile
["ip-profile-params"].get("ip-version", "ipv4")),
2335 "subnet_address": str(ip_profile
["ip-profile-params"].get("subnet-address")),
2336 "gateway_address": str(ip_profile
["ip-profile-params"].get("gateway-address")),
2337 "dhcp_enabled": str(ip_profile
["ip-profile-params"]["dhcp-params"].get("enabled", True)),
2338 "dhcp_start_address": str(ip_profile
["ip-profile-params"]["dhcp-params"].get("start-address")),
2339 "dhcp_count": str(ip_profile
["ip-profile-params"]["dhcp-params"].get("count")),
2342 for dns
in ip_profile
["ip-profile-params"]["dns-server"].itervalues():
2343 dns_list
.append(str(dns
.get("address")))
2344 db_ip_profile
["dns_address"] = ";".join(dns_list
)
2345 if ip_profile
["ip-profile-params"].get('security-group'):
2346 db_ip_profile
["security_group"] = ip_profile
["ip-profile-params"]['security-group']
2347 ip_profile_name2db_table_index
[str(ip_profile
["name"])] = db_ip_profiles_index
2348 db_ip_profiles_index
+= 1
2349 db_ip_profiles
.append(db_ip_profile
)
2351 # table sce_nets (internal-vld)
2352 for vld
in nsd
.get("vld").itervalues():
2353 sce_net_uuid
= str(uuid4())
2354 uuid_list
.append(sce_net_uuid
)
2356 "uuid": sce_net_uuid
,
2357 "name": get_str(vld
, "name", 255),
2358 "scenario_id": scenario_uuid
,
2360 "multipoint": not vld
.get("type") == "ELINE",
2361 "osm_id": get_str(vld
, "id", 255),
2363 "description": get_str(vld
, "description", 255),
2365 # guess type of network
2366 if vld
.get("mgmt-network"):
2367 db_sce_net
["type"] = "bridge"
2368 db_sce_net
["external"] = True
2369 elif vld
.get("provider-network").get("overlay-type") == "VLAN":
2370 db_sce_net
["type"] = "data"
2372 # later on it will be fixed to bridge or data depending on the type of interfaces attached to it
2373 db_sce_net
["type"] = None
2374 db_sce_nets
.append(db_sce_net
)
2376 # ip-profile, link db_ip_profile with db_sce_net
2377 if vld
.get("ip-profile-ref"):
2378 ip_profile_name
= vld
.get("ip-profile-ref")
2379 if ip_profile_name
not in ip_profile_name2db_table_index
:
2380 raise NfvoException("Error. Invalid NS descriptor at 'nsd[{}]':'vld[{}]':'ip-profile-ref':'{}'."
2381 " Reference to a non-existing 'ip_profiles'".format(
2382 str(nsd
["id"]), str(vld
["id"]), str(vld
["ip-profile-ref"])),
2383 httperrors
.Bad_Request
)
2384 db_ip_profiles
[ip_profile_name2db_table_index
[ip_profile_name
]]["sce_net_id"] = sce_net_uuid
2385 elif vld
.get("vim-network-name"):
2386 db_sce_net
["vim_network_name"] = get_str(vld
, "vim-network-name", 255)
2388 # table sce_interfaces (vld:vnfd-connection-point-ref)
2389 for iface
in vld
.get("vnfd-connection-point-ref").itervalues():
2390 vnf_index
= str(iface
['member-vnf-index-ref'])
2391 # check correct parameters
2392 if vnf_index
not in vnf_index2vnf_uuid
:
2393 raise NfvoException("Error. Invalid NS descriptor at 'nsd[{}]':'vld[{}]':'vnfd-connection-point"
2394 "-ref':'member-vnf-index-ref':'{}'. Reference to a non-existing index at "
2395 "'nsd':'constituent-vnfd'".format(
2396 str(nsd
["id"]), str(vld
["id"]), str(iface
["member-vnf-index-ref"])),
2397 httperrors
.Bad_Request
)
2399 existing_ifaces
= mydb
.get_rows(SELECT
=('i.uuid as uuid', 'i.type as iface_type'),
2400 FROM
="interfaces as i join vms on i.vm_id=vms.uuid",
2401 WHERE
={'vnf_id': vnf_index2vnf_uuid
[vnf_index
],
2402 'external_name': get_str(iface
, "vnfd-connection-point-ref",
2404 if not existing_ifaces
:
2405 raise NfvoException("Error. Invalid NS descriptor at 'nsd[{}]':'vld[{}]':'vnfd-connection-point"
2406 "-ref':'vnfd-connection-point-ref':'{}'. Reference to a non-existing "
2407 "connection-point name at VNFD '{}'".format(
2408 str(nsd
["id"]), str(vld
["id"]), str(iface
["vnfd-connection-point-ref"]),
2409 str(iface
.get("vnfd-id-ref"))[:255]),
2410 httperrors
.Bad_Request
)
2411 interface_uuid
= existing_ifaces
[0]["uuid"]
2412 if existing_ifaces
[0]["iface_type"] == "data" and not db_sce_net
["type"]:
2413 db_sce_net
["type"] = "data"
2414 sce_interface_uuid
= str(uuid4())
2415 uuid_list
.append(sce_net_uuid
)
2416 iface_ip_address
= None
2417 if iface
.get("ip-address"):
2418 iface_ip_address
= str(iface
.get("ip-address"))
2419 db_sce_interface
= {
2420 "uuid": sce_interface_uuid
,
2421 "sce_vnf_id": vnf_index2scevnf_uuid
[vnf_index
],
2422 "sce_net_id": sce_net_uuid
,
2423 "interface_id": interface_uuid
,
2424 "ip_address": iface_ip_address
,
2426 db_sce_interfaces
.append(db_sce_interface
)
2427 if not db_sce_net
["type"]:
2428 db_sce_net
["type"] = "bridge"
2430 # table sce_vnffgs (vnffgd)
2431 for vnffg
in nsd
.get("vnffgd").itervalues():
2432 sce_vnffg_uuid
= str(uuid4())
2433 uuid_list
.append(sce_vnffg_uuid
)
2435 "uuid": sce_vnffg_uuid
,
2436 "name": get_str(vnffg
, "name", 255),
2437 "scenario_id": scenario_uuid
,
2438 "vendor": get_str(vnffg
, "vendor", 255),
2439 "description": get_str(vld
, "description", 255),
2441 db_sce_vnffgs
.append(db_sce_vnffg
)
2445 for rsp
in vnffg
.get("rsp").itervalues():
2446 sce_rsp_uuid
= str(uuid4())
2447 uuid_list
.append(sce_rsp_uuid
)
2449 "uuid": sce_rsp_uuid
,
2450 "name": get_str(rsp
, "name", 255),
2451 "sce_vnffg_id": sce_vnffg_uuid
,
2452 "id": get_str(rsp
, "id", 255), # only useful to link with classifiers; will be removed later in the code
2454 db_sce_rsps
.append(db_sce_rsp
)
2455 db_sce_rsp_hops
= []
2456 for iface
in rsp
.get("vnfd-connection-point-ref").itervalues():
2457 vnf_index
= str(iface
['member-vnf-index-ref'])
2458 if_order
= int(iface
['order'])
2459 # check correct parameters
2460 if vnf_index
not in vnf_index2vnf_uuid
:
2461 raise NfvoException("Error. Invalid NS descriptor at 'nsd[{}]':'rsp[{}]':'vnfd-connection-point"
2462 "-ref':'member-vnf-index-ref':'{}'. Reference to a non-existing index at "
2463 "'nsd':'constituent-vnfd'".format(
2464 str(nsd
["id"]), str(rsp
["id"]), str(iface
["member-vnf-index-ref"])),
2465 httperrors
.Bad_Request
)
2467 ingress_existing_ifaces
= mydb
.get_rows(SELECT
=('i.uuid as uuid',),
2468 FROM
="interfaces as i join vms on i.vm_id=vms.uuid",
2470 'vnf_id': vnf_index2vnf_uuid
[vnf_index
],
2471 'external_name': get_str(iface
, "vnfd-ingress-connection-point-ref",
2473 if not ingress_existing_ifaces
:
2474 raise NfvoException("Error. Invalid NS descriptor at 'nsd[{}]':'rsp[{}]':'vnfd-connection-point"
2475 "-ref':'vnfd-ingress-connection-point-ref':'{}'. Reference to a non-existing "
2476 "connection-point name at VNFD '{}'".format(
2477 str(nsd
["id"]), str(rsp
["id"]), str(iface
["vnfd-ingress-connection-point-ref"]),
2478 str(iface
.get("vnfd-id-ref"))[:255]), httperrors
.Bad_Request
)
2480 egress_existing_ifaces
= mydb
.get_rows(SELECT
=('i.uuid as uuid',),
2481 FROM
="interfaces as i join vms on i.vm_id=vms.uuid",
2483 'vnf_id': vnf_index2vnf_uuid
[vnf_index
],
2484 'external_name': get_str(iface
, "vnfd-egress-connection-point-ref",
2486 if not egress_existing_ifaces
:
2487 raise NfvoException("Error. Invalid NS descriptor at 'nsd[{}]':'rsp[{}]':'vnfd-connection-point"
2488 "-ref':'vnfd-egress-connection-point-ref':'{}'. Reference to a non-existing "
2489 "connection-point name at VNFD '{}'".format(
2490 str(nsd
["id"]), str(rsp
["id"]), str(iface
["vnfd-egress-connection-point-ref"]),
2491 str(iface
.get("vnfd-id-ref"))[:255]), HTTP_Bad_Request
)
2493 ingress_interface_uuid
= ingress_existing_ifaces
[0]["uuid"]
2494 egress_interface_uuid
= egress_existing_ifaces
[0]["uuid"]
2495 sce_rsp_hop_uuid
= str(uuid4())
2496 uuid_list
.append(sce_rsp_hop_uuid
)
2498 "uuid": sce_rsp_hop_uuid
,
2499 "if_order": if_order
,
2500 "ingress_interface_id": ingress_interface_uuid
,
2501 "egress_interface_id": egress_interface_uuid
,
2502 "sce_vnf_id": vnf_index2scevnf_uuid
[vnf_index
],
2503 "sce_rsp_id": sce_rsp_uuid
,
2505 db_sce_rsp_hops
.append(db_sce_rsp_hop
)
2507 # deal with classifiers
2508 db_sce_classifiers
= []
2509 for classifier
in vnffg
.get("classifier").itervalues():
2510 sce_classifier_uuid
= str(uuid4())
2511 uuid_list
.append(sce_classifier_uuid
)
2514 vnf_index
= str(classifier
['member-vnf-index-ref'])
2515 if vnf_index
not in vnf_index2vnf_uuid
:
2516 raise NfvoException("Error. Invalid NS descriptor at 'nsd[{}]':'classifier[{}]':'vnfd-connection-point"
2517 "-ref':'member-vnf-index-ref':'{}'. Reference to a non-existing index at "
2518 "'nsd':'constituent-vnfd'".format(
2519 str(nsd
["id"]), str(classifier
["id"]), str(classifier
["member-vnf-index-ref"])),
2520 httperrors
.Bad_Request
)
2521 existing_ifaces
= mydb
.get_rows(SELECT
=('i.uuid as uuid',),
2522 FROM
="interfaces as i join vms on i.vm_id=vms.uuid",
2523 WHERE
={'vnf_id': vnf_index2vnf_uuid
[vnf_index
],
2524 'external_name': get_str(classifier
, "vnfd-connection-point-ref",
2526 if not existing_ifaces
:
2527 raise NfvoException("Error. Invalid NS descriptor at 'nsd[{}]':'rsp[{}]':'vnfd-connection-point"
2528 "-ref':'vnfd-connection-point-ref':'{}'. Reference to a non-existing "
2529 "connection-point name at VNFD '{}'".format(
2530 str(nsd
["id"]), str(rsp
["id"]), str(iface
["vnfd-connection-point-ref"]),
2531 str(iface
.get("vnfd-id-ref"))[:255]),
2532 httperrors
.Bad_Request
)
2533 interface_uuid
= existing_ifaces
[0]["uuid"]
2535 db_sce_classifier
= {
2536 "uuid": sce_classifier_uuid
,
2537 "name": get_str(classifier
, "name", 255),
2538 "sce_vnffg_id": sce_vnffg_uuid
,
2539 "sce_vnf_id": vnf_index2scevnf_uuid
[vnf_index
],
2540 "interface_id": interface_uuid
,
2542 rsp_id
= get_str(classifier
, "rsp-id-ref", 255)
2543 rsp
= next((item
for item
in db_sce_rsps
if item
["id"] == rsp_id
), None)
2544 db_sce_classifier
["sce_rsp_id"] = rsp
["uuid"]
2545 db_sce_classifiers
.append(db_sce_classifier
)
2547 db_sce_classifier_matches
= []
2548 for match
in classifier
.get("match-attributes").itervalues():
2549 sce_classifier_match_uuid
= str(uuid4())
2550 uuid_list
.append(sce_classifier_match_uuid
)
2551 db_sce_classifier_match
= {
2552 "uuid": sce_classifier_match_uuid
,
2553 "ip_proto": get_str(match
, "ip-proto", 2),
2554 "source_ip": get_str(match
, "source-ip-address", 16),
2555 "destination_ip": get_str(match
, "destination-ip-address", 16),
2556 "source_port": get_str(match
, "source-port", 5),
2557 "destination_port": get_str(match
, "destination-port", 5),
2558 "sce_classifier_id": sce_classifier_uuid
,
2560 db_sce_classifier_matches
.append(db_sce_classifier_match
)
2563 # remove unneeded id's in sce_rsps
2564 for rsp
in db_sce_rsps
:
2568 {"scenarios": db_scenarios
},
2569 {"sce_nets": db_sce_nets
},
2570 {"ip_profiles": db_ip_profiles
},
2571 {"sce_vnfs": db_sce_vnfs
},
2572 {"sce_interfaces": db_sce_interfaces
},
2573 {"sce_vnffgs": db_sce_vnffgs
},
2574 {"sce_rsps": db_sce_rsps
},
2575 {"sce_rsp_hops": db_sce_rsp_hops
},
2576 {"sce_classifiers": db_sce_classifiers
},
2577 {"sce_classifier_matches": db_sce_classifier_matches
},
2580 logger
.debug("new_nsd_v3 done: %s",
2581 yaml
.safe_dump(db_tables
, indent
=4, default_flow_style
=False) )
2582 mydb
.new_rows(db_tables
, uuid_list
)
2583 return nsd_uuid_list
2584 except NfvoException
:
2586 except Exception as e
:
2587 logger
.error("Exception {}".format(e
))
2588 raise # NfvoException("Exception {}".format(e), httperrors.Bad_Request)
2591 def edit_scenario(mydb
, tenant_id
, scenario_id
, data
):
2592 data
["uuid"] = scenario_id
2593 data
["tenant_id"] = tenant_id
2594 c
= mydb
.edit_scenario( data
)
2598 @deprecated("Use create_instance")
2599 def start_scenario(mydb
, tenant_id
, scenario_id
, instance_scenario_name
, instance_scenario_description
, datacenter
=None,vim_tenant
=None, startvms
=True):
2600 #print "Checking that nfvo_tenant_id exists and getting the VIM URI and the VIM tenant_id"
2601 datacenter_id
, myvim
= get_datacenter_by_name_uuid(mydb
, tenant_id
, datacenter
, vim_tenant
=vim_tenant
)
2602 vims
= {datacenter_id
: myvim
}
2603 myvim_tenant
= myvim
['tenant_id']
2604 datacenter_name
= myvim
['name']
2608 #print "Checking that the scenario_id exists and getting the scenario dictionary"
2609 scenarioDict
= mydb
.get_scenario(scenario_id
, tenant_id
, datacenter_id
=datacenter_id
)
2610 scenarioDict
['datacenter2tenant'] = { datacenter_id
: myvim
['config']['datacenter_tenant_id'] }
2611 scenarioDict
['datacenter_id'] = datacenter_id
2612 #print '================scenarioDict======================='
2613 #print json.dumps(scenarioDict, indent=4)
2614 #print 'BEGIN launching instance scenario "%s" based on "%s"' % (instance_scenario_name,scenarioDict['name'])
2616 logger
.debug("start_scenario Scenario %s: consisting of %d VNF(s)", scenarioDict
['name'],len(scenarioDict
['vnfs']))
2617 #print yaml.safe_dump(scenarioDict, indent=4, default_flow_style=False)
2619 auxNetDict
= {} #Auxiliar dictionary. First key:'scenario' or sce_vnf uuid. Second Key: uuid of the net/sce_net. Value: vim_net_id
2620 auxNetDict
['scenario'] = {}
2622 logger
.debug("start_scenario 1. Creating new nets (sce_nets) in the VIM")
2623 for sce_net
in scenarioDict
['nets']:
2624 #print "Net name: %s. Description: %s" % (sce_net["name"], sce_net["description"])
2626 myNetName
= "%s.%s" % (instance_scenario_name
, sce_net
['name'])
2627 myNetName
= myNetName
[0:255] #limit length
2628 myNetType
= sce_net
['type']
2630 myNetDict
["name"] = myNetName
2631 myNetDict
["type"] = myNetType
2632 myNetDict
["tenant_id"] = myvim_tenant
2633 myNetIPProfile
= sce_net
.get('ip_profile', None)
2635 #We should use the dictionary as input parameter for new_network
2637 if not sce_net
["external"]:
2638 network_id
= myvim
.new_network(myNetName
, myNetType
, myNetIPProfile
)
2639 #print "New VIM network created for scenario %s. Network id: %s" % (scenarioDict['name'],network_id)
2640 sce_net
['vim_id'] = network_id
2641 auxNetDict
['scenario'][sce_net
['uuid']] = network_id
2642 rollbackList
.append({'what':'network','where':'vim','vim_id':datacenter_id
,'uuid':network_id
})
2643 sce_net
["created"] = True
2645 if sce_net
['vim_id'] == None:
2646 error_text
= "Error, datacenter '%s' does not have external network '%s'." % (datacenter_name
, sce_net
['name'])
2647 _
, message
= rollback(mydb
, vims
, rollbackList
)
2648 logger
.error("nfvo.start_scenario: %s", error_text
)
2649 raise NfvoException(error_text
, httperrors
.Bad_Request
)
2650 logger
.debug("Using existent VIM network for scenario %s. Network id %s", scenarioDict
['name'],sce_net
['vim_id'])
2651 auxNetDict
['scenario'][sce_net
['uuid']] = sce_net
['vim_id']
2653 logger
.debug("start_scenario 2. Creating new nets (vnf internal nets) in the VIM")
2654 #For each vnf net, we create it and we add it to instanceNetlist.
2656 for sce_vnf
in scenarioDict
['vnfs']:
2657 for net
in sce_vnf
['nets']:
2658 #print "Net name: %s. Description: %s" % (net["name"], net["description"])
2660 myNetName
= "%s.%s" % (instance_scenario_name
,net
['name'])
2661 myNetName
= myNetName
[0:255] #limit length
2662 myNetType
= net
['type']
2664 myNetDict
["name"] = myNetName
2665 myNetDict
["type"] = myNetType
2666 myNetDict
["tenant_id"] = myvim_tenant
2667 myNetIPProfile
= net
.get('ip_profile', None)
2670 #We should use the dictionary as input parameter for new_network
2671 network_id
= myvim
.new_network(myNetName
, myNetType
, myNetIPProfile
)
2672 #print "VIM network id for scenario %s: %s" % (scenarioDict['name'],network_id)
2673 net
['vim_id'] = network_id
2674 if sce_vnf
['uuid'] not in auxNetDict
:
2675 auxNetDict
[sce_vnf
['uuid']] = {}
2676 auxNetDict
[sce_vnf
['uuid']][net
['uuid']] = network_id
2677 rollbackList
.append({'what':'network','where':'vim','vim_id':datacenter_id
,'uuid':network_id
})
2678 net
["created"] = True
2680 #print "auxNetDict:"
2681 #print yaml.safe_dump(auxNetDict, indent=4, default_flow_style=False)
2683 logger
.debug("start_scenario 3. Creating new vm instances in the VIM")
2684 #myvim.new_vminstance(self,vimURI,tenant_id,name,description,image_id,flavor_id,net_dict)
2686 for sce_vnf
in scenarioDict
['vnfs']:
2687 vnf_availability_zones
= []
2688 for vm
in sce_vnf
['vms']:
2689 vm_av
= vm
.get('availability_zone')
2690 if vm_av
and vm_av
not in vnf_availability_zones
:
2691 vnf_availability_zones
.append(vm_av
)
2693 # check if there is enough availability zones available at vim level.
2694 if myvims
[datacenter_id
].availability_zone
and vnf_availability_zones
:
2695 if len(vnf_availability_zones
) > len(myvims
[datacenter_id
].availability_zone
):
2696 raise NfvoException('No enough availability zones at VIM for this deployment', httperrors
.Bad_Request
)
2698 for vm
in sce_vnf
['vms']:
2701 #myVMDict['name'] = "%s-%s-%s" % (scenarioDict['name'],sce_vnf['name'], vm['name'])
2702 myVMDict
['name'] = "{}.{}.{}".format(instance_scenario_name
,sce_vnf
['name'],chr(96+i
))
2703 #myVMDict['description'] = vm['description']
2704 myVMDict
['description'] = myVMDict
['name'][0:99]
2706 myVMDict
['start'] = "no"
2707 myVMDict
['name'] = myVMDict
['name'][0:255] #limit name length
2708 #print "VM name: %s. Description: %s" % (myVMDict['name'], myVMDict['name'])
2710 #create image at vim in case it not exist
2711 image_dict
= mydb
.get_table_by_uuid_name("images", vm
['image_id'])
2712 image_id
= create_or_use_image(mydb
, vims
, image_dict
, [], True)
2713 vm
['vim_image_id'] = image_id
2715 #create flavor at vim in case it not exist
2716 flavor_dict
= mydb
.get_table_by_uuid_name("flavors", vm
['flavor_id'])
2717 if flavor_dict
['extended']!=None:
2718 flavor_dict
['extended']= yaml
.load(flavor_dict
['extended'])
2719 flavor_id
= create_or_use_flavor(mydb
, vims
, flavor_dict
, [], True)
2720 vm
['vim_flavor_id'] = flavor_id
2723 myVMDict
['imageRef'] = vm
['vim_image_id']
2724 myVMDict
['flavorRef'] = vm
['vim_flavor_id']
2725 myVMDict
['networks'] = []
2726 for iface
in vm
['interfaces']:
2728 if iface
['type']=="data":
2729 netDict
['type'] = iface
['model']
2730 elif "model" in iface
and iface
["model"]!=None:
2731 netDict
['model']=iface
['model']
2732 #TODO in future, remove this because mac_address will not be set, and the type of PV,VF is obtained from iterface table model
2733 #discover type of interface looking at flavor
2734 for numa
in flavor_dict
.get('extended',{}).get('numas',[]):
2735 for flavor_iface
in numa
.get('interfaces',[]):
2736 if flavor_iface
.get('name') == iface
['internal_name']:
2737 if flavor_iface
['dedicated'] == 'yes':
2738 netDict
['type']="PF" #passthrough
2739 elif flavor_iface
['dedicated'] == 'no':
2740 netDict
['type']="VF" #siov
2741 elif flavor_iface
['dedicated'] == 'yes:sriov':
2742 netDict
['type']="VFnotShared" #sriov but only one sriov on the PF
2743 netDict
["mac_address"] = flavor_iface
.get("mac_address")
2745 netDict
["use"]=iface
['type']
2746 if netDict
["use"]=="data" and not netDict
.get("type"):
2747 #print "netDict", netDict
2748 #print "iface", iface
2749 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'])
2750 if flavor_dict
.get('extended')==None:
2751 raise NfvoException(e_text
+ "After database migration some information is not available. \
2752 Try to delete and create the scenarios and VNFs again", httperrors
.Conflict
)
2754 raise NfvoException(e_text
, httperrors
.Internal_Server_Error
)
2755 if netDict
["use"]=="mgmt" or netDict
["use"]=="bridge":
2756 netDict
["type"]="virtual"
2757 if "vpci" in iface
and iface
["vpci"] is not None:
2758 netDict
['vpci'] = iface
['vpci']
2759 if "mac" in iface
and iface
["mac"] is not None:
2760 netDict
['mac_address'] = iface
['mac']
2761 if "port-security" in iface
and iface
["port-security"] is not None:
2762 netDict
['port_security'] = iface
['port-security']
2763 if "floating-ip" in iface
and iface
["floating-ip"] is not None:
2764 netDict
['floating_ip'] = iface
['floating-ip']
2765 netDict
['name'] = iface
['internal_name']
2766 if iface
['net_id'] is None:
2767 for vnf_iface
in sce_vnf
["interfaces"]:
2770 if vnf_iface
['interface_id']==iface
['uuid']:
2771 netDict
['net_id'] = auxNetDict
['scenario'][ vnf_iface
['sce_net_id'] ]
2774 netDict
['net_id'] = auxNetDict
[ sce_vnf
['uuid'] ][ iface
['net_id'] ]
2775 #skip bridge ifaces not connected to any net
2776 #if 'net_id' not in netDict or netDict['net_id']==None:
2778 myVMDict
['networks'].append(netDict
)
2779 #print ">>>>>>>>>>>>>>>>>>>>>>>>>>>"
2780 #print myVMDict['name']
2781 #print "networks", yaml.safe_dump(myVMDict['networks'], indent=4, default_flow_style=False)
2782 #print "interfaces", yaml.safe_dump(vm['interfaces'], indent=4, default_flow_style=False)
2783 #print ">>>>>>>>>>>>>>>>>>>>>>>>>>>"
2785 if 'availability_zone' in myVMDict
:
2786 av_index
= vnf_availability_zones
.index(myVMDict
['availability_zone'])
2790 vm_id
, _
= myvim
.new_vminstance(myVMDict
['name'], myVMDict
['description'], myVMDict
.get('start', None),
2791 myVMDict
['imageRef'], myVMDict
['flavorRef'], myVMDict
['networks'],
2792 availability_zone_index
=av_index
,
2793 availability_zone_list
=vnf_availability_zones
)
2794 #print "VIM vm instance id (server id) for scenario %s: %s" % (scenarioDict['name'],vm_id)
2795 vm
['vim_id'] = vm_id
2796 rollbackList
.append({'what':'vm','where':'vim','vim_id':datacenter_id
,'uuid':vm_id
})
2797 #put interface uuid back to scenario[vnfs][vms[[interfaces]
2798 for net
in myVMDict
['networks']:
2800 for iface
in vm
['interfaces']:
2801 if net
["name"]==iface
["internal_name"]:
2802 iface
["vim_id"]=net
["vim_id"]
2805 logger
.debug("start scenario Deployment done")
2806 #print yaml.safe_dump(scenarioDict, indent=4, default_flow_style=False)
2807 #r,c = mydb.new_instance_scenario_as_a_whole(nfvo_tenant,scenarioDict['name'],scenarioDict)
2808 instance_id
= mydb
.new_instance_scenario_as_a_whole(tenant_id
,instance_scenario_name
, instance_scenario_description
, scenarioDict
)
2809 return mydb
.get_instance_scenario(instance_id
)
2811 except (db_base_Exception
, vimconn
.vimconnException
) as e
:
2812 _
, message
= rollback(mydb
, vims
, rollbackList
)
2813 if isinstance(e
, db_base_Exception
):
2814 error_text
= "Exception at database"
2816 error_text
= "Exception at VIM"
2817 error_text
+= " {} {}. {}".format(type(e
).__name
__, str(e
), message
)
2818 #logger.error("start_scenario %s", error_text)
2819 raise NfvoException(error_text
, e
.http_code
)
2821 def unify_cloud_config(cloud_config_preserve
, cloud_config
):
2822 """ join the cloud config information into cloud_config_preserve.
2823 In case of conflict cloud_config_preserve preserves
2826 if not cloud_config_preserve
and not cloud_config
:
2829 new_cloud_config
= {"key-pairs":[], "users":[]}
2831 if cloud_config_preserve
:
2832 for key
in cloud_config_preserve
.get("key-pairs", () ):
2833 if key
not in new_cloud_config
["key-pairs"]:
2834 new_cloud_config
["key-pairs"].append(key
)
2836 for key
in cloud_config
.get("key-pairs", () ):
2837 if key
not in new_cloud_config
["key-pairs"]:
2838 new_cloud_config
["key-pairs"].append(key
)
2839 if not new_cloud_config
["key-pairs"]:
2840 del new_cloud_config
["key-pairs"]
2844 new_cloud_config
["users"] += cloud_config
.get("users", () )
2845 if cloud_config_preserve
:
2846 new_cloud_config
["users"] += cloud_config_preserve
.get("users", () )
2847 index_to_delete
= []
2848 users
= new_cloud_config
.get("users", [])
2849 for index0
in range(0,len(users
)):
2850 if index0
in index_to_delete
:
2852 for index1
in range(index0
+1,len(users
)):
2853 if index1
in index_to_delete
:
2855 if users
[index0
]["name"] == users
[index1
]["name"]:
2856 index_to_delete
.append(index1
)
2857 for key
in users
[index1
].get("key-pairs",()):
2858 if "key-pairs" not in users
[index0
]:
2859 users
[index0
]["key-pairs"] = [key
]
2860 elif key
not in users
[index0
]["key-pairs"]:
2861 users
[index0
]["key-pairs"].append(key
)
2862 index_to_delete
.sort(reverse
=True)
2863 for index
in index_to_delete
:
2865 if not new_cloud_config
["users"]:
2866 del new_cloud_config
["users"]
2869 if cloud_config
and cloud_config
.get("boot-data-drive") != None:
2870 new_cloud_config
["boot-data-drive"] = cloud_config
["boot-data-drive"]
2871 if cloud_config_preserve
and cloud_config_preserve
.get("boot-data-drive") != None:
2872 new_cloud_config
["boot-data-drive"] = cloud_config_preserve
["boot-data-drive"]
2875 new_cloud_config
["user-data"] = []
2876 if cloud_config
and cloud_config
.get("user-data"):
2877 if isinstance(cloud_config
["user-data"], list):
2878 new_cloud_config
["user-data"] += cloud_config
["user-data"]
2880 new_cloud_config
["user-data"].append(cloud_config
["user-data"])
2881 if cloud_config_preserve
and cloud_config_preserve
.get("user-data"):
2882 if isinstance(cloud_config_preserve
["user-data"], list):
2883 new_cloud_config
["user-data"] += cloud_config_preserve
["user-data"]
2885 new_cloud_config
["user-data"].append(cloud_config_preserve
["user-data"])
2886 if not new_cloud_config
["user-data"]:
2887 del new_cloud_config
["user-data"]
2890 new_cloud_config
["config-files"] = []
2891 if cloud_config
and cloud_config
.get("config-files") != None:
2892 new_cloud_config
["config-files"] += cloud_config
["config-files"]
2893 if cloud_config_preserve
:
2894 for file in cloud_config_preserve
.get("config-files", ()):
2895 for index
in range(0, len(new_cloud_config
["config-files"])):
2896 if new_cloud_config
["config-files"][index
]["dest"] == file["dest"]:
2897 new_cloud_config
["config-files"][index
] = file
2900 new_cloud_config
["config-files"].append(file)
2901 if not new_cloud_config
["config-files"]:
2902 del new_cloud_config
["config-files"]
2903 return new_cloud_config
2906 def get_vim_thread(mydb
, tenant_id
, datacenter_id_name
=None, datacenter_tenant_id
=None):
2907 datacenter_id
= None
2908 datacenter_name
= None
2911 if datacenter_tenant_id
:
2912 thread_id
= datacenter_tenant_id
2913 thread
= vim_threads
["running"].get(datacenter_tenant_id
)
2915 where_
={"td.nfvo_tenant_id": tenant_id
}
2916 if datacenter_id_name
:
2917 if utils
.check_valid_uuid(datacenter_id_name
):
2918 datacenter_id
= datacenter_id_name
2919 where_
["dt.datacenter_id"] = datacenter_id
2921 datacenter_name
= datacenter_id_name
2922 where_
["d.name"] = datacenter_name
2923 if datacenter_tenant_id
:
2924 where_
["dt.uuid"] = datacenter_tenant_id
2925 datacenters
= mydb
.get_rows(
2926 SELECT
=("dt.uuid as datacenter_tenant_id",),
2927 FROM
="datacenter_tenants as dt join tenants_datacenters as td on dt.uuid=td.datacenter_tenant_id "
2928 "join datacenters as d on d.uuid=dt.datacenter_id",
2930 if len(datacenters
) > 1:
2931 raise NfvoException("More than one datacenters found, try to identify with uuid", httperrors
.Conflict
)
2933 thread_id
= datacenters
[0]["datacenter_tenant_id"]
2934 thread
= vim_threads
["running"].get(thread_id
)
2936 raise NfvoException("datacenter '{}' not found".format(str(datacenter_id_name
)), httperrors
.Not_Found
)
2937 return thread_id
, thread
2938 except db_base_Exception
as e
:
2939 raise NfvoException("{} {}".format(type(e
).__name
__ , str(e
)), e
.http_code
)
2942 def get_datacenter_uuid(mydb
, tenant_id
, datacenter_id_name
):
2944 if utils
.check_valid_uuid(datacenter_id_name
):
2945 WHERE_dict
['d.uuid'] = datacenter_id_name
2947 WHERE_dict
['d.name'] = datacenter_id_name
2950 WHERE_dict
['nfvo_tenant_id'] = tenant_id
2951 from_
= "tenants_datacenters as td join datacenters as d on td.datacenter_id=d.uuid join datacenter_tenants as" \
2952 " dt on td.datacenter_tenant_id=dt.uuid"
2954 from_
= 'datacenters as d'
2955 vimaccounts
= mydb
.get_rows(FROM
=from_
, SELECT
=("d.uuid as uuid, d.name as name",), WHERE
=WHERE_dict
)
2956 if len(vimaccounts
) == 0:
2957 raise NfvoException("datacenter '{}' not found".format(str(datacenter_id_name
)), httperrors
.Not_Found
)
2958 elif len(vimaccounts
)>1:
2959 #print "nfvo.datacenter_action() error. Several datacenters found"
2960 raise NfvoException("More than one datacenters found, try to identify with uuid", httperrors
.Conflict
)
2961 return vimaccounts
[0]["uuid"], vimaccounts
[0]["name"]
2964 def get_datacenter_by_name_uuid(mydb
, tenant_id
, datacenter_id_name
=None, **extra_filter
):
2965 datacenter_id
= None
2966 datacenter_name
= None
2967 if datacenter_id_name
:
2968 if utils
.check_valid_uuid(datacenter_id_name
):
2969 datacenter_id
= datacenter_id_name
2971 datacenter_name
= datacenter_id_name
2972 vims
= get_vim(mydb
, tenant_id
, datacenter_id
, datacenter_name
, **extra_filter
)
2974 raise NfvoException("datacenter '{}' not found".format(str(datacenter_id_name
)), httperrors
.Not_Found
)
2976 #print "nfvo.datacenter_action() error. Several datacenters found"
2977 raise NfvoException("More than one datacenters found, try to identify with uuid", httperrors
.Conflict
)
2978 return vims
.keys()[0], vims
.values()[0]
2982 """Takes dict d and updates it with the values in dict u.
2983 It merges all depth levels"""
2984 for k
, v
in u
.iteritems():
2985 if isinstance(v
, collections
.Mapping
):
2986 r
= update(d
.get(k
, {}), v
)
2993 def create_instance(mydb
, tenant_id
, instance_dict
):
2994 # print "Checking that nfvo_tenant_id exists and getting the VIM URI and the VIM tenant_id"
2995 # logger.debug("Creating instance...")
2996 scenario
= instance_dict
["scenario"]
2998 # find main datacenter
3000 myvim_threads_id
= {}
3001 datacenter
= instance_dict
.get("datacenter")
3002 default_datacenter_id
, vim
= get_datacenter_by_name_uuid(mydb
, tenant_id
, datacenter
)
3003 myvims
[default_datacenter_id
] = vim
3004 myvim_threads_id
[default_datacenter_id
], _
= get_vim_thread(mydb
, tenant_id
, default_datacenter_id
)
3005 tenant
= mydb
.get_rows_by_id('nfvo_tenants', tenant_id
)
3006 # myvim_tenant = myvim['tenant_id']
3009 # print "Checking that the scenario exists and getting the scenario dictionary"
3010 if isinstance(scenario
, str):
3011 scenarioDict
= mydb
.get_scenario(scenario
, tenant_id
, datacenter_vim_id
=myvim_threads_id
[default_datacenter_id
],
3012 datacenter_id
=default_datacenter_id
)
3014 scenarioDict
= scenario
3015 scenarioDict
["uuid"] = None
3017 # logger.debug(">>>>>> Dictionaries before merging")
3018 # logger.debug(">>>>>> InstanceDict:\n{}".format(yaml.safe_dump(instance_dict,default_flow_style=False, width=256)))
3019 # logger.debug(">>>>>> ScenarioDict:\n{}".format(yaml.safe_dump(scenarioDict,default_flow_style=False, width=256)))
3021 db_instance_vnfs
= []
3022 db_instance_vms
= []
3023 db_instance_interfaces
= []
3024 db_instance_sfis
= []
3025 db_instance_sfs
= []
3026 db_instance_classifications
= []
3027 db_instance_sfps
= []
3032 instance_name
= instance_dict
["name"]
3033 instance_uuid
= str(uuid4())
3034 uuid_list
.append(instance_uuid
)
3035 db_instance_scenario
= {
3036 "uuid": instance_uuid
,
3037 "name": instance_name
,
3038 "tenant_id": tenant_id
,
3039 "scenario_id": scenarioDict
['uuid'],
3040 "datacenter_id": default_datacenter_id
,
3041 # filled bellow 'datacenter_tenant_id'
3042 "description": instance_dict
.get("description"),
3044 if scenarioDict
.get("cloud-config"):
3045 db_instance_scenario
["cloud_config"] = yaml
.safe_dump(scenarioDict
["cloud-config"],
3046 default_flow_style
=True, width
=256)
3047 instance_action_id
= get_task_id()
3048 db_instance_action
= {
3049 "uuid": instance_action_id
, # same uuid for the instance and the action on create
3050 "tenant_id": tenant_id
,
3051 "instance_id": instance_uuid
,
3052 "description": "CREATE",
3055 # Auxiliary dictionaries from x to y
3056 sce_net2instance
= {}
3057 net2task_id
= {'scenario': {}}
3059 def ip_profile_IM2RO(ip_profile_im
):
3060 # translate from input format to database format
3062 if 'subnet-address' in ip_profile_im
:
3063 ip_profile_ro
['subnet_address'] = ip_profile_im
['subnet-address']
3064 if 'ip-version' in ip_profile_im
:
3065 ip_profile_ro
['ip_version'] = ip_profile_im
['ip-version']
3066 if 'gateway-address' in ip_profile_im
:
3067 ip_profile_ro
['gateway_address'] = ip_profile_im
['gateway-address']
3068 if 'dns-address' in ip_profile_im
:
3069 ip_profile_ro
['dns_address'] = ip_profile_im
['dns-address']
3070 if isinstance(ip_profile_ro
['dns_address'], (list, tuple)):
3071 ip_profile_ro
['dns_address'] = ";".join(ip_profile_ro
['dns_address'])
3072 if 'dhcp' in ip_profile_im
:
3073 ip_profile_ro
['dhcp_start_address'] = ip_profile_im
['dhcp'].get('start-address')
3074 ip_profile_ro
['dhcp_enabled'] = ip_profile_im
['dhcp'].get('enabled', True)
3075 ip_profile_ro
['dhcp_count'] = ip_profile_im
['dhcp'].get('count')
3076 return ip_profile_ro
3078 # logger.debug("Creating instance from scenario-dict:\n%s",
3079 # yaml.safe_dump(scenarioDict, indent=4, default_flow_style=False))
3081 # 0 check correct parameters
3082 for net_name
, net_instance_desc
in instance_dict
.get("networks", {}).iteritems():
3083 for scenario_net
in scenarioDict
['nets']:
3084 if net_name
== scenario_net
.get("name") or net_name
== scenario_net
.get("osm_id") or net_name
== scenario_net
.get("uuid"):
3087 raise NfvoException("Invalid scenario network name or id '{}' at instance:networks".format(net_name
),
3088 httperrors
.Bad_Request
)
3089 if "sites" not in net_instance_desc
:
3090 net_instance_desc
["sites"] = [ {} ]
3091 site_without_datacenter_field
= False
3092 for site
in net_instance_desc
["sites"]:
3093 if site
.get("datacenter"):
3094 site
["datacenter"], _
= get_datacenter_uuid(mydb
, tenant_id
, site
["datacenter"])
3095 if site
["datacenter"] not in myvims
:
3096 # Add this datacenter to myvims
3097 d
, v
= get_datacenter_by_name_uuid(mydb
, tenant_id
, site
["datacenter"])
3099 myvim_threads_id
[d
], _
= get_vim_thread(mydb
, tenant_id
, site
["datacenter"])
3100 site
["datacenter"] = d
# change name to id
3102 if site_without_datacenter_field
:
3103 raise NfvoException("Found more than one entries without datacenter field at "
3104 "instance:networks:{}:sites".format(net_name
), httperrors
.Bad_Request
)
3105 site_without_datacenter_field
= True
3106 site
["datacenter"] = default_datacenter_id
# change name to id
3108 for vnf_name
, vnf_instance_desc
in instance_dict
.get("vnfs",{}).iteritems():
3109 for scenario_vnf
in scenarioDict
['vnfs']:
3110 if vnf_name
== scenario_vnf
['member_vnf_index'] or vnf_name
== scenario_vnf
['uuid'] or vnf_name
== scenario_vnf
['name']:
3113 raise NfvoException("Invalid vnf name '{}' at instance:vnfs".format(vnf_name
), httperrors
.Bad_Request
)
3114 if "datacenter" in vnf_instance_desc
:
3115 # Add this datacenter to myvims
3116 vnf_instance_desc
["datacenter"], _
= get_datacenter_uuid(mydb
, tenant_id
, vnf_instance_desc
["datacenter"])
3117 if vnf_instance_desc
["datacenter"] not in myvims
:
3118 d
, v
= get_datacenter_by_name_uuid(mydb
, tenant_id
, vnf_instance_desc
["datacenter"])
3120 myvim_threads_id
[d
], _
= get_vim_thread(mydb
, tenant_id
, vnf_instance_desc
["datacenter"])
3121 scenario_vnf
["datacenter"] = vnf_instance_desc
["datacenter"]
3123 for net_id
, net_instance_desc
in vnf_instance_desc
.get("networks", {}).iteritems():
3124 for scenario_net
in scenario_vnf
['nets']:
3125 if net_id
== scenario_net
['osm_id'] or net_id
== scenario_net
['uuid'] or net_id
== scenario_net
["name"]:
3128 raise NfvoException("Invalid net id or name '{}' at instance:vnfs:networks".format(net_id
), httperrors
.Bad_Request
)
3129 if net_instance_desc
.get("vim-network-name"):
3130 scenario_net
["vim-network-name"] = net_instance_desc
["vim-network-name"]
3131 if net_instance_desc
.get("vim-network-id"):
3132 scenario_net
["vim-network-id"] = net_instance_desc
["vim-network-id"]
3133 if net_instance_desc
.get("name"):
3134 scenario_net
["name"] = net_instance_desc
["name"]
3135 if 'ip-profile' in net_instance_desc
:
3136 ipprofile_db
= ip_profile_IM2RO(net_instance_desc
['ip-profile'])
3137 if 'ip_profile' not in scenario_net
:
3138 scenario_net
['ip_profile'] = ipprofile_db
3140 update(scenario_net
['ip_profile'], ipprofile_db
)
3142 for vdu_id
, vdu_instance_desc
in vnf_instance_desc
.get("vdus", {}).iteritems():
3143 for scenario_vm
in scenario_vnf
['vms']:
3144 if vdu_id
== scenario_vm
['osm_id'] or vdu_id
== scenario_vm
["name"]:
3147 raise NfvoException("Invalid vdu id or name '{}' at instance:vnfs:vdus".format(vdu_id
), httperrors
.Bad_Request
)
3148 scenario_vm
["instance_parameters"] = vdu_instance_desc
3149 for iface_id
, iface_instance_desc
in vdu_instance_desc
.get("interfaces", {}).iteritems():
3150 for scenario_interface
in scenario_vm
['interfaces']:
3151 if iface_id
== scenario_interface
['internal_name'] or iface_id
== scenario_interface
["external_name"]:
3152 scenario_interface
.update(iface_instance_desc
)
3155 raise NfvoException("Invalid vdu id or name '{}' at instance:vnfs:vdus".format(vdu_id
), httperrors
.Bad_Request
)
3157 # 0.1 parse cloud-config parameters
3158 cloud_config
= unify_cloud_config(instance_dict
.get("cloud-config"), scenarioDict
.get("cloud-config"))
3160 # 0.2 merge instance information into scenario
3161 # Ideally, the operation should be as simple as: update(scenarioDict,instance_dict)
3162 # However, this is not possible yet.
3163 for net_name
, net_instance_desc
in instance_dict
.get("networks", {}).iteritems():
3164 for scenario_net
in scenarioDict
['nets']:
3165 if net_name
== scenario_net
["name"]:
3166 if 'ip-profile' in net_instance_desc
:
3167 ipprofile_db
= ip_profile_IM2RO(net_instance_desc
['ip-profile'])
3168 if 'ip_profile' not in scenario_net
:
3169 scenario_net
['ip_profile'] = ipprofile_db
3171 update(scenario_net
['ip_profile'], ipprofile_db
)
3172 for interface
in net_instance_desc
.get('interfaces', ()):
3173 if 'ip_address' in interface
:
3174 for vnf
in scenarioDict
['vnfs']:
3175 if interface
['vnf'] == vnf
['name']:
3176 for vnf_interface
in vnf
['interfaces']:
3177 if interface
['vnf_interface'] == vnf_interface
['external_name']:
3178 vnf_interface
['ip_address'] = interface
['ip_address']
3180 # logger.debug(">>>>>>>> Merged dictionary")
3181 # logger.debug("Creating instance scenario-dict MERGED:\n%s",
3182 # yaml.safe_dump(scenarioDict, indent=4, default_flow_style=False))
3184 # 1. Creating new nets (sce_nets) in the VIM"
3185 number_mgmt_networks
= 0
3186 db_instance_nets
= []
3187 for sce_net
in scenarioDict
['nets']:
3188 sce_net_uuid
= sce_net
.get('uuid', sce_net
["name"])
3189 # get involved datacenters where this network need to be created
3190 involved_datacenters
= []
3191 for sce_vnf
in scenarioDict
.get("vnfs", ()):
3192 vnf_datacenter
= sce_vnf
.get("datacenter", default_datacenter_id
)
3193 if vnf_datacenter
in involved_datacenters
:
3195 if sce_vnf
.get("interfaces"):
3196 for sce_vnf_ifaces
in sce_vnf
["interfaces"]:
3197 if sce_vnf_ifaces
.get("sce_net_id") == sce_net
["uuid"]:
3198 involved_datacenters
.append(vnf_datacenter
)
3200 if not involved_datacenters
:
3201 involved_datacenters
.append(default_datacenter_id
)
3204 if instance_dict
.get("networks") and instance_dict
["networks"].get(sce_net
["name"]):
3205 descriptor_net
= instance_dict
["networks"][sce_net
["name"]]
3206 net_name
= descriptor_net
.get("vim-network-name")
3207 # add datacenters from instantiation parameters
3208 if descriptor_net
.get("sites"):
3209 for site
in descriptor_net
["sites"]:
3210 if site
.get("datacenter") and site
["datacenter"] not in involved_datacenters
:
3211 involved_datacenters
.append(site
["datacenter"])
3212 sce_net2instance
[sce_net_uuid
] = {}
3213 net2task_id
['scenario'][sce_net_uuid
] = {}
3215 if sce_net
["external"]:
3216 number_mgmt_networks
+= 1
3218 for datacenter_id
in involved_datacenters
:
3220 netmap_create
= None
3221 if descriptor_net
.get("sites"):
3222 for site
in descriptor_net
["sites"]:
3223 if site
.get("datacenter") == datacenter_id
:
3224 netmap_use
= site
.get("netmap-use")
3225 netmap_create
= site
.get("netmap-create")
3228 vim
= myvims
[datacenter_id
]
3229 myvim_thread_id
= myvim_threads_id
[datacenter_id
]
3231 net_type
= sce_net
['type']
3233 lookfor_filter
= {'admin_state_up': True, 'status': 'ACTIVE'} # 'shared': True
3236 if sce_net
["external"]:
3237 net_name
= sce_net
["name"]
3239 net_name
= "{}-{}".format(instance_name
, sce_net
["name"])
3240 net_name
= net_name
[:255] # limit length
3242 if netmap_use
or netmap_create
:
3243 create_network
= False
3244 lookfor_network
= False
3246 lookfor_network
= True
3247 if utils
.check_valid_uuid(netmap_use
):
3248 lookfor_filter
["id"] = netmap_use
3250 lookfor_filter
["name"] = netmap_use
3252 create_network
= True
3253 net_vim_name
= net_name
3254 if isinstance(netmap_create
, str):
3255 net_vim_name
= netmap_create
3256 elif sce_net
.get("vim_network_name"):
3257 create_network
= False
3258 lookfor_network
= True
3259 lookfor_filter
["name"] = sce_net
.get("vim_network_name")
3260 elif sce_net
["external"]:
3261 if sce_net
.get('vim_id'):
3262 # there is a netmap at datacenter_nets database # TODO REVISE!!!!
3263 create_network
= False
3264 lookfor_network
= True
3265 lookfor_filter
["id"] = sce_net
['vim_id']
3266 elif vim
["config"].get("management_network_id") or vim
["config"].get("management_network_name"):
3267 if number_mgmt_networks
> 1:
3268 raise NfvoException("Found several VLD of type mgmt. "
3269 "You must concrete what vim-network must be use for each one",
3270 httperrors
.Bad_Request
)
3271 create_network
= False
3272 lookfor_network
= True
3273 if vim
["config"].get("management_network_id"):
3274 lookfor_filter
["id"] = vim
["config"]["management_network_id"]
3276 lookfor_filter
["name"] = vim
["config"]["management_network_name"]
3278 # There is not a netmap, look at datacenter for a net with this name and create if not found
3279 create_network
= True
3280 lookfor_network
= True
3281 lookfor_filter
["name"] = sce_net
["name"]
3282 net_vim_name
= sce_net
["name"]
3284 net_vim_name
= net_name
3285 create_network
= True
3286 lookfor_network
= False
3290 task_action
= "CREATE"
3291 task_extra
["params"] = (net_vim_name
, net_type
, sce_net
.get('ip_profile', None))
3293 task_extra
["find"] = (lookfor_filter
,)
3294 elif lookfor_network
:
3295 task_action
= "FIND"
3296 task_extra
["params"] = (lookfor_filter
,)
3298 # fill database content
3299 net_uuid
= str(uuid4())
3300 uuid_list
.append(net_uuid
)
3301 sce_net2instance
[sce_net_uuid
][datacenter_id
] = net_uuid
3305 "vim_name": net_vim_name
,
3306 "instance_scenario_id": instance_uuid
,
3307 "sce_net_id": sce_net
.get("uuid"),
3308 "created": create_network
,
3309 'datacenter_id': datacenter_id
,
3310 'datacenter_tenant_id': myvim_thread_id
,
3311 'status': 'BUILD' # if create_network else "ACTIVE"
3313 db_instance_nets
.append(db_net
)
3315 "instance_action_id": instance_action_id
,
3316 "status": "SCHEDULED",
3317 "task_index": task_index
,
3318 "datacenter_vim_id": myvim_thread_id
,
3319 "action": task_action
,
3320 "item": "instance_nets",
3321 "item_id": net_uuid
,
3322 "extra": yaml
.safe_dump(task_extra
, default_flow_style
=True, width
=256)
3324 net2task_id
['scenario'][sce_net_uuid
][datacenter_id
] = task_index
3326 db_vim_actions
.append(db_vim_action
)
3328 if 'ip_profile' in sce_net
:
3330 'instance_net_id': net_uuid
,
3331 'ip_version': sce_net
['ip_profile']['ip_version'],
3332 'subnet_address': sce_net
['ip_profile']['subnet_address'],
3333 'gateway_address': sce_net
['ip_profile']['gateway_address'],
3334 'dns_address': sce_net
['ip_profile']['dns_address'],
3335 'dhcp_enabled': sce_net
['ip_profile']['dhcp_enabled'],
3336 'dhcp_start_address': sce_net
['ip_profile']['dhcp_start_address'],
3337 'dhcp_count': sce_net
['ip_profile']['dhcp_count'],
3339 db_ip_profiles
.append(db_ip_profile
)
3343 "default_datacenter_id": default_datacenter_id
,
3344 "myvim_threads_id": myvim_threads_id
,
3345 "instance_uuid": instance_uuid
,
3346 "instance_name": instance_name
,
3347 "instance_action_id": instance_action_id
,
3349 "cloud_config": cloud_config
,
3350 "RO_pub_key": tenant
[0].get('RO_pub_key'),
3351 "instance_parameters": instance_dict
,
3354 "task_index": task_index
,
3355 "uuid_list": uuid_list
,
3356 "db_instance_nets": db_instance_nets
,
3357 "db_vim_actions": db_vim_actions
,
3358 "db_ip_profiles": db_ip_profiles
,
3359 "db_instance_vnfs": db_instance_vnfs
,
3360 "db_instance_vms": db_instance_vms
,
3361 "db_instance_interfaces": db_instance_interfaces
,
3362 "net2task_id": net2task_id
,
3363 "sce_net2instance": sce_net2instance
,
3365 # sce_vnf_list = sorted(scenarioDict['vnfs'], key=lambda k: k['name'])
3366 for sce_vnf
in scenarioDict
.get('vnfs', ()): # sce_vnf_list:
3367 instantiate_vnf(mydb
, sce_vnf
, vnf_params
, vnf_params_out
, rollbackList
)
3368 task_index
= vnf_params_out
["task_index"]
3369 uuid_list
= vnf_params_out
["uuid_list"]
3372 # task_depends_on = []
3373 for vnffg
in scenarioDict
.get('vnffgs', ()):
3374 for rsp
in vnffg
['rsps']:
3376 for cp
in rsp
['connection_points']:
3377 count
= mydb
.get_rows(
3379 FROM
="vms join interfaces on vms.uuid=interfaces.vm_id join sce_rsp_hops as h "
3380 "on interfaces.uuid=h.ingress_interface_id",
3381 WHERE
={'h.uuid': cp
['uuid']})[0]['count']
3382 instance_vnf
= next((item
for item
in db_instance_vnfs
if item
['sce_vnf_id'] == cp
['sce_vnf_id']), None)
3383 instance_vms
= [item
for item
in db_instance_vms
if item
['instance_vnf_id'] == instance_vnf
['uuid']]
3385 for instance_vm
in instance_vms
:
3386 action
= next((item
for item
in db_vim_actions
if item
['item_id'] == instance_vm
['uuid']), None)
3388 dependencies
.append(action
['task_index'])
3389 # TODO: throw exception if count != len(instance_vms)
3390 # TODO: and action shouldn't ever be None
3392 for i
in range(count
):
3394 sfi_uuid
= str(uuid4())
3396 "ingress_interface_id": cp
["ingress_interface_id"],
3397 "egress_interface_id": cp
["egress_interface_id"]
3399 uuid_list
.append(sfi_uuid
)
3402 "instance_scenario_id": instance_uuid
,
3403 'sce_rsp_hop_id': cp
['uuid'],
3404 'datacenter_id': datacenter_id
,
3405 'datacenter_tenant_id': myvim_thread_id
,
3406 "vim_sfi_id": None, # vim thread will populate
3408 db_instance_sfis
.append(db_sfi
)
3410 "instance_action_id": instance_action_id
,
3411 "task_index": task_index
,
3412 "datacenter_vim_id": myvim_thread_id
,
3414 "status": "SCHEDULED",
3415 "item": "instance_sfis",
3416 "item_id": sfi_uuid
,
3417 "extra": yaml
.safe_dump({"params": extra_params
, "depends_on": [dependencies
[i
]]},
3418 default_flow_style
=True, width
=256)
3420 sfis_created
.append(task_index
)
3422 db_vim_actions
.append(db_vim_action
)
3424 sf_uuid
= str(uuid4())
3425 uuid_list
.append(sf_uuid
)
3428 "instance_scenario_id": instance_uuid
,
3429 'sce_rsp_hop_id': cp
['uuid'],
3430 'datacenter_id': datacenter_id
,
3431 'datacenter_tenant_id': myvim_thread_id
,
3432 "vim_sf_id": None, # vim thread will populate
3434 db_instance_sfs
.append(db_sf
)
3436 "instance_action_id": instance_action_id
,
3437 "task_index": task_index
,
3438 "datacenter_vim_id": myvim_thread_id
,
3440 "status": "SCHEDULED",
3441 "item": "instance_sfs",
3443 "extra": yaml
.safe_dump({"params": "", "depends_on": sfis_created
},
3444 default_flow_style
=True, width
=256)
3446 sfs_created
.append(task_index
)
3448 db_vim_actions
.append(db_vim_action
)
3449 classifier
= rsp
['classifier']
3451 # TODO the following ~13 lines can be reused for the sfi case
3452 count
= mydb
.get_rows(
3453 SELECT
=('vms.count'),
3454 FROM
="vms join interfaces on vms.uuid=interfaces.vm_id join sce_classifiers as c on interfaces.uuid=c.interface_id",
3455 WHERE
={'c.uuid': classifier
['uuid']})[0]['count']
3456 instance_vnf
= next((item
for item
in db_instance_vnfs
if item
['sce_vnf_id'] == classifier
['sce_vnf_id']), None)
3457 instance_vms
= [item
for item
in db_instance_vms
if item
['instance_vnf_id'] == instance_vnf
['uuid']]
3459 for instance_vm
in instance_vms
:
3460 action
= next((item
for item
in db_vim_actions
if item
['item_id'] == instance_vm
['uuid']), None)
3462 dependencies
.append(action
['task_index'])
3463 # TODO: throw exception if count != len(instance_vms)
3464 # TODO: and action shouldn't ever be None
3465 classifications_created
= []
3466 for i
in range(count
):
3467 for match
in classifier
['matches']:
3468 # create classifications
3469 classification_uuid
= str(uuid4())
3470 uuid_list
.append(classification_uuid
)
3471 db_classification
= {
3472 "uuid": classification_uuid
,
3473 "instance_scenario_id": instance_uuid
,
3474 'sce_classifier_match_id': match
['uuid'],
3475 'datacenter_id': datacenter_id
,
3476 'datacenter_tenant_id': myvim_thread_id
,
3477 "vim_classification_id": None, # vim thread will populate
3479 db_instance_classifications
.append(db_classification
)
3480 classification_params
= {
3481 "ip_proto": match
["ip_proto"],
3482 "source_ip": match
["source_ip"],
3483 "destination_ip": match
["destination_ip"],
3484 "source_port": match
["source_port"],
3485 "destination_port": match
["destination_port"]
3488 "instance_action_id": instance_action_id
,
3489 "task_index": task_index
,
3490 "datacenter_vim_id": myvim_thread_id
,
3492 "status": "SCHEDULED",
3493 "item": "instance_classifications",
3494 "item_id": classification_uuid
,
3495 "extra": yaml
.safe_dump({"params": classification_params
, "depends_on": [dependencies
[i
]]},
3496 default_flow_style
=True, width
=256)
3498 classifications_created
.append(task_index
)
3500 db_vim_actions
.append(db_vim_action
)
3503 sfp_uuid
= str(uuid4())
3504 uuid_list
.append(sfp_uuid
)
3507 "instance_scenario_id": instance_uuid
,
3508 'sce_rsp_id': rsp
['uuid'],
3509 'datacenter_id': datacenter_id
,
3510 'datacenter_tenant_id': myvim_thread_id
,
3511 "vim_sfp_id": None, # vim thread will populate
3513 db_instance_sfps
.append(db_sfp
)
3515 "instance_action_id": instance_action_id
,
3516 "task_index": task_index
,
3517 "datacenter_vim_id": myvim_thread_id
,
3519 "status": "SCHEDULED",
3520 "item": "instance_sfps",
3521 "item_id": sfp_uuid
,
3522 "extra": yaml
.safe_dump({"params": "", "depends_on": sfs_created
+ classifications_created
},
3523 default_flow_style
=True, width
=256)
3526 db_vim_actions
.append(db_vim_action
)
3527 db_instance_action
["number_tasks"] = task_index
3530 wan_links
= wim_engine
.derive_wan_links(db_instance_nets
, tenant_id
)
3531 wim_actions
= wim_engine
.create_actions(wan_links
)
3532 wim_actions
, db_instance_action
= (
3533 wim_engine
.incorporate_actions(wim_actions
, db_instance_action
))
3536 scenarioDict
["datacenter2tenant"] = myvim_threads_id
3538 db_instance_scenario
['datacenter_tenant_id'] = myvim_threads_id
[default_datacenter_id
]
3539 db_instance_scenario
['datacenter_id'] = default_datacenter_id
3541 {"instance_scenarios": db_instance_scenario
},
3542 {"instance_vnfs": db_instance_vnfs
},
3543 {"instance_nets": db_instance_nets
},
3544 {"ip_profiles": db_ip_profiles
},
3545 {"instance_vms": db_instance_vms
},
3546 {"instance_interfaces": db_instance_interfaces
},
3547 {"instance_actions": db_instance_action
},
3548 {"instance_sfis": db_instance_sfis
},
3549 {"instance_sfs": db_instance_sfs
},
3550 {"instance_classifications": db_instance_classifications
},
3551 {"instance_sfps": db_instance_sfps
},
3552 {"instance_wim_nets": wan_links
},
3553 {"vim_wim_actions": db_vim_actions
+ wim_actions
}
3556 logger
.debug("create_instance done DB tables: %s",
3557 yaml
.safe_dump(db_tables
, indent
=4, default_flow_style
=False) )
3558 mydb
.new_rows(db_tables
, uuid_list
)
3559 for myvim_thread_id
in myvim_threads_id
.values():
3560 vim_threads
["running"][myvim_thread_id
].insert_task(db_vim_actions
)
3562 wim_engine
.dispatch(wim_actions
)
3564 returned_instance
= mydb
.get_instance_scenario(instance_uuid
)
3565 returned_instance
["action_id"] = instance_action_id
3566 return returned_instance
3567 except (NfvoException
, vimconn
.vimconnException
, db_base_Exception
) as e
:
3568 message
= rollback(mydb
, myvims
, rollbackList
)
3569 if isinstance(e
, db_base_Exception
):
3570 error_text
= "database Exception"
3571 elif isinstance(e
, vimconn
.vimconnException
):
3572 error_text
= "VIM Exception"
3574 error_text
= "Exception"
3575 error_text
+= " {} {}. {}".format(type(e
).__name
__, str(e
), message
)
3576 # logger.error("create_instance: %s", error_text)
3578 raise NfvoException(error_text
, e
.http_code
)
3581 def instantiate_vnf(mydb
, sce_vnf
, params
, params_out
, rollbackList
):
3582 default_datacenter_id
= params
["default_datacenter_id"]
3583 myvim_threads_id
= params
["myvim_threads_id"]
3584 instance_uuid
= params
["instance_uuid"]
3585 instance_name
= params
["instance_name"]
3586 instance_action_id
= params
["instance_action_id"]
3587 myvims
= params
["myvims"]
3588 cloud_config
= params
["cloud_config"]
3589 RO_pub_key
= params
["RO_pub_key"]
3591 task_index
= params_out
["task_index"]
3592 uuid_list
= params_out
["uuid_list"]
3593 db_instance_nets
= params_out
["db_instance_nets"]
3594 db_vim_actions
= params_out
["db_vim_actions"]
3595 db_ip_profiles
= params_out
["db_ip_profiles"]
3596 db_instance_vnfs
= params_out
["db_instance_vnfs"]
3597 db_instance_vms
= params_out
["db_instance_vms"]
3598 db_instance_interfaces
= params_out
["db_instance_interfaces"]
3599 net2task_id
= params_out
["net2task_id"]
3600 sce_net2instance
= params_out
["sce_net2instance"]
3602 vnf_net2instance
= {}
3604 # 2. Creating new nets (vnf internal nets) in the VIM"
3605 # For each vnf net, we create it and we add it to instanceNetlist.
3606 if sce_vnf
.get("datacenter"):
3607 datacenter_id
= sce_vnf
["datacenter"]
3608 myvim_thread_id
= myvim_threads_id
[sce_vnf
["datacenter"]]
3610 datacenter_id
= default_datacenter_id
3611 myvim_thread_id
= myvim_threads_id
[default_datacenter_id
]
3612 for net
in sce_vnf
['nets']:
3614 # descriptor_net = instance_dict.get("vnfs", {}).get(sce_vnf["name"], {})
3615 # net_name = descriptor_net.get("name")
3618 net_name
= "{}-{}".format(instance_name
, net
["name"])
3619 net_name
= net_name
[:255] # limit length
3620 net_type
= net
['type']
3622 if sce_vnf
['uuid'] not in vnf_net2instance
:
3623 vnf_net2instance
[sce_vnf
['uuid']] = {}
3624 if sce_vnf
['uuid'] not in net2task_id
:
3625 net2task_id
[sce_vnf
['uuid']] = {}
3626 net2task_id
[sce_vnf
['uuid']][net
['uuid']] = task_index
3628 # fill database content
3629 net_uuid
= str(uuid4())
3630 uuid_list
.append(net_uuid
)
3631 vnf_net2instance
[sce_vnf
['uuid']][net
['uuid']] = net_uuid
3635 "vim_name": net_name
,
3636 "instance_scenario_id": instance_uuid
,
3637 "net_id": net
["uuid"],
3639 'datacenter_id': datacenter_id
,
3640 'datacenter_tenant_id': myvim_thread_id
,
3642 db_instance_nets
.append(db_net
)
3645 if net
.get("vim-network-name"):
3646 lookfor_filter
["name"] = net
["vim-network-name"]
3647 if net
.get("vim-network-id"):
3648 lookfor_filter
["id"] = net
["vim-network-id"]
3650 task_action
= "FIND"
3651 task_extra
= {"params": (lookfor_filter
,)}
3653 task_action
= "CREATE"
3654 task_extra
= {"params": (net_name
, net_type
, net
.get('ip_profile', None))}
3657 "instance_action_id": instance_action_id
,
3658 "task_index": task_index
,
3659 "datacenter_vim_id": myvim_thread_id
,
3660 "status": "SCHEDULED",
3661 "action": task_action
,
3662 "item": "instance_nets",
3663 "item_id": net_uuid
,
3664 "extra": yaml
.safe_dump(task_extra
, default_flow_style
=True, width
=256)
3667 db_vim_actions
.append(db_vim_action
)
3669 if 'ip_profile' in net
:
3671 'instance_net_id': net_uuid
,
3672 'ip_version': net
['ip_profile']['ip_version'],
3673 'subnet_address': net
['ip_profile']['subnet_address'],
3674 'gateway_address': net
['ip_profile']['gateway_address'],
3675 'dns_address': net
['ip_profile']['dns_address'],
3676 'dhcp_enabled': net
['ip_profile']['dhcp_enabled'],
3677 'dhcp_start_address': net
['ip_profile']['dhcp_start_address'],
3678 'dhcp_count': net
['ip_profile']['dhcp_count'],
3680 db_ip_profiles
.append(db_ip_profile
)
3682 # print "vnf_net2instance:"
3683 # print yaml.safe_dump(vnf_net2instance, indent=4, default_flow_style=False)
3685 # 3. Creating new vm instances in the VIM
3686 # myvim.new_vminstance(self,vimURI,tenant_id,name,description,image_id,flavor_id,net_dict)
3688 if sce_vnf
.get('mgmt_access'):
3689 ssh_access
= sce_vnf
['mgmt_access'].get('config-access', {}).get('ssh-access')
3690 vnf_availability_zones
= []
3691 for vm
in sce_vnf
.get('vms'):
3692 vm_av
= vm
.get('availability_zone')
3693 if vm_av
and vm_av
not in vnf_availability_zones
:
3694 vnf_availability_zones
.append(vm_av
)
3696 # check if there is enough availability zones available at vim level.
3697 if myvims
[datacenter_id
].availability_zone
and vnf_availability_zones
:
3698 if len(vnf_availability_zones
) > len(myvims
[datacenter_id
].availability_zone
):
3699 raise NfvoException('No enough availability zones at VIM for this deployment', httperrors
.Bad_Request
)
3701 if sce_vnf
.get("datacenter"):
3702 vim
= myvims
[sce_vnf
["datacenter"]]
3703 myvim_thread_id
= myvim_threads_id
[sce_vnf
["datacenter"]]
3704 datacenter_id
= sce_vnf
["datacenter"]
3706 vim
= myvims
[default_datacenter_id
]
3707 myvim_thread_id
= myvim_threads_id
[default_datacenter_id
]
3708 datacenter_id
= default_datacenter_id
3709 sce_vnf
["datacenter_id"] = datacenter_id
3712 vnf_uuid
= str(uuid4())
3713 uuid_list
.append(vnf_uuid
)
3716 'instance_scenario_id': instance_uuid
,
3717 'vnf_id': sce_vnf
['vnf_id'],
3718 'sce_vnf_id': sce_vnf
['uuid'],
3719 'datacenter_id': datacenter_id
,
3720 'datacenter_tenant_id': myvim_thread_id
,
3722 db_instance_vnfs
.append(db_instance_vnf
)
3724 for vm
in sce_vnf
['vms']:
3726 if vm
.get("pdu_type"):
3730 sce_vnf_name
= sce_vnf
['member_vnf_index'] if sce_vnf
['member_vnf_index'] else sce_vnf
['name']
3731 myVMDict
['name'] = "{}-{}-{}".format(instance_name
[:64], sce_vnf_name
[:64], vm
["name"][:64])
3732 myVMDict
['description'] = myVMDict
['name'][0:99]
3734 # myVMDict['start'] = "no"
3735 if vm
.get("instance_parameters") and vm
["instance_parameters"].get("name"):
3736 myVMDict
['name'] = vm
["instance_parameters"].get("name")
3737 myVMDict
['name'] = myVMDict
['name'][0:255] # limit name length
3738 # create image at vim in case it not exist
3739 image_uuid
= vm
['image_id']
3740 if vm
.get("image_list"):
3741 for alternative_image
in vm
["image_list"]:
3742 if alternative_image
["vim_type"] == vim
["config"]["_vim_type_internal"]:
3743 image_uuid
= alternative_image
['image_id']
3745 image_dict
= mydb
.get_table_by_uuid_name("images", image_uuid
)
3746 image_id
= create_or_use_image(mydb
, {datacenter_id
: vim
}, image_dict
, [], True)
3747 vm
['vim_image_id'] = image_id
3749 # create flavor at vim in case it not exist
3750 flavor_dict
= mydb
.get_table_by_uuid_name("flavors", vm
['flavor_id'])
3751 if flavor_dict
['extended'] != None:
3752 flavor_dict
['extended'] = yaml
.load(flavor_dict
['extended'])
3753 flavor_id
= create_or_use_flavor(mydb
, {datacenter_id
: vim
}, flavor_dict
, rollbackList
, True)
3755 # Obtain information for additional disks
3756 extended_flavor_dict
= mydb
.get_rows(FROM
='datacenters_flavors', SELECT
=('extended',),
3757 WHERE
={'vim_id': flavor_id
})
3758 if not extended_flavor_dict
:
3759 raise NfvoException("flavor '{}' not found".format(flavor_id
), httperrors
.Not_Found
)
3761 # extended_flavor_dict_yaml = yaml.load(extended_flavor_dict[0])
3762 myVMDict
['disks'] = None
3763 extended_info
= extended_flavor_dict
[0]['extended']
3764 if extended_info
!= None:
3765 extended_flavor_dict_yaml
= yaml
.load(extended_info
)
3766 if 'disks' in extended_flavor_dict_yaml
:
3767 myVMDict
['disks'] = extended_flavor_dict_yaml
['disks']
3768 if vm
.get("instance_parameters") and vm
["instance_parameters"].get("devices"):
3769 for disk
in myVMDict
['disks']:
3770 if disk
.get("name") in vm
["instance_parameters"]["devices"]:
3771 disk
.update(vm
["instance_parameters"]["devices"][disk
.get("name")])
3773 vm
['vim_flavor_id'] = flavor_id
3774 myVMDict
['imageRef'] = vm
['vim_image_id']
3775 myVMDict
['flavorRef'] = vm
['vim_flavor_id']
3776 myVMDict
['availability_zone'] = vm
.get('availability_zone')
3777 myVMDict
['networks'] = []
3778 task_depends_on
= []
3779 # TODO ALF. connect_mgmt_interfaces. Connect management interfaces if this is true
3780 is_management_vm
= False
3782 for iface
in vm
['interfaces']:
3784 if iface
['type'] == "data":
3785 netDict
['type'] = iface
['model']
3786 elif "model" in iface
and iface
["model"] != None:
3787 netDict
['model'] = iface
['model']
3788 # TODO in future, remove this because mac_address will not be set, and the type of PV,VF
3789 # is obtained from iterface table model
3790 # discover type of interface looking at flavor
3791 for numa
in flavor_dict
.get('extended', {}).get('numas', []):
3792 for flavor_iface
in numa
.get('interfaces', []):
3793 if flavor_iface
.get('name') == iface
['internal_name']:
3794 if flavor_iface
['dedicated'] == 'yes':
3795 netDict
['type'] = "PF" # passthrough
3796 elif flavor_iface
['dedicated'] == 'no':
3797 netDict
['type'] = "VF" # siov
3798 elif flavor_iface
['dedicated'] == 'yes:sriov':
3799 netDict
['type'] = "VFnotShared" # sriov but only one sriov on the PF
3800 netDict
["mac_address"] = flavor_iface
.get("mac_address")
3802 netDict
["use"] = iface
['type']
3803 if netDict
["use"] == "data" and not netDict
.get("type"):
3804 # print "netDict", netDict
3805 # print "iface", iface
3806 e_text
= "Cannot determine the interface type PF or VF of VNF '{}' VM '{}' iface '{}'".fromat(
3807 sce_vnf
['name'], vm
['name'], iface
['internal_name'])
3808 if flavor_dict
.get('extended') == None:
3809 raise NfvoException(e_text
+ "After database migration some information is not available. \
3810 Try to delete and create the scenarios and VNFs again", httperrors
.Conflict
)
3812 raise NfvoException(e_text
, httperrors
.Internal_Server_Error
)
3813 if netDict
["use"] == "mgmt":
3814 is_management_vm
= True
3815 netDict
["type"] = "virtual"
3816 if netDict
["use"] == "bridge":
3817 netDict
["type"] = "virtual"
3818 if iface
.get("vpci"):
3819 netDict
['vpci'] = iface
['vpci']
3820 if iface
.get("mac"):
3821 netDict
['mac_address'] = iface
['mac']
3822 if iface
.get("mac_address"):
3823 netDict
['mac_address'] = iface
['mac_address']
3824 if iface
.get("ip_address"):
3825 netDict
['ip_address'] = iface
['ip_address']
3826 if iface
.get("port-security") is not None:
3827 netDict
['port_security'] = iface
['port-security']
3828 if iface
.get("floating-ip") is not None:
3829 netDict
['floating_ip'] = iface
['floating-ip']
3830 netDict
['name'] = iface
['internal_name']
3831 if iface
['net_id'] is None:
3832 for vnf_iface
in sce_vnf
["interfaces"]:
3835 if vnf_iface
['interface_id'] == iface
['uuid']:
3836 netDict
['net_id'] = "TASK-{}".format(
3837 net2task_id
['scenario'][vnf_iface
['sce_net_id']][datacenter_id
])
3838 instance_net_id
= sce_net2instance
[vnf_iface
['sce_net_id']][datacenter_id
]
3839 task_depends_on
.append(net2task_id
['scenario'][vnf_iface
['sce_net_id']][datacenter_id
])
3842 netDict
['net_id'] = "TASK-{}".format(net2task_id
[sce_vnf
['uuid']][iface
['net_id']])
3843 instance_net_id
= vnf_net2instance
[sce_vnf
['uuid']][iface
['net_id']]
3844 task_depends_on
.append(net2task_id
[sce_vnf
['uuid']][iface
['net_id']])
3845 # skip bridge ifaces not connected to any net
3846 if 'net_id' not in netDict
or netDict
['net_id'] == None:
3848 myVMDict
['networks'].append(netDict
)
3851 # 'instance_vm_id': instance_vm_uuid,
3852 "instance_net_id": instance_net_id
,
3853 'interface_id': iface
['uuid'],
3854 # 'vim_interface_id': ,
3855 'type': 'external' if iface
['external_name'] is not None else 'internal',
3856 'ip_address': iface
.get('ip_address'),
3857 'mac_address': iface
.get('mac'),
3858 'floating_ip': int(iface
.get('floating-ip', False)),
3859 'port_security': int(iface
.get('port-security', True))
3861 db_vm_ifaces
.append(db_vm_iface
)
3862 # print ">>>>>>>>>>>>>>>>>>>>>>>>>>>"
3863 # print myVMDict['name']
3864 # print "networks", yaml.safe_dump(myVMDict['networks'], indent=4, default_flow_style=False)
3865 # print "interfaces", yaml.safe_dump(vm['interfaces'], indent=4, default_flow_style=False)
3866 # print ">>>>>>>>>>>>>>>>>>>>>>>>>>>"
3868 # We add the RO key to cloud_config if vnf will need ssh access
3869 cloud_config_vm
= cloud_config
3870 if is_management_vm
and params
["instance_parameters"].get("mgmt_keys"):
3871 cloud_config_vm
= unify_cloud_config({"key-pairs": params
["instance_parameters"]["mgmt_keys"]},
3874 if vm
.get("instance_parameters") and vm
["instance_parameters"].get("mgmt_keys"):
3875 cloud_config_vm
= unify_cloud_config({"key-pairs": vm
["instance_parameters"]["mgmt_keys"]},
3877 # if ssh_access and ssh_access['required'] and ssh_access['default-user'] and tenant[0].get('RO_pub_key'):
3878 # RO_key = {"key-pairs": [tenant[0]['RO_pub_key']]}
3879 # cloud_config_vm = unify_cloud_config(cloud_config_vm, RO_key)
3880 if vm
.get("boot_data"):
3881 cloud_config_vm
= unify_cloud_config(vm
["boot_data"], cloud_config_vm
)
3883 if myVMDict
.get('availability_zone'):
3884 av_index
= vnf_availability_zones
.index(myVMDict
['availability_zone'])
3887 for vm_index
in range(0, vm
.get('count', 1)):
3888 vm_name
= myVMDict
['name'] + "-" + str(vm_index
+1)
3889 task_params
= (vm_name
, myVMDict
['description'], myVMDict
.get('start', None),
3890 myVMDict
['imageRef'], myVMDict
['flavorRef'], myVMDict
['networks'], cloud_config_vm
,
3891 myVMDict
['disks'], av_index
, vnf_availability_zones
)
3892 # put interface uuid back to scenario[vnfs][vms[[interfaces]
3893 for net
in myVMDict
['networks']:
3895 for iface
in vm
['interfaces']:
3896 if net
["name"] == iface
["internal_name"]:
3897 iface
["vim_id"] = net
["vim_id"]
3899 vm_uuid
= str(uuid4())
3900 uuid_list
.append(vm_uuid
)
3903 'instance_vnf_id': vnf_uuid
,
3904 # TODO delete "vim_vm_id": vm_id,
3905 "vm_id": vm
["uuid"],
3906 "vim_name": vm_name
,
3909 db_instance_vms
.append(db_vm
)
3912 for db_vm_iface
in db_vm_ifaces
:
3913 iface_uuid
= str(uuid4())
3914 uuid_list
.append(iface_uuid
)
3915 db_vm_iface_instance
= {
3917 "instance_vm_id": vm_uuid
3919 db_vm_iface_instance
.update(db_vm_iface
)
3920 if db_vm_iface_instance
.get("ip_address"): # increment ip_address
3921 ip
= db_vm_iface_instance
.get("ip_address")
3926 ip
= ip
[i
:] + str(int(ip
[:i
]) + 1)
3927 db_vm_iface_instance
["ip_address"] = ip
3929 db_vm_iface_instance
["ip_address"] = None
3930 db_instance_interfaces
.append(db_vm_iface_instance
)
3931 myVMDict
['networks'][iface_index
]["uuid"] = iface_uuid
3935 "instance_action_id": instance_action_id
,
3936 "task_index": task_index
,
3937 "datacenter_vim_id": myvim_thread_id
,
3939 "status": "SCHEDULED",
3940 "item": "instance_vms",
3942 "extra": yaml
.safe_dump({"params": task_params
, "depends_on": task_depends_on
},
3943 default_flow_style
=True, width
=256)
3946 db_vim_actions
.append(db_vim_action
)
3947 params_out
["task_index"] = task_index
3948 params_out
["uuid_list"] = uuid_list
3951 def delete_instance(mydb
, tenant_id
, instance_id
):
3952 # print "Checking that the instance_id exists and getting the instance dictionary"
3953 instanceDict
= mydb
.get_instance_scenario(instance_id
, tenant_id
)
3954 # print yaml.safe_dump(instanceDict, indent=4, default_flow_style=False)
3955 tenant_id
= instanceDict
["tenant_id"]
3958 # We need to retrieve the WIM Actions now, before the instance_scenario is
3959 # deleted. The reason for that is that: ON CASCADE rules will delete the
3960 # instance_wim_nets record in the database
3961 wim_actions
= wim_engine
.delete_actions(instance_scenario_id
=instance_id
)
3964 # print "Checking that nfvo_tenant_id exists and getting the VIM URI and the VIM tenant_id"
3965 # 1. Delete from Database
3966 message
= mydb
.delete_instance_scenario(instance_id
, tenant_id
)
3968 # 2. delete from VIM
3972 vimthread_affected
= {}
3973 net2vm_dependencies
= {}
3976 instance_action_id
= get_task_id()
3978 db_instance_action
= {
3979 "uuid": instance_action_id
, # same uuid for the instance and the action on create
3980 "tenant_id": tenant_id
,
3981 "instance_id": instance_id
,
3982 "description": "DELETE",
3983 # "number_tasks": 0 # filled bellow
3986 # 2.1 deleting VNFFGs
3987 for sfp
in instanceDict
.get('sfps', ()):
3988 vimthread_affected
[sfp
["datacenter_tenant_id"]] = None
3989 datacenter_key
= (sfp
["datacenter_id"], sfp
["datacenter_tenant_id"])
3990 if datacenter_key
not in myvims
:
3992 _
, myvim_thread
= get_vim_thread(mydb
, tenant_id
, sfp
["datacenter_id"], sfp
["datacenter_tenant_id"])
3993 except NfvoException
as e
:
3994 logger
.error(str(e
))
3996 myvim_threads
[datacenter_key
] = myvim_thread
3997 vims
= get_vim(mydb
, tenant_id
, datacenter_id
=sfp
["datacenter_id"],
3998 datacenter_tenant_id
=sfp
["datacenter_tenant_id"])
4000 logger
.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(sfp
["datacenter_id"], sfp
["datacenter_tenant_id"]))
4001 myvims
[datacenter_key
] = None
4003 myvims
[datacenter_key
] = vims
.values()[0]
4004 myvim
= myvims
[datacenter_key
]
4005 myvim_thread
= myvim_threads
[datacenter_key
]
4008 error_msg
+= "\n vim_sfp_id={} cannot be deleted because datacenter={} not found".format(sfp
['vim_sfp_id'], sfp
["datacenter_id"])
4010 extra
= {"params": (sfp
['vim_sfp_id'])}
4012 "instance_action_id": instance_action_id
,
4013 "task_index": task_index
,
4014 "datacenter_vim_id": sfp
["datacenter_tenant_id"],
4016 "status": "SCHEDULED",
4017 "item": "instance_sfps",
4018 "item_id": sfp
["uuid"],
4019 "extra": yaml
.safe_dump(extra
, default_flow_style
=True, width
=256)
4022 db_vim_actions
.append(db_vim_action
)
4024 for classification
in instanceDict
['classifications']:
4025 vimthread_affected
[classification
["datacenter_tenant_id"]] = None
4026 datacenter_key
= (classification
["datacenter_id"], classification
["datacenter_tenant_id"])
4027 if datacenter_key
not in myvims
:
4029 _
, myvim_thread
= get_vim_thread(mydb
, tenant_id
, classification
["datacenter_id"], classification
["datacenter_tenant_id"])
4030 except NfvoException
as e
:
4031 logger
.error(str(e
))
4033 myvim_threads
[datacenter_key
] = myvim_thread
4034 vims
= get_vim(mydb
, tenant_id
, datacenter_id
=classification
["datacenter_id"],
4035 datacenter_tenant_id
=classification
["datacenter_tenant_id"])
4037 logger
.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(classification
["datacenter_id"],
4038 classification
["datacenter_tenant_id"]))
4039 myvims
[datacenter_key
] = None
4041 myvims
[datacenter_key
] = vims
.values()[0]
4042 myvim
= myvims
[datacenter_key
]
4043 myvim_thread
= myvim_threads
[datacenter_key
]
4046 error_msg
+= "\n vim_classification_id={} cannot be deleted because datacenter={} not found".format(classification
['vim_classification_id'],
4047 classification
["datacenter_id"])
4049 depends_on
= [action
["task_index"] for action
in db_vim_actions
if action
["item"] == "instance_sfps"]
4050 extra
= {"params": (classification
['vim_classification_id']), "depends_on": depends_on
}
4052 "instance_action_id": instance_action_id
,
4053 "task_index": task_index
,
4054 "datacenter_vim_id": classification
["datacenter_tenant_id"],
4056 "status": "SCHEDULED",
4057 "item": "instance_classifications",
4058 "item_id": classification
["uuid"],
4059 "extra": yaml
.safe_dump(extra
, default_flow_style
=True, width
=256)
4062 db_vim_actions
.append(db_vim_action
)
4064 for sf
in instanceDict
.get('sfs', ()):
4065 vimthread_affected
[sf
["datacenter_tenant_id"]] = None
4066 datacenter_key
= (sf
["datacenter_id"], sf
["datacenter_tenant_id"])
4067 if datacenter_key
not in myvims
:
4069 _
, myvim_thread
= get_vim_thread(mydb
, tenant_id
, sf
["datacenter_id"], sf
["datacenter_tenant_id"])
4070 except NfvoException
as e
:
4071 logger
.error(str(e
))
4073 myvim_threads
[datacenter_key
] = myvim_thread
4074 vims
= get_vim(mydb
, tenant_id
, datacenter_id
=sf
["datacenter_id"],
4075 datacenter_tenant_id
=sf
["datacenter_tenant_id"])
4077 logger
.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(sf
["datacenter_id"], sf
["datacenter_tenant_id"]))
4078 myvims
[datacenter_key
] = None
4080 myvims
[datacenter_key
] = vims
.values()[0]
4081 myvim
= myvims
[datacenter_key
]
4082 myvim_thread
= myvim_threads
[datacenter_key
]
4085 error_msg
+= "\n vim_sf_id={} cannot be deleted because datacenter={} not found".format(sf
['vim_sf_id'], sf
["datacenter_id"])
4087 depends_on
= [action
["task_index"] for action
in db_vim_actions
if action
["item"] == "instance_sfps"]
4088 extra
= {"params": (sf
['vim_sf_id']), "depends_on": depends_on
}
4090 "instance_action_id": instance_action_id
,
4091 "task_index": task_index
,
4092 "datacenter_vim_id": sf
["datacenter_tenant_id"],
4094 "status": "SCHEDULED",
4095 "item": "instance_sfs",
4096 "item_id": sf
["uuid"],
4097 "extra": yaml
.safe_dump(extra
, default_flow_style
=True, width
=256)
4100 db_vim_actions
.append(db_vim_action
)
4102 for sfi
in instanceDict
.get('sfis', ()):
4103 vimthread_affected
[sfi
["datacenter_tenant_id"]] = None
4104 datacenter_key
= (sfi
["datacenter_id"], sfi
["datacenter_tenant_id"])
4105 if datacenter_key
not in myvims
:
4107 _
, myvim_thread
= get_vim_thread(mydb
, tenant_id
, sfi
["datacenter_id"], sfi
["datacenter_tenant_id"])
4108 except NfvoException
as e
:
4109 logger
.error(str(e
))
4111 myvim_threads
[datacenter_key
] = myvim_thread
4112 vims
= get_vim(mydb
, tenant_id
, datacenter_id
=sfi
["datacenter_id"],
4113 datacenter_tenant_id
=sfi
["datacenter_tenant_id"])
4115 logger
.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(sfi
["datacenter_id"], sfi
["datacenter_tenant_id"]))
4116 myvims
[datacenter_key
] = None
4118 myvims
[datacenter_key
] = vims
.values()[0]
4119 myvim
= myvims
[datacenter_key
]
4120 myvim_thread
= myvim_threads
[datacenter_key
]
4123 error_msg
+= "\n vim_sfi_id={} cannot be deleted because datacenter={} not found".format(sfi
['vim_sfi_id'], sfi
["datacenter_id"])
4125 depends_on
= [action
["task_index"] for action
in db_vim_actions
if action
["item"] == "instance_sfs"]
4126 extra
= {"params": (sfi
['vim_sfi_id']), "depends_on": depends_on
}
4128 "instance_action_id": instance_action_id
,
4129 "task_index": task_index
,
4130 "datacenter_vim_id": sfi
["datacenter_tenant_id"],
4132 "status": "SCHEDULED",
4133 "item": "instance_sfis",
4134 "item_id": sfi
["uuid"],
4135 "extra": yaml
.safe_dump(extra
, default_flow_style
=True, width
=256)
4138 db_vim_actions
.append(db_vim_action
)
4142 for sce_vnf
in instanceDict
.get('vnfs', ()):
4143 datacenter_key
= (sce_vnf
["datacenter_id"], sce_vnf
["datacenter_tenant_id"])
4144 vimthread_affected
[sce_vnf
["datacenter_tenant_id"]] = None
4145 if datacenter_key
not in myvims
:
4147 _
, myvim_thread
= get_vim_thread(mydb
, tenant_id
, sce_vnf
["datacenter_id"], sce_vnf
["datacenter_tenant_id"])
4148 except NfvoException
as e
:
4149 logger
.error(str(e
))
4151 myvim_threads
[datacenter_key
] = myvim_thread
4152 vims
= get_vim(mydb
, tenant_id
, datacenter_id
=sce_vnf
["datacenter_id"],
4153 datacenter_tenant_id
=sce_vnf
["datacenter_tenant_id"])
4155 logger
.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(sce_vnf
["datacenter_id"],
4156 sce_vnf
["datacenter_tenant_id"]))
4157 myvims
[datacenter_key
] = None
4159 myvims
[datacenter_key
] = vims
.values()[0]
4160 myvim
= myvims
[datacenter_key
]
4161 myvim_thread
= myvim_threads
[datacenter_key
]
4163 for vm
in sce_vnf
['vms']:
4165 error_msg
+= "\n VM id={} cannot be deleted because datacenter={} not found".format(vm
['vim_vm_id'], sce_vnf
["datacenter_id"])
4167 sfi_dependencies
= [action
["task_index"] for action
in db_vim_actions
if action
["item"] == "instance_sfis"]
4169 "instance_action_id": instance_action_id
,
4170 "task_index": task_index
,
4171 "datacenter_vim_id": sce_vnf
["datacenter_tenant_id"],
4173 "status": "SCHEDULED",
4174 "item": "instance_vms",
4175 "item_id": vm
["uuid"],
4176 "extra": yaml
.safe_dump({"params": vm
["interfaces"], "depends_on": sfi_dependencies
},
4177 default_flow_style
=True, width
=256)
4179 db_vim_actions
.append(db_vim_action
)
4180 for interface
in vm
["interfaces"]:
4181 if not interface
.get("instance_net_id"):
4183 if interface
["instance_net_id"] not in net2vm_dependencies
:
4184 net2vm_dependencies
[interface
["instance_net_id"]] = []
4185 net2vm_dependencies
[interface
["instance_net_id"]].append(task_index
)
4190 for net
in instanceDict
['nets']:
4191 vimthread_affected
[net
["datacenter_tenant_id"]] = None
4192 datacenter_key
= (net
["datacenter_id"], net
["datacenter_tenant_id"])
4193 if datacenter_key
not in myvims
:
4195 _
,myvim_thread
= get_vim_thread(mydb
, tenant_id
, net
["datacenter_id"], net
["datacenter_tenant_id"])
4196 except NfvoException
as e
:
4197 logger
.error(str(e
))
4199 myvim_threads
[datacenter_key
] = myvim_thread
4200 vims
= get_vim(mydb
, tenant_id
, datacenter_id
=net
["datacenter_id"],
4201 datacenter_tenant_id
=net
["datacenter_tenant_id"])
4203 logger
.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(net
["datacenter_id"], net
["datacenter_tenant_id"]))
4204 myvims
[datacenter_key
] = None
4206 myvims
[datacenter_key
] = vims
.values()[0]
4207 myvim
= myvims
[datacenter_key
]
4208 myvim_thread
= myvim_threads
[datacenter_key
]
4211 error_msg
+= "\n Net VIM_id={} cannot be deleted because datacenter={} not found".format(net
['vim_net_id'], net
["datacenter_id"])
4213 extra
= {"params": (net
['vim_net_id'], net
['sdn_net_id'])}
4214 if net2vm_dependencies
.get(net
["uuid"]):
4215 extra
["depends_on"] = net2vm_dependencies
[net
["uuid"]]
4216 sfi_dependencies
= [action
["task_index"] for action
in db_vim_actions
if action
["item"] == "instance_sfis"]
4217 if len(sfi_dependencies
) > 0:
4218 if "depends_on" in extra
:
4219 extra
["depends_on"] += sfi_dependencies
4221 extra
["depends_on"] = sfi_dependencies
4223 "instance_action_id": instance_action_id
,
4224 "task_index": task_index
,
4225 "datacenter_vim_id": net
["datacenter_tenant_id"],
4227 "status": "SCHEDULED",
4228 "item": "instance_nets",
4229 "item_id": net
["uuid"],
4230 "extra": yaml
.safe_dump(extra
, default_flow_style
=True, width
=256)
4233 db_vim_actions
.append(db_vim_action
)
4235 db_instance_action
["number_tasks"] = task_index
4238 wim_actions
, db_instance_action
= (
4239 wim_engine
.incorporate_actions(wim_actions
, db_instance_action
))
4243 {"instance_actions": db_instance_action
},
4244 {"vim_wim_actions": db_vim_actions
+ wim_actions
}
4247 logger
.debug("delete_instance done DB tables: %s",
4248 yaml
.safe_dump(db_tables
, indent
=4, default_flow_style
=False))
4249 mydb
.new_rows(db_tables
, ())
4250 for myvim_thread_id
in vimthread_affected
.keys():
4251 vim_threads
["running"][myvim_thread_id
].insert_task(db_vim_actions
)
4253 wim_engine
.dispatch(wim_actions
)
4255 if len(error_msg
) > 0:
4256 return 'action_id={} instance {} deleted but some elements could not be deleted, or already deleted '\
4257 '(error: 404) from VIM: {}'.format(instance_action_id
, message
, error_msg
)
4259 return "action_id={} instance {} deleted".format(instance_action_id
, message
)
4261 def get_instance_id(mydb
, tenant_id
, instance_id
):
4263 #check valid tenant_id
4264 check_tenant(mydb
, tenant_id
)
4267 instance_dict
= mydb
.get_instance_scenario(instance_id
, tenant_id
, verbose
=True)
4268 for net
in instance_dict
["nets"]:
4269 if net
.get("sdn_net_id"):
4270 net_sdn
= ovim
.show_network(net
["sdn_net_id"])
4272 "admin_state_up": net_sdn
.get("admin_state_up"),
4273 "flows": net_sdn
.get("flows"),
4274 "last_error": net_sdn
.get("last_error"),
4275 "ports": net_sdn
.get("ports"),
4276 "type": net_sdn
.get("type"),
4277 "status": net_sdn
.get("status"),
4278 "vlan": net_sdn
.get("vlan"),
4280 return instance_dict
4282 @deprecated("Instance is automatically refreshed by vim_threads")
4283 def refresh_instance(mydb
, nfvo_tenant
, instanceDict
, datacenter
=None, vim_tenant
=None):
4284 '''Refreshes a scenario instance. It modifies instanceDict'''
4286 - 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
4289 # # Assumption: nfvo_tenant and instance_id were checked before entering into this function
4290 # #print "nfvo.refresh_instance begins"
4291 # #print json.dumps(instanceDict, indent=4)
4293 # #print "Getting the VIM URL and the VIM tenant_id"
4296 # # 1. Getting VIM vm and net list
4297 # vms_updated = [] #List of VM instance uuids in openmano that were updated
4300 # for sce_vnf in instanceDict['vnfs']:
4301 # datacenter_key = (sce_vnf["datacenter_id"], sce_vnf["datacenter_tenant_id"])
4302 # if datacenter_key not in vm_list:
4303 # vm_list[datacenter_key] = []
4304 # if datacenter_key not in myvims:
4305 # vims = get_vim(mydb, nfvo_tenant, datacenter_id=sce_vnf["datacenter_id"],
4306 # datacenter_tenant_id=sce_vnf["datacenter_tenant_id"])
4307 # if len(vims) == 0:
4308 # logger.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(sce_vnf["datacenter_id"], sce_vnf["datacenter_tenant_id"]))
4309 # myvims[datacenter_key] = None
4311 # myvims[datacenter_key] = vims.values()[0]
4312 # for vm in sce_vnf['vms']:
4313 # vm_list[datacenter_key].append(vm['vim_vm_id'])
4314 # vms_notupdated.append(vm["uuid"])
4316 # nets_updated = [] #List of VM instance uuids in openmano that were updated
4317 # nets_notupdated=[]
4319 # for net in instanceDict['nets']:
4320 # datacenter_key = (net["datacenter_id"], net["datacenter_tenant_id"])
4321 # if datacenter_key not in net_list:
4322 # net_list[datacenter_key] = []
4323 # if datacenter_key not in myvims:
4324 # vims = get_vim(mydb, nfvo_tenant, datacenter_id=net["datacenter_id"],
4325 # datacenter_tenant_id=net["datacenter_tenant_id"])
4326 # if len(vims) == 0:
4327 # logger.error("datacenter '{}' with datacenter_tenant_id '{}' not found".format(net["datacenter_id"], net["datacenter_tenant_id"]))
4328 # myvims[datacenter_key] = None
4330 # myvims[datacenter_key] = vims.values()[0]
4332 # net_list[datacenter_key].append(net['vim_net_id'])
4333 # nets_notupdated.append(net["uuid"])
4335 # # 1. Getting the status of all VMs
4337 # for datacenter_key in myvims:
4338 # if not vm_list.get(datacenter_key):
4342 # if not myvims[datacenter_key]:
4343 # failed_message = "datacenter '{}' with datacenter_tenant_id '{}' not found".format(net["datacenter_id"], net["datacenter_tenant_id"])
4346 # vm_dict.update(myvims[datacenter_key].refresh_vms_status(vm_list[datacenter_key]) )
4348 # except vimconn.vimconnException as e:
4349 # logger.error("VIM exception %s %s", type(e).__name__, str(e))
4350 # failed_message = str(e)
4352 # for vm in vm_list[datacenter_key]:
4353 # vm_dict[vm] = {'status': "VIM_ERROR", 'error_msg': failed_message}
4355 # # 2. Update the status of VMs in the instanceDict, while collects the VMs whose status changed
4356 # for sce_vnf in instanceDict['vnfs']:
4357 # for vm in sce_vnf['vms']:
4358 # vm_id = vm['vim_vm_id']
4359 # interfaces = vm_dict[vm_id].pop('interfaces', [])
4360 # #2.0 look if contain manamgement interface, and if not change status from ACTIVE:NoMgmtIP to ACTIVE
4361 # has_mgmt_iface = False
4362 # for iface in vm["interfaces"]:
4363 # if iface["type"]=="mgmt":
4364 # has_mgmt_iface = True
4365 # if vm_dict[vm_id]['status'] == "ACTIVE:NoMgmtIP" and not has_mgmt_iface:
4366 # vm_dict[vm_id]['status'] = "ACTIVE"
4367 # if vm_dict[vm_id].get('error_msg') and len(vm_dict[vm_id]['error_msg']) >= 1024:
4368 # vm_dict[vm_id]['error_msg'] = vm_dict[vm_id]['error_msg'][:516] + " ... " + vm_dict[vm_id]['error_msg'][-500:]
4369 # 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'):
4370 # vm['status'] = vm_dict[vm_id]['status']
4371 # vm['error_msg'] = vm_dict[vm_id].get('error_msg')
4372 # vm['vim_info'] = vm_dict[vm_id].get('vim_info')
4373 # # 2.1. Update in openmano DB the VMs whose status changed
4375 # updates = mydb.update_rows('instance_vms', UPDATE=vm_dict[vm_id], WHERE={'uuid':vm["uuid"]})
4376 # vms_notupdated.remove(vm["uuid"])
4378 # vms_updated.append(vm["uuid"])
4379 # except db_base_Exception as e:
4380 # logger.error("nfvo.refresh_instance error database update: %s", str(e))
4381 # # 2.2. Update in openmano DB the interface VMs
4382 # for interface in interfaces:
4383 # #translate from vim_net_id to instance_net_id
4384 # network_id_list=[]
4385 # for net in instanceDict['nets']:
4386 # if net["vim_net_id"] == interface["vim_net_id"]:
4387 # network_id_list.append(net["uuid"])
4388 # if not network_id_list:
4390 # del interface["vim_net_id"]
4392 # for network_id in network_id_list:
4393 # mydb.update_rows('instance_interfaces', UPDATE=interface, WHERE={'instance_vm_id':vm["uuid"], "instance_net_id":network_id})
4394 # except db_base_Exception as e:
4395 # logger.error( "nfvo.refresh_instance error with vm=%s, interface_net_id=%s", vm["uuid"], network_id)
4397 # # 3. Getting the status of all nets
4399 # for datacenter_key in myvims:
4400 # if not net_list.get(datacenter_key):
4403 # failed_message = ""
4404 # if not myvims[datacenter_key]:
4405 # failed_message = "datacenter '{}' with datacenter_tenant_id '{}' not found".format(net["datacenter_id"], net["datacenter_tenant_id"])
4408 # net_dict.update(myvims[datacenter_key].refresh_nets_status(net_list[datacenter_key]) )
4410 # except vimconn.vimconnException as e:
4411 # logger.error("VIM exception %s %s", type(e).__name__, str(e))
4412 # failed_message = str(e)
4414 # for net in net_list[datacenter_key]:
4415 # net_dict[net] = {'status': "VIM_ERROR", 'error_msg': failed_message}
4417 # # 4. Update the status of nets in the instanceDict, while collects the nets whose status changed
4418 # # TODO: update nets inside a vnf
4419 # for net in instanceDict['nets']:
4420 # net_id = net['vim_net_id']
4421 # if net_dict[net_id].get('error_msg') and len(net_dict[net_id]['error_msg']) >= 1024:
4422 # net_dict[net_id]['error_msg'] = net_dict[net_id]['error_msg'][:516] + " ... " + net_dict[vm_id]['error_msg'][-500:]
4423 # 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'):
4424 # net['status'] = net_dict[net_id]['status']
4425 # net['error_msg'] = net_dict[net_id].get('error_msg')
4426 # net['vim_info'] = net_dict[net_id].get('vim_info')
4427 # # 5.1. Update in openmano DB the nets whose status changed
4429 # updated = mydb.update_rows('instance_nets', UPDATE=net_dict[net_id], WHERE={'uuid':net["uuid"]})
4430 # nets_notupdated.remove(net["uuid"])
4432 # nets_updated.append(net["uuid"])
4433 # except db_base_Exception as e:
4434 # logger.error("nfvo.refresh_instance error database update: %s", str(e))
4436 # # Returns appropriate output
4437 # #print "nfvo.refresh_instance finishes"
4438 # logger.debug("VMs updated in the database: %s; nets updated in the database %s; VMs not updated: %s; nets not updated: %s",
4439 # str(vms_updated), str(nets_updated), str(vms_notupdated), str(nets_notupdated))
4440 instance_id
= instanceDict
['uuid']
4441 # if len(vms_notupdated)+len(nets_notupdated)>0:
4442 # error_msg = "VMs not updated: " + str(vms_notupdated) + "; nets not updated: " + str(nets_notupdated)
4443 # return len(vms_notupdated)+len(nets_notupdated), 'Scenario instance ' + instance_id + ' refreshed but some elements could not be updated in the database: ' + error_msg
4445 return 0, 'Scenario instance ' + instance_id
+ ' refreshed.'
4447 def instance_action(mydb
,nfvo_tenant
,instance_id
, action_dict
):
4448 #print "Checking that the instance_id exists and getting the instance dictionary"
4449 instanceDict
= mydb
.get_instance_scenario(instance_id
, nfvo_tenant
)
4450 #print yaml.safe_dump(instanceDict, indent=4, default_flow_style=False)
4452 #print "Checking that nfvo_tenant_id exists and getting the VIM URI and the VIM tenant_id"
4453 vims
= get_vim(mydb
, nfvo_tenant
, instanceDict
['datacenter_id'])
4455 raise NfvoException("datacenter '{}' not found".format(str(instanceDict
['datacenter_id'])), httperrors
.Not_Found
)
4456 myvim
= vims
.values()[0]
4461 myvim_threads_id
= {}
4462 if action_dict
.get("vdu-scaling"):
4463 db_instance_vms
= []
4465 db_instance_interfaces
= []
4466 instance_action_id
= get_task_id()
4467 db_instance_action
= {
4468 "uuid": instance_action_id
, # same uuid for the instance and the action on create
4469 "tenant_id": nfvo_tenant
,
4470 "instance_id": instance_id
,
4471 "description": "SCALE",
4473 vm_result
["instance_action_id"] = instance_action_id
4474 vm_result
["created"] = []
4475 vm_result
["deleted"] = []
4477 for vdu
in action_dict
["vdu-scaling"]:
4478 vdu_id
= vdu
.get("vdu-id")
4479 osm_vdu_id
= vdu
.get("osm_vdu_id")
4480 member_vnf_index
= vdu
.get("member-vnf-index")
4481 vdu_count
= vdu
.get("count", 1)
4483 target_vms
= mydb
.get_rows(
4484 FROM
="instance_vms as vms join instance_vnfs as vnfs on vms.instance_vnf_id=vnfs.uuid",
4485 WHERE
={"vms.uuid": vdu_id
},
4486 ORDER_BY
="vms.created_at"
4489 raise NfvoException("Cannot find the vdu with id {}".format(vdu_id
), httperrors
.Not_Found
)
4491 if not osm_vdu_id
and not member_vnf_index
:
4492 raise NfvoException("Invalid input vdu parameters. Must supply either 'vdu-id' of 'osm_vdu_id','member-vnf-index'")
4493 target_vms
= mydb
.get_rows(
4494 # SELECT=("ivms.uuid", "ivnfs.datacenter_id", "ivnfs.datacenter_tenant_id"),
4495 FROM
="instance_vms as ivms join instance_vnfs as ivnfs on ivms.instance_vnf_id=ivnfs.uuid"\
4496 " join sce_vnfs as svnfs on ivnfs.sce_vnf_id=svnfs.uuid"\
4497 " join vms on ivms.vm_id=vms.uuid",
4498 WHERE
={"vms.osm_id": osm_vdu_id
, "svnfs.member_vnf_index": member_vnf_index
,
4499 "ivnfs.instance_scenario_id": instance_id
},
4500 ORDER_BY
="ivms.created_at"
4503 raise NfvoException("Cannot find the vdu with osm_vdu_id {} and member-vnf-index {}".format(osm_vdu_id
, member_vnf_index
), httperrors
.Not_Found
)
4504 vdu_id
= target_vms
[-1]["uuid"]
4505 target_vm
= target_vms
[-1]
4506 datacenter
= target_vm
["datacenter_id"]
4507 myvim_threads_id
[datacenter
], _
= get_vim_thread(mydb
, nfvo_tenant
, datacenter
)
4509 if vdu
["type"] == "delete":
4510 for index
in range(0, vdu_count
):
4511 target_vm
= target_vms
[-1-index
]
4512 vdu_id
= target_vm
["uuid"]
4514 vm_interfaces
= None
4515 for sce_vnf
in instanceDict
['vnfs']:
4516 for vm
in sce_vnf
['vms']:
4517 if vm
["uuid"] == vdu_id
:
4518 vm_interfaces
= vm
["interfaces"]
4522 "instance_action_id": instance_action_id
,
4523 "task_index": task_index
,
4524 "datacenter_vim_id": target_vm
["datacenter_tenant_id"],
4526 "status": "SCHEDULED",
4527 "item": "instance_vms",
4529 "extra": yaml
.safe_dump({"params": vm_interfaces
},
4530 default_flow_style
=True, width
=256)
4533 db_vim_actions
.append(db_vim_action
)
4534 vm_result
["deleted"].append(vdu_id
)
4535 # delete from database
4536 db_instance_vms
.append({"TO-DELETE": vdu_id
})
4538 else: # vdu["type"] == "create":
4540 where
= {"item": "instance_vms", "item_id": target_vm
["uuid"], "action": "CREATE"}
4542 vim_action_to_clone
= mydb
.get_rows(FROM
="vim_wim_actions", WHERE
=where
)
4543 if not vim_action_to_clone
:
4544 raise NfvoException("Cannot find the vim_action at database with {}".format(where
), httperrors
.Internal_Server_Error
)
4545 vim_action_to_clone
= vim_action_to_clone
[0]
4546 extra
= yaml
.safe_load(vim_action_to_clone
["extra"])
4548 # generate a new depends_on. Convert format TASK-Y into new format TASK-ACTION-XXXX.XXXX.Y
4549 # TODO do the same for flavor and image when available
4550 task_depends_on
= []
4551 task_params
= extra
["params"]
4552 task_params_networks
= deepcopy(task_params
[5])
4553 for iface
in task_params
[5]:
4554 if iface
["net_id"].startswith("TASK-"):
4555 if "." not in iface
["net_id"]:
4556 task_depends_on
.append("{}.{}".format(vim_action_to_clone
["instance_action_id"],
4557 iface
["net_id"][5:]))
4558 iface
["net_id"] = "TASK-{}.{}".format(vim_action_to_clone
["instance_action_id"],
4559 iface
["net_id"][5:])
4561 task_depends_on
.append(iface
["net_id"][5:])
4562 if "mac_address" in iface
:
4563 del iface
["mac_address"]
4565 vm_ifaces_to_clone
= mydb
.get_rows(FROM
="instance_interfaces", WHERE
={"instance_vm_id": target_vm
["uuid"]})
4566 for index
in range(0, vdu_count
):
4567 vm_uuid
= str(uuid4())
4568 vm_name
= target_vm
.get('vim_name')
4570 suffix
= vm_name
.rfind("-")
4571 vm_name
= vm_name
[:suffix
+1] + str(index
+ 1 + int(vm_name
[suffix
+1:]))
4576 'instance_vnf_id': target_vm
['instance_vnf_id'],
4577 'vm_id': target_vm
['vm_id'],
4580 db_instance_vms
.append(db_instance_vm
)
4582 for vm_iface
in vm_ifaces_to_clone
:
4583 iface_uuid
= str(uuid4())
4584 iface2iface
[vm_iface
["uuid"]] = iface_uuid
4587 'instance_vm_id': vm_uuid
,
4588 "instance_net_id": vm_iface
["instance_net_id"],
4589 'interface_id': vm_iface
['interface_id'],
4590 'type': vm_iface
['type'],
4591 'floating_ip': vm_iface
['floating_ip'],
4592 'port_security': vm_iface
['port_security']
4594 db_instance_interfaces
.append(db_vm_iface
)
4595 task_params_copy
= deepcopy(task_params
)
4596 for iface
in task_params_copy
[5]:
4597 iface
["uuid"] = iface2iface
[iface
["uuid"]]
4598 # increment ip_address
4599 if "ip_address" in iface
:
4600 ip
= iface
.get("ip_address")
4605 ip
= ip
[i
:] + str(int(ip
[:i
]) + 1)
4606 iface
["ip_address"] = ip
4608 iface
["ip_address"] = None
4610 task_params_copy
[0] = vm_name
4612 "instance_action_id": instance_action_id
,
4613 "task_index": task_index
,
4614 "datacenter_vim_id": vim_action_to_clone
["datacenter_vim_id"],
4616 "status": "SCHEDULED",
4617 "item": "instance_vms",
4621 # TODO examinar parametros, quitar MAC o incrementar. Incrementar IP y colocar las dependencias con ACTION-asdfasd.
4624 "extra": yaml
.safe_dump({"params": task_params_copy
, "depends_on": task_depends_on
}, default_flow_style
=True, width
=256)
4627 db_vim_actions
.append(db_vim_action
)
4628 vm_result
["created"].append(vm_uuid
)
4630 db_instance_action
["number_tasks"] = task_index
4632 {"instance_vms": db_instance_vms
},
4633 {"instance_interfaces": db_instance_interfaces
},
4634 {"instance_actions": db_instance_action
},
4636 # {"instance_sfis": db_instance_sfis},
4637 # {"instance_sfs": db_instance_sfs},
4638 # {"instance_classifications": db_instance_classifications},
4639 # {"instance_sfps": db_instance_sfps},
4640 {"vim_wim_actions": db_vim_actions
}
4642 logger
.debug("create_vdu done DB tables: %s",
4643 yaml
.safe_dump(db_tables
, indent
=4, default_flow_style
=False))
4644 mydb
.new_rows(db_tables
, [])
4645 for myvim_thread
in myvim_threads_id
.values():
4646 vim_threads
["running"][myvim_thread
].insert_task(db_vim_actions
)
4650 input_vnfs
= action_dict
.pop("vnfs", [])
4651 input_vms
= action_dict
.pop("vms", [])
4652 action_over_all
= True if not input_vnfs
and not input_vms
else False
4653 for sce_vnf
in instanceDict
['vnfs']:
4654 for vm
in sce_vnf
['vms']:
4655 if not action_over_all
and sce_vnf
['uuid'] not in input_vnfs
and sce_vnf
['vnf_name'] not in input_vnfs
and \
4656 sce_vnf
['member_vnf_index'] not in input_vnfs
and \
4657 vm
['uuid'] not in input_vms
and vm
['name'] not in input_vms
:
4660 if "add_public_key" in action_dict
:
4662 if sce_vnf
.get('mgmt_access'):
4663 mgmt_access
= yaml
.load(sce_vnf
['mgmt_access'])
4664 ssh_access
= mgmt_access
['config-access']['ssh-access']
4665 tenant
= mydb
.get_rows_by_id('nfvo_tenants', nfvo_tenant
)
4667 if ssh_access
['required'] and ssh_access
['default-user']:
4668 if 'ip_address' in vm
:
4669 mgmt_ip
= vm
['ip_address'].split(';')
4670 password
= mgmt_access
['config-access'].get('password')
4671 priv_RO_key
= decrypt_key(tenant
[0]['encrypted_RO_priv_key'], tenant
[0]['uuid'])
4672 myvim
.inject_user_key(mgmt_ip
[0], ssh_access
['default-user'],
4673 action_dict
['add_public_key'],
4674 password
=password
, ro_key
=priv_RO_key
)
4676 raise NfvoException("Unable to inject ssh key in vm: {} - Aborting".format(vm
['uuid']),
4677 httperrors
.Internal_Server_Error
)
4679 raise NfvoException("Unable to inject ssh key in vm: {} - Aborting".format(vm
['uuid']),
4680 httperrors
.Internal_Server_Error
)
4682 raise NfvoException("Unable to inject ssh key in vm: {} - Aborting".format(vm
['uuid']),
4683 httperrors
.Internal_Server_Error
)
4685 data
= myvim
.action_vminstance(vm
['vim_vm_id'], action_dict
)
4686 if "console" in action_dict
:
4687 if not global_config
["http_console_proxy"]:
4688 vm_result
[ vm
['uuid'] ] = {"vim_result": 200,
4689 "description": "{protocol}//{ip}:{port}/{suffix}".format(
4690 protocol
=data
["protocol"],
4691 ip
= data
["server"],
4692 port
= data
["port"],
4693 suffix
= data
["suffix"]),
4697 elif data
["server"]=="127.0.0.1" or data
["server"]=="localhost":
4698 vm_result
[ vm
['uuid'] ] = {"vim_result": -httperrors
.Unauthorized
,
4699 "description": "this console is only reachable by local interface",
4704 #print "console data", data
4706 console_thread
= create_or_use_console_proxy_thread(data
["server"], data
["port"])
4707 vm_result
[ vm
['uuid'] ] = {"vim_result": 200,
4708 "description": "{protocol}//{ip}:{port}/{suffix}".format(
4709 protocol
=data
["protocol"],
4710 ip
= global_config
["http_console_host"],
4711 port
= console_thread
.port
,
4712 suffix
= data
["suffix"]),
4716 except NfvoException
as e
:
4717 vm_result
[ vm
['uuid'] ] = {"vim_result": e
.http_code
, "name":vm
['name'], "description": str(e
)}
4721 vm_result
[ vm
['uuid'] ] = {"vim_result": 200, "description": "ok", "name":vm
['name']}
4723 except vimconn
.vimconnException
as e
:
4724 vm_result
[ vm
['uuid'] ] = {"vim_result": e
.http_code
, "name":vm
['name'], "description": str(e
)}
4727 if vm_ok
==0: #all goes wrong
4732 def instance_action_get(mydb
, nfvo_tenant
, instance_id
, action_id
):
4734 if nfvo_tenant
and nfvo_tenant
!= "any":
4735 filter["tenant_id"] = nfvo_tenant
4736 if instance_id
and instance_id
!= "any":
4737 filter["instance_id"] = instance_id
4739 filter["uuid"] = action_id
4740 rows
= mydb
.get_rows(FROM
="instance_actions", WHERE
=filter)
4743 raise NfvoException("Not found any action with this criteria", httperrors
.Not_Found
)
4744 vim_wim_actions
= mydb
.get_rows(FROM
="vim_wim_actions", WHERE
={"instance_action_id": action_id
})
4745 rows
[0]["vim_wim_actions"] = vim_wim_actions
4746 # for backward compatibility set vim_actions = vim_wim_actions
4747 rows
[0]["vim_actions"] = vim_wim_actions
4748 return {"actions": rows
}
4751 def create_or_use_console_proxy_thread(console_server
, console_port
):
4752 #look for a non-used port
4753 console_thread_key
= console_server
+ ":" + str(console_port
)
4754 if console_thread_key
in global_config
["console_thread"]:
4755 #global_config["console_thread"][console_thread_key].start_timeout()
4756 return global_config
["console_thread"][console_thread_key
]
4758 for port
in global_config
["console_port_iterator"]():
4759 #print "create_or_use_console_proxy_thread() port:", port
4760 if port
in global_config
["console_ports"]:
4763 clithread
= cli
.ConsoleProxyThread(global_config
['http_host'], port
, console_server
, console_port
)
4765 global_config
["console_thread"][console_thread_key
] = clithread
4766 global_config
["console_ports"][port
] = console_thread_key
4768 except cli
.ConsoleProxyExceptionPortUsed
as e
:
4769 #port used, try with onoher
4771 except cli
.ConsoleProxyException
as e
:
4772 raise NfvoException(str(e
), httperrors
.Bad_Request
)
4773 raise NfvoException("Not found any free 'http_console_ports'", httperrors
.Conflict
)
4776 def check_tenant(mydb
, tenant_id
):
4777 '''check that tenant exists at database'''
4778 tenant
= mydb
.get_rows(FROM
='nfvo_tenants', SELECT
=('uuid',), WHERE
={'uuid': tenant_id
})
4780 raise NfvoException("tenant '{}' not found".format(tenant_id
), httperrors
.Not_Found
)
4783 def new_tenant(mydb
, tenant_dict
):
4785 tenant_uuid
= str(uuid4())
4786 tenant_dict
['uuid'] = tenant_uuid
4788 pub_key
, priv_key
= create_RO_keypair(tenant_uuid
)
4789 tenant_dict
['RO_pub_key'] = pub_key
4790 tenant_dict
['encrypted_RO_priv_key'] = priv_key
4791 mydb
.new_row("nfvo_tenants", tenant_dict
, confidential_data
=True)
4792 except db_base_Exception
as e
:
4793 raise NfvoException("Error creating the new tenant: {} ".format(tenant_dict
['name']) + str(e
), e
.http_code
)
4796 def delete_tenant(mydb
, tenant
):
4797 #get nfvo_tenant info
4799 tenant_dict
= mydb
.get_table_by_uuid_name('nfvo_tenants', tenant
, 'tenant')
4800 mydb
.delete_row_by_id("nfvo_tenants", tenant_dict
['uuid'])
4801 return tenant_dict
['uuid'] + " " + tenant_dict
["name"]
4804 def new_datacenter(mydb
, datacenter_descriptor
):
4805 sdn_port_mapping
= None
4806 if "config" in datacenter_descriptor
:
4807 sdn_port_mapping
= datacenter_descriptor
["config"].pop("sdn-port-mapping", None)
4808 datacenter_descriptor
["config"] = yaml
.safe_dump(datacenter_descriptor
["config"], default_flow_style
=True,
4810 # Check that datacenter-type is correct
4811 datacenter_type
= datacenter_descriptor
.get("type", "openvim");
4812 # module_info = None
4814 module
= "vimconn_" + datacenter_type
4815 pkg
= __import__("osm_ro." + module
)
4816 # vim_conn = getattr(pkg, module)
4817 # module_info = imp.find_module(module, [__file__[:__file__.rfind("/")]])
4818 except (IOError, ImportError):
4819 # if module_info and module_info[0]:
4820 # file.close(module_info[0])
4821 raise NfvoException("Incorrect datacenter type '{}'. Plugin '{}.py' not installed".format(datacenter_type
,
4823 httperrors
.Bad_Request
)
4825 datacenter_id
= mydb
.new_row("datacenters", datacenter_descriptor
, add_uuid
=True, confidential_data
=True)
4826 if sdn_port_mapping
:
4828 datacenter_sdn_port_mapping_set(mydb
, None, datacenter_id
, sdn_port_mapping
)
4829 except Exception as e
:
4830 mydb
.delete_row_by_id("datacenters", datacenter_id
) # Rollback
4832 return datacenter_id
4835 def edit_datacenter(mydb
, datacenter_id_name
, datacenter_descriptor
):
4836 # obtain data, check that only one exist
4837 datacenter
= mydb
.get_table_by_uuid_name('datacenters', datacenter_id_name
)
4840 datacenter_id
= datacenter
['uuid']
4841 where
= {'uuid': datacenter
['uuid']}
4842 remove_port_mapping
= False
4843 new_sdn_port_mapping
= None
4844 if "config" in datacenter_descriptor
:
4845 if datacenter_descriptor
['config'] != None:
4847 new_config_dict
= datacenter_descriptor
["config"]
4848 if "sdn-port-mapping" in new_config_dict
:
4849 remove_port_mapping
= True
4850 new_sdn_port_mapping
= new_config_dict
.pop("sdn-port-mapping")
4851 # delete null fields
4853 for k
in new_config_dict
:
4854 if new_config_dict
[k
] is None:
4856 if k
== 'sdn-controller':
4857 remove_port_mapping
= True
4859 config_text
= datacenter
.get("config")
4862 config_dict
= yaml
.load(config_text
)
4863 config_dict
.update(new_config_dict
)
4864 # delete null fields
4867 except Exception as e
:
4868 raise NfvoException("Bad format at datacenter:config " + str(e
), httperrors
.Bad_Request
)
4870 datacenter_descriptor
["config"] = yaml
.safe_dump(config_dict
, default_flow_style
=True, width
=256)
4872 datacenter_descriptor
["config"] = None
4873 if remove_port_mapping
:
4875 datacenter_sdn_port_mapping_delete(mydb
, None, datacenter_id
)
4876 except ovimException
as e
:
4877 raise NfvoException("Error deleting datacenter-port-mapping " + str(e
), httperrors
.Conflict
)
4879 mydb
.update_rows('datacenters', datacenter_descriptor
, where
)
4880 if new_sdn_port_mapping
:
4882 datacenter_sdn_port_mapping_set(mydb
, None, datacenter_id
, new_sdn_port_mapping
)
4883 except ovimException
as e
:
4885 mydb
.update_rows('datacenters', datacenter
, where
)
4886 raise NfvoException("Error adding datacenter-port-mapping " + str(e
), httperrors
.Conflict
)
4887 return datacenter_id
4890 def delete_datacenter(mydb
, datacenter
):
4891 #get nfvo_tenant info
4892 datacenter_dict
= mydb
.get_table_by_uuid_name('datacenters', datacenter
, 'datacenter')
4893 mydb
.delete_row_by_id("datacenters", datacenter_dict
['uuid'])
4895 datacenter_sdn_port_mapping_delete(mydb
, None, datacenter_dict
['uuid'])
4896 except ovimException
as e
:
4897 raise NfvoException("Error deleting datacenter-port-mapping " + str(e
))
4898 return datacenter_dict
['uuid'] + " " + datacenter_dict
['name']
4901 def create_vim_account(mydb
, nfvo_tenant
, datacenter_id
, name
=None, vim_id
=None, vim_tenant
=None, vim_tenant_name
=None,
4902 vim_username
=None, vim_password
=None, config
=None):
4903 # get datacenter info
4905 if not datacenter_id
:
4907 raise NfvoException("You must provide 'vim_id", http_code
=httperrors
.Bad_Request
)
4908 datacenter_id
= vim_id
4909 datacenter_id
, datacenter_name
= get_datacenter_uuid(mydb
, None, datacenter_id
)
4911 create_vim_tenant
= True if not vim_tenant
and not vim_tenant_name
else False
4913 # get nfvo_tenant info
4914 tenant_dict
= mydb
.get_table_by_uuid_name('nfvo_tenants', nfvo_tenant
)
4915 if vim_tenant_name
==None:
4916 vim_tenant_name
=tenant_dict
['name']
4918 tenants_datacenter_dict
={"nfvo_tenant_id":tenant_dict
['uuid'], "datacenter_id":datacenter_id
}
4919 # #check that this association does not exist before
4920 # tenants_datacenters = mydb.get_rows(FROM='tenants_datacenters', WHERE=tenants_datacenter_dict)
4921 # if len(tenants_datacenters)>0:
4922 # raise NfvoException("datacenter '{}' and tenant'{}' are already attached".format(datacenter_id, tenant_dict['uuid']), httperrors.Conflict)
4924 vim_tenant_id_exist_atdb
=False
4925 if not create_vim_tenant
:
4926 where_
={"datacenter_id": datacenter_id
}
4927 if vim_tenant
!=None:
4928 where_
["vim_tenant_id"] = vim_tenant
4929 if vim_tenant_name
!=None:
4930 where_
["vim_tenant_name"] = vim_tenant_name
4931 #check if vim_tenant_id is already at database
4932 datacenter_tenants_dict
= mydb
.get_rows(FROM
='datacenter_tenants', WHERE
=where_
)
4933 if len(datacenter_tenants_dict
)>=1:
4934 datacenter_tenants_dict
= datacenter_tenants_dict
[0]
4935 vim_tenant_id_exist_atdb
=True
4936 #TODO check if a field has changed and edit entry at datacenter_tenants at DB
4938 datacenter_tenants_dict
= {}
4939 #insert at table datacenter_tenants
4940 else: #if vim_tenant==None:
4941 #create tenant at VIM if not provided
4943 _
, myvim
= get_datacenter_by_name_uuid(mydb
, None, datacenter
, vim_user
=vim_username
,
4944 vim_passwd
=vim_password
)
4945 datacenter_name
= myvim
["name"]
4946 vim_tenant
= myvim
.new_tenant(vim_tenant_name
, "created by openmano for datacenter "+datacenter_name
)
4947 except vimconn
.vimconnException
as e
:
4948 raise NfvoException("Not possible to create vim_tenant {} at VIM: {}".format(vim_tenant_id
, str(e
)), httperrors
.Internal_Server_Error
)
4949 datacenter_tenants_dict
= {}
4950 datacenter_tenants_dict
["created"]="true"
4952 #fill datacenter_tenants table
4953 if not vim_tenant_id_exist_atdb
:
4954 datacenter_tenants_dict
["vim_tenant_id"] = vim_tenant
4955 datacenter_tenants_dict
["vim_tenant_name"] = vim_tenant_name
4956 datacenter_tenants_dict
["user"] = vim_username
4957 datacenter_tenants_dict
["passwd"] = vim_password
4958 datacenter_tenants_dict
["datacenter_id"] = datacenter_id
4960 datacenter_tenants_dict
["name"] = name
4962 datacenter_tenants_dict
["name"] = datacenter_name
4964 datacenter_tenants_dict
["config"] = yaml
.safe_dump(config
, default_flow_style
=True, width
=256)
4965 id_
= mydb
.new_row('datacenter_tenants', datacenter_tenants_dict
, add_uuid
=True, confidential_data
=True)
4966 datacenter_tenants_dict
["uuid"] = id_
4968 #fill tenants_datacenters table
4969 datacenter_tenant_id
= datacenter_tenants_dict
["uuid"]
4970 tenants_datacenter_dict
["datacenter_tenant_id"] = datacenter_tenant_id
4971 mydb
.new_row('tenants_datacenters', tenants_datacenter_dict
)
4974 thread_name
= get_non_used_vim_name(datacenter_name
, datacenter_id
, tenant_dict
['name'], tenant_dict
['uuid'])
4975 new_thread
= vim_thread
.vim_thread(task_lock
, thread_name
, datacenter_name
, datacenter_tenant_id
,
4976 db
=db
, db_lock
=db_lock
, ovim
=ovim
)
4978 thread_id
= datacenter_tenants_dict
["uuid"]
4979 vim_threads
["running"][thread_id
] = new_thread
4981 except vimconn
.vimconnException
as e
:
4982 raise NfvoException(str(e
), httperrors
.Bad_Request
)
4985 def edit_vim_account(mydb
, nfvo_tenant
, datacenter_tenant_id
, datacenter_id
=None, name
=None, vim_tenant
=None,
4986 vim_tenant_name
=None, vim_username
=None, vim_password
=None, config
=None):
4988 # get vim_account; check is valid for this tenant
4989 from_
= "datacenter_tenants as dt JOIN tenants_datacenters as td ON dt.uuid=td.datacenter_tenant_id"
4990 where_
= {"td.nfvo_tenant_id": nfvo_tenant
}
4991 if datacenter_tenant_id
:
4992 where_
["dt.uuid"] = datacenter_tenant_id
4994 where_
["dt.datacenter_id"] = datacenter_id
4995 vim_accounts
= mydb
.get_rows(SELECT
="dt.uuid as uuid, config", FROM
=from_
, WHERE
=where_
)
4996 if not vim_accounts
:
4997 raise NfvoException("vim_account not found for this tenant", http_code
=httperrors
.Not_Found
)
4998 elif len(vim_accounts
) > 1:
4999 raise NfvoException("found more than one vim_account for this tenant", http_code
=httperrors
.Conflict
)
5000 datacenter_tenant_id
= vim_accounts
[0]["uuid"]
5001 original_config
= vim_accounts
[0]["config"]
5005 original_config_dict
= yaml
.load(original_config
)
5006 original_config_dict
.update(config
)
5007 update
["config"] = yaml
.safe_dump(original_config_dict
, default_flow_style
=True, width
=256)
5009 update_
['name'] = name
5011 update_
['vim_tenant_id'] = vim_tenant
5013 update_
['vim_tenant_name'] = vim_tenant_name
5015 update_
['user'] = vim_username
5017 update_
['passwd'] = vim_password
5019 mydb
.update_rows("datacenter_tenants", UPDATE
=update_
, WHERE
={"uuid": datacenter_tenant_id
})
5021 vim_threads
["running"][datacenter_tenant_id
].insert_task("reload")
5022 return datacenter_tenant_id
5024 def delete_vim_account(mydb
, tenant_id
, vim_account_id
, datacenter
=None):
5025 #get nfvo_tenant info
5026 if not tenant_id
or tenant_id
=="any":
5029 tenant_dict
= mydb
.get_table_by_uuid_name('nfvo_tenants', tenant_id
)
5030 tenant_uuid
= tenant_dict
['uuid']
5032 #check that this association exist before
5033 tenants_datacenter_dict
= {}
5035 datacenter_id
, _
= get_datacenter_uuid(mydb
, tenant_uuid
, datacenter
)
5036 tenants_datacenter_dict
["datacenter_id"] = datacenter_id
5037 elif vim_account_id
:
5038 tenants_datacenter_dict
["datacenter_tenant_id"] = vim_account_id
5040 tenants_datacenter_dict
["nfvo_tenant_id"] = tenant_uuid
5041 tenant_datacenter_list
= mydb
.get_rows(FROM
='tenants_datacenters', WHERE
=tenants_datacenter_dict
)
5042 if len(tenant_datacenter_list
)==0 and tenant_uuid
:
5043 raise NfvoException("datacenter '{}' and tenant '{}' are not attached".format(datacenter_id
, tenant_dict
['uuid']), httperrors
.Not_Found
)
5045 #delete this association
5046 mydb
.delete_row(FROM
='tenants_datacenters', WHERE
=tenants_datacenter_dict
)
5048 #get vim_tenant info and deletes
5050 for tenant_datacenter_item
in tenant_datacenter_list
:
5051 vim_tenant_dict
= mydb
.get_table_by_uuid_name('datacenter_tenants', tenant_datacenter_item
['datacenter_tenant_id'])
5052 #try to delete vim:tenant
5054 mydb
.delete_row_by_id('datacenter_tenants', tenant_datacenter_item
['datacenter_tenant_id'])
5055 if vim_tenant_dict
['created']=='true':
5056 #delete tenant at VIM if created by NFVO
5058 datacenter_id
, myvim
= get_datacenter_by_name_uuid(mydb
, tenant_id
, datacenter
)
5059 myvim
.delete_tenant(vim_tenant_dict
['vim_tenant_id'])
5060 except vimconn
.vimconnException
as e
:
5061 warning
= "Not possible to delete vim_tenant_id {} from VIM: {} ".format(vim_tenant_dict
['vim_tenant_id'], str(e
))
5062 logger
.warn(warning
)
5063 except db_base_Exception
as e
:
5064 logger
.error("Cannot delete datacenter_tenants " + str(e
))
5065 pass # the error will be caused because dependencies, vim_tenant can not be deleted
5066 thread_id
= tenant_datacenter_item
["datacenter_tenant_id"]
5067 thread
= vim_threads
["running"].get(thread_id
)
5069 thread
.insert_task("exit")
5070 vim_threads
["deleting"][thread_id
] = thread
5071 return "datacenter {} detached. {}".format(datacenter_id
, warning
)
5074 def datacenter_action(mydb
, tenant_id
, datacenter
, action_dict
):
5076 #get datacenter info
5077 datacenter_id
, myvim
= get_datacenter_by_name_uuid(mydb
, tenant_id
, datacenter
)
5079 if 'net-update' in action_dict
:
5081 nets
= myvim
.get_network_list(filter_dict
={'shared': True, 'admin_state_up': True, 'status': 'ACTIVE'})
5083 except vimconn
.vimconnException
as e
:
5084 #logger.error("nfvo.datacenter_action() Not possible to get_network_list from VIM: %s ", str(e))
5085 raise NfvoException(str(e
), httperrors
.Internal_Server_Error
)
5086 #update nets Change from VIM format to NFVO format
5089 net_nfvo
={'datacenter_id': datacenter_id
}
5090 net_nfvo
['name'] = net
['name']
5091 #net_nfvo['description']= net['name']
5092 net_nfvo
['vim_net_id'] = net
['id']
5093 net_nfvo
['type'] = net
['type'][0:6] #change from ('ptp','data','bridge_data','bridge_man') to ('bridge','data','ptp')
5094 net_nfvo
['shared'] = net
['shared']
5095 net_nfvo
['multipoint'] = False if net
['type']=='ptp' else True
5096 net_list
.append(net_nfvo
)
5097 inserted
, deleted
= mydb
.update_datacenter_nets(datacenter_id
, net_list
)
5098 logger
.info("Inserted %d nets, deleted %d old nets", inserted
, deleted
)
5100 elif 'net-edit' in action_dict
:
5101 net
= action_dict
['net-edit'].pop('net')
5102 what
= 'vim_net_id' if utils
.check_valid_uuid(net
) else 'name'
5103 result
= mydb
.update_rows('datacenter_nets', action_dict
['net-edit'],
5104 WHERE
={'datacenter_id':datacenter_id
, what
: net
})
5106 elif 'net-delete' in action_dict
:
5107 net
= action_dict
['net-deelte'].get('net')
5108 what
= 'vim_net_id' if utils
.check_valid_uuid(net
) else 'name'
5109 result
= mydb
.delete_row(FROM
='datacenter_nets',
5110 WHERE
={'datacenter_id':datacenter_id
, what
: net
})
5114 raise NfvoException("Unknown action " + str(action_dict
), httperrors
.Bad_Request
)
5117 def datacenter_edit_netmap(mydb
, tenant_id
, datacenter
, netmap
, action_dict
):
5118 #get datacenter info
5119 datacenter_id
, _
= get_datacenter_by_name_uuid(mydb
, tenant_id
, datacenter
)
5121 what
= 'uuid' if utils
.check_valid_uuid(netmap
) else 'name'
5122 result
= mydb
.update_rows('datacenter_nets', action_dict
['netmap'],
5123 WHERE
={'datacenter_id':datacenter_id
, what
: netmap
})
5127 def datacenter_new_netmap(mydb
, tenant_id
, datacenter
, action_dict
=None):
5128 #get datacenter info
5129 datacenter_id
, myvim
= get_datacenter_by_name_uuid(mydb
, tenant_id
, datacenter
)
5132 action_dict
= action_dict
["netmap"]
5133 if 'vim_id' in action_dict
:
5134 filter_dict
["id"] = action_dict
['vim_id']
5135 if 'vim_name' in action_dict
:
5136 filter_dict
["name"] = action_dict
['vim_name']
5138 filter_dict
["shared"] = True
5141 vim_nets
= myvim
.get_network_list(filter_dict
=filter_dict
)
5142 except vimconn
.vimconnException
as e
:
5143 #logger.error("nfvo.datacenter_new_netmap() Not possible to get_network_list from VIM: %s ", str(e))
5144 raise NfvoException(str(e
), httperrors
.Internal_Server_Error
)
5145 if len(vim_nets
)>1 and action_dict
:
5146 raise NfvoException("more than two networks found, specify with vim_id", httperrors
.Conflict
)
5147 elif len(vim_nets
)==0: # and action_dict:
5148 raise NfvoException("Not found a network at VIM with " + str(filter_dict
), httperrors
.Not_Found
)
5150 for net
in vim_nets
:
5151 net_nfvo
={'datacenter_id': datacenter_id
}
5152 if action_dict
and "name" in action_dict
:
5153 net_nfvo
['name'] = action_dict
['name']
5155 net_nfvo
['name'] = net
['name']
5156 #net_nfvo['description']= net['name']
5157 net_nfvo
['vim_net_id'] = net
['id']
5158 net_nfvo
['type'] = net
['type'][0:6] #change from ('ptp','data','bridge_data','bridge_man') to ('bridge','data','ptp')
5159 net_nfvo
['shared'] = net
['shared']
5160 net_nfvo
['multipoint'] = False if net
['type']=='ptp' else True
5162 net_id
= mydb
.new_row("datacenter_nets", net_nfvo
, add_uuid
=True)
5163 net_nfvo
["status"] = "OK"
5164 net_nfvo
["uuid"] = net_id
5165 except db_base_Exception
as e
:
5169 net_nfvo
["status"] = "FAIL: " + str(e
)
5170 net_list
.append(net_nfvo
)
5173 def get_sdn_net_id(mydb
, tenant_id
, datacenter
, network_id
):
5174 # obtain all network data
5176 if utils
.check_valid_uuid(network_id
):
5177 filter_dict
= {"id": network_id
}
5179 filter_dict
= {"name": network_id
}
5181 datacenter_id
, myvim
= get_datacenter_by_name_uuid(mydb
, tenant_id
, datacenter
)
5182 network
= myvim
.get_network_list(filter_dict
=filter_dict
)
5183 except vimconn
.vimconnException
as e
:
5184 raise NfvoException("Not possible to get_sdn_net_id from VIM: {}".format(str(e
)), e
.http_code
)
5186 # ensure the network is defined
5187 if len(network
) == 0:
5188 raise NfvoException("Network {} is not present in the system".format(network_id
),
5189 httperrors
.Bad_Request
)
5191 # ensure there is only one network with the provided name
5192 if len(network
) > 1:
5193 raise NfvoException("Multiple networks present in vim identified by {}".format(network_id
), httperrors
.Bad_Request
)
5195 # ensure it is a dataplane network
5196 if network
[0]['type'] != 'data':
5199 # ensure we use the id
5200 network_id
= network
[0]['id']
5202 # search in dabase mano_db in table instance nets for the sdn_net_id that corresponds to the vim_net_id==network_id
5203 # and with instance_scenario_id==NULL
5204 #search_dict = {'vim_net_id': network_id, 'instance_scenario_id': None}
5205 search_dict
= {'vim_net_id': network_id
}
5208 #sdn_network_id = mydb.get_rows(SELECT=('sdn_net_id',), FROM='instance_nets', WHERE=search_dict)[0]['sdn_net_id']
5209 result
= mydb
.get_rows(SELECT
=('sdn_net_id',), FROM
='instance_nets', WHERE
=search_dict
)
5210 except db_base_Exception
as e
:
5211 raise NfvoException("db_base_Exception obtaining SDN network to associated to vim network {}".format(
5212 network_id
) + str(e
), e
.http_code
)
5216 if net
['sdn_net_id'] != None:
5218 sdn_net_id
= net
['sdn_net_id']
5220 if sdn_net_counter
== 0:
5222 elif sdn_net_counter
== 1:
5225 raise NfvoException("More than one SDN network is associated to vim network {}".format(
5226 network_id
), httperrors
.Internal_Server_Error
)
5228 def get_sdn_controller_id(mydb
, datacenter
):
5229 # Obtain sdn controller id
5230 config
= mydb
.get_rows(SELECT
=('config',), FROM
='datacenters', WHERE
={'uuid': datacenter
})[0].get('config', '{}')
5234 return yaml
.load(config
).get('sdn-controller')
5236 def vim_net_sdn_attach(mydb
, tenant_id
, datacenter
, network_id
, descriptor
):
5238 sdn_network_id
= get_sdn_net_id(mydb
, tenant_id
, datacenter
, network_id
)
5239 if not sdn_network_id
:
5240 raise NfvoException("No SDN network is associated to vim-network {}".format(network_id
), httperrors
.Internal_Server_Error
)
5242 #Obtain sdn controller id
5243 controller_id
= get_sdn_controller_id(mydb
, datacenter
)
5244 if not controller_id
:
5245 raise NfvoException("No SDN controller is set for datacenter {}".format(datacenter
), httperrors
.Internal_Server_Error
)
5247 #Obtain sdn controller info
5248 sdn_controller
= ovim
.show_of_controller(controller_id
)
5251 'name': 'external_port',
5252 'net_id': sdn_network_id
,
5253 'ofc_id': controller_id
,
5254 'switch_dpid': sdn_controller
['dpid'],
5255 'switch_port': descriptor
['port']
5258 if 'vlan' in descriptor
:
5259 port_data
['vlan'] = descriptor
['vlan']
5260 if 'mac' in descriptor
:
5261 port_data
['mac'] = descriptor
['mac']
5263 result
= ovim
.new_port(port_data
)
5264 except ovimException
as e
:
5265 raise NfvoException("ovimException attaching SDN network {} to vim network {}".format(
5266 sdn_network_id
, network_id
) + str(e
), httperrors
.Internal_Server_Error
)
5267 except db_base_Exception
as e
:
5268 raise NfvoException("db_base_Exception attaching SDN network to vim network {}".format(
5269 network_id
) + str(e
), e
.http_code
)
5271 return 'Port uuid: '+ result
5273 def vim_net_sdn_detach(mydb
, tenant_id
, datacenter
, network_id
, port_id
=None):
5275 filter = {'uuid': port_id
}
5277 sdn_network_id
= get_sdn_net_id(mydb
, tenant_id
, datacenter
, network_id
)
5278 if not sdn_network_id
:
5279 raise NfvoException("No SDN network is associated to vim-network {}".format(network_id
),
5280 httperrors
.Internal_Server_Error
)
5281 #in case no port_id is specified only ports marked as 'external_port' will be detached
5282 filter = {'name': 'external_port', 'net_id': sdn_network_id
}
5285 port_list
= ovim
.get_ports(columns
={'uuid'}, filter=filter)
5286 except ovimException
as e
:
5287 raise NfvoException("ovimException obtaining external ports for net {}. ".format(network_id
) + str(e
),
5288 httperrors
.Internal_Server_Error
)
5290 if len(port_list
) == 0:
5291 raise NfvoException("No ports attached to the network {} were found with the requested criteria".format(network_id
),
5292 httperrors
.Bad_Request
)
5295 for port
in port_list
:
5297 port_uuid_list
.append(port
['uuid'])
5298 ovim
.delete_port(port
['uuid'])
5299 except ovimException
as e
:
5300 raise NfvoException("ovimException deleting port {} for net {}. ".format(port
['uuid'], network_id
) + str(e
), httperrors
.Internal_Server_Error
)
5302 return 'Detached ports uuid: {}'.format(','.join(port_uuid_list
))
5304 def vim_action_get(mydb
, tenant_id
, datacenter
, item
, name
):
5305 #get datacenter info
5306 datacenter_id
, myvim
= get_datacenter_by_name_uuid(mydb
, tenant_id
, datacenter
)
5309 if utils
.check_valid_uuid(name
):
5310 filter_dict
["id"] = name
5312 filter_dict
["name"] = name
5314 if item
=="networks":
5315 #filter_dict['tenant_id'] = myvim['tenant_id']
5316 content
= myvim
.get_network_list(filter_dict
=filter_dict
)
5318 if len(content
) == 0:
5319 raise NfvoException("Network {} is not present in the system. ".format(name
),
5320 httperrors
.Bad_Request
)
5322 #Update the networks with the attached ports
5324 sdn_network_id
= get_sdn_net_id(mydb
, tenant_id
, datacenter
, net
['id'])
5325 if sdn_network_id
!= None:
5327 #port_list = ovim.get_ports(columns={'uuid', 'switch_port', 'vlan'}, filter={'name': 'external_port', 'net_id': sdn_network_id})
5328 port_list
= ovim
.get_ports(columns
={'uuid', 'switch_port', 'vlan','name'}, filter={'net_id': sdn_network_id
})
5329 except ovimException
as e
:
5330 raise NfvoException("ovimException obtaining external ports for net {}. ".format(network_id
) + str(e
), httperrors
.Internal_Server_Error
)
5331 #Remove field name and if port name is external_port save it as 'type'
5332 for port
in port_list
:
5333 if port
['name'] == 'external_port':
5334 port
['type'] = "External"
5336 net
['sdn_network_id'] = sdn_network_id
5337 net
['sdn_attached_ports'] = port_list
5339 elif item
=="tenants":
5340 content
= myvim
.get_tenant_list(filter_dict
=filter_dict
)
5341 elif item
== "images":
5343 content
= myvim
.get_image_list(filter_dict
=filter_dict
)
5345 raise NfvoException(item
+ "?", httperrors
.Method_Not_Allowed
)
5346 logger
.debug("vim_action response %s", content
) #update nets Change from VIM format to NFVO format
5347 if name
and len(content
)==1:
5348 return {item
[:-1]: content
[0]}
5349 elif name
and len(content
)==0:
5350 raise NfvoException("No {} found with ".format(item
[:-1]) + " and ".join(map(lambda x
: str(x
[0])+": "+str(x
[1]), filter_dict
.iteritems())),
5353 return {item
: content
}
5354 except vimconn
.vimconnException
as e
:
5355 print "vim_action Not possible to get_%s_list from VIM: %s " % (item
, str(e
))
5356 raise NfvoException("Not possible to get_{}_list from VIM: {}".format(item
, str(e
)), e
.http_code
)
5359 def vim_action_delete(mydb
, tenant_id
, datacenter
, item
, name
):
5360 #get datacenter info
5361 if tenant_id
== "any":
5364 datacenter_id
, myvim
= get_datacenter_by_name_uuid(mydb
, tenant_id
, datacenter
)
5366 content
= vim_action_get(mydb
, tenant_id
, datacenter
, item
, name
)
5367 logger
.debug("vim_action_delete vim response: " + str(content
))
5368 items
= content
.values()[0]
5369 if type(items
)==list and len(items
)==0:
5370 raise NfvoException("Not found " + item
, httperrors
.Not_Found
)
5371 elif type(items
)==list and len(items
)>1:
5372 raise NfvoException("Found more than one {} with this name. Use uuid.".format(item
), httperrors
.Not_Found
)
5373 else: # it is a dict
5374 item_id
= items
["id"]
5375 item_name
= str(items
.get("name"))
5378 if item
=="networks":
5379 # If there is a SDN network associated to the vim-network, proceed to clear the relationship and delete it
5380 sdn_network_id
= get_sdn_net_id(mydb
, tenant_id
, datacenter
, item_id
)
5381 if sdn_network_id
!= None:
5382 #Delete any port attachment to this network
5384 port_list
= ovim
.get_ports(columns
={'uuid'}, filter={'net_id': sdn_network_id
})
5385 except ovimException
as e
:
5386 raise NfvoException(
5387 "ovimException obtaining external ports for net {}. ".format(network_id
) + str(e
),
5388 httperrors
.Internal_Server_Error
)
5390 # By calling one by one all ports to be detached we ensure that not only the external_ports get detached
5391 for port
in port_list
:
5392 vim_net_sdn_detach(mydb
, tenant_id
, datacenter
, item_id
, port
['uuid'])
5394 #Delete from 'instance_nets' the correspondence between the vim-net-id and the sdn-net-id
5396 mydb
.delete_row(FROM
='instance_nets', WHERE
={'instance_scenario_id': None, 'sdn_net_id': sdn_network_id
, 'vim_net_id': item_id
})
5397 except db_base_Exception
as e
:
5398 raise NfvoException("Error deleting correspondence for VIM/SDN dataplane networks{}: ".format(correspondence
) +
5399 str(e
), e
.http_code
)
5401 #Delete the SDN network
5403 ovim
.delete_network(sdn_network_id
)
5404 except ovimException
as e
:
5405 logger
.error("ovimException deleting SDN network={} ".format(sdn_network_id
) + str(e
), exc_info
=True)
5406 raise NfvoException("ovimException deleting SDN network={} ".format(sdn_network_id
) + str(e
),
5407 httperrors
.Internal_Server_Error
)
5409 content
= myvim
.delete_network(item_id
)
5410 elif item
=="tenants":
5411 content
= myvim
.delete_tenant(item_id
)
5412 elif item
== "images":
5413 content
= myvim
.delete_image(item_id
)
5415 raise NfvoException(item
+ "?", httperrors
.Method_Not_Allowed
)
5416 except vimconn
.vimconnException
as e
:
5417 #logger.error( "vim_action Not possible to delete_{} {}from VIM: {} ".format(item, name, str(e)))
5418 raise NfvoException("Not possible to delete_{} {} from VIM: {}".format(item
, name
, str(e
)), e
.http_code
)
5420 return "{} {} {} deleted".format(item
[:-1], item_id
,item_name
)
5423 def vim_action_create(mydb
, tenant_id
, datacenter
, item
, descriptor
):
5424 #get datacenter info
5425 logger
.debug("vim_action_create descriptor %s", str(descriptor
))
5426 if tenant_id
== "any":
5428 datacenter_id
, myvim
= get_datacenter_by_name_uuid(mydb
, tenant_id
, datacenter
)
5430 if item
=="networks":
5431 net
= descriptor
["network"]
5432 net_name
= net
.pop("name")
5433 net_type
= net
.pop("type", "bridge")
5434 net_public
= net
.pop("shared", False)
5435 net_ipprofile
= net
.pop("ip_profile", None)
5436 net_vlan
= net
.pop("vlan", None)
5437 content
= myvim
.new_network(net_name
, net_type
, net_ipprofile
, shared
=net_public
, vlan
=net_vlan
) #, **net)
5439 #If the datacenter has a SDN controller defined and the network is of dataplane type, then create the sdn network
5440 if get_sdn_controller_id(mydb
, datacenter
) != None and (net_type
== 'data' or net_type
== 'ptp'):
5441 #obtain datacenter_tenant_id
5442 datacenter_tenant_id
= mydb
.get_rows(SELECT
=('uuid',),
5443 FROM
='datacenter_tenants',
5444 WHERE
={'datacenter_id': datacenter
})[0]['uuid']
5447 sdn_network
['vlan'] = net_vlan
5448 sdn_network
['type'] = net_type
5449 sdn_network
['name'] = net_name
5450 sdn_network
['region'] = datacenter_tenant_id
5451 ovim_content
= ovim
.new_network(sdn_network
)
5452 except ovimException
as e
:
5453 logger
.error("ovimException creating SDN network={} ".format(
5454 sdn_network
) + str(e
), exc_info
=True)
5455 raise NfvoException("ovimException creating SDN network={} ".format(sdn_network
) + str(e
),
5456 httperrors
.Internal_Server_Error
)
5458 # Save entry in in dabase mano_db in table instance_nets to stablish a dictionary vim_net_id <->sdn_net_id
5459 # use instance_scenario_id=None to distinguish from real instaces of nets
5460 correspondence
= {'instance_scenario_id': None,
5461 'sdn_net_id': ovim_content
,
5462 'vim_net_id': content
,
5463 'datacenter_tenant_id': datacenter_tenant_id
5466 mydb
.new_row('instance_nets', correspondence
, add_uuid
=True)
5467 except db_base_Exception
as e
:
5468 raise NfvoException("Error saving correspondence for VIM/SDN dataplane networks{}: {}".format(
5469 correspondence
, e
), e
.http_code
)
5470 elif item
=="tenants":
5471 tenant
= descriptor
["tenant"]
5472 content
= myvim
.new_tenant(tenant
["name"], tenant
.get("description"))
5474 raise NfvoException(item
+ "?", httperrors
.Method_Not_Allowed
)
5475 except vimconn
.vimconnException
as e
:
5476 raise NfvoException("Not possible to create {} at VIM: {}".format(item
, str(e
)), e
.http_code
)
5478 return vim_action_get(mydb
, tenant_id
, datacenter
, item
, content
)
5480 def sdn_controller_create(mydb
, tenant_id
, sdn_controller
):
5481 data
= ovim
.new_of_controller(sdn_controller
)
5482 logger
.debug('New SDN controller created with uuid {}'.format(data
))
5485 def sdn_controller_update(mydb
, tenant_id
, controller_id
, sdn_controller
):
5486 data
= ovim
.edit_of_controller(controller_id
, sdn_controller
)
5487 msg
= 'SDN controller {} updated'.format(data
)
5491 def sdn_controller_list(mydb
, tenant_id
, controller_id
=None):
5492 if controller_id
== None:
5493 data
= ovim
.get_of_controllers()
5495 data
= ovim
.show_of_controller(controller_id
)
5497 msg
= 'SDN controller list:\n {}'.format(data
)
5501 def sdn_controller_delete(mydb
, tenant_id
, controller_id
):
5502 select_
= ('uuid', 'config')
5503 datacenters
= mydb
.get_rows(FROM
='datacenters', SELECT
=select_
)
5504 for datacenter
in datacenters
:
5505 if datacenter
['config']:
5506 config
= yaml
.load(datacenter
['config'])
5507 if 'sdn-controller' in config
and config
['sdn-controller'] == controller_id
:
5508 raise NfvoException("SDN controller {} is in use by datacenter {}".format(controller_id
, datacenter
['uuid']), httperrors
.Conflict
)
5510 data
= ovim
.delete_of_controller(controller_id
)
5511 msg
= 'SDN controller {} deleted'.format(data
)
5515 def datacenter_sdn_port_mapping_set(mydb
, tenant_id
, datacenter_id
, sdn_port_mapping
):
5516 controller
= mydb
.get_rows(FROM
="datacenters", SELECT
=("config",), WHERE
={"uuid":datacenter_id
})
5517 if len(controller
) < 1:
5518 raise NfvoException("Datacenter {} not present in the database".format(datacenter_id
), httperrors
.Not_Found
)
5521 sdn_controller_id
= yaml
.load(controller
[0]["config"])["sdn-controller"]
5523 raise NfvoException("The datacenter {} has not an SDN controller associated".format(datacenter_id
), httperrors
.Bad_Request
)
5525 sdn_controller
= ovim
.show_of_controller(sdn_controller_id
)
5526 switch_dpid
= sdn_controller
["dpid"]
5529 for compute_node
in sdn_port_mapping
:
5530 #element = {"ofc_id": sdn_controller_id, "region": datacenter_id, "switch_dpid": switch_dpid}
5532 element
["compute_node"] = compute_node
["compute_node"]
5533 for port
in compute_node
["ports"]:
5534 pci
= port
.get("pci")
5535 element
["switch_port"] = port
.get("switch_port")
5536 element
["switch_mac"] = port
.get("switch_mac")
5537 if not pci
or not (element
["switch_port"] or element
["switch_mac"]):
5538 raise NfvoException ("The mapping must contain the 'pci' and at least one of the elements 'switch_port'"
5539 " or 'switch_mac'", httperrors
.Bad_Request
)
5540 for pci_expanded
in utils
.expand_brackets(pci
):
5541 element
["pci"] = pci_expanded
5542 maps
.append(dict(element
))
5544 return ovim
.set_of_port_mapping(maps
, ofc_id
=sdn_controller_id
, switch_dpid
=switch_dpid
, region
=datacenter_id
)
5546 def datacenter_sdn_port_mapping_list(mydb
, tenant_id
, datacenter_id
):
5547 maps
= ovim
.get_of_port_mappings(db_filter
={"region": datacenter_id
})
5550 "sdn-controller": None,
5551 "datacenter-id": datacenter_id
,
5553 "ports_mapping": list()
5556 datacenter
= mydb
.get_table_by_uuid_name('datacenters', datacenter_id
)
5557 if datacenter
['config']:
5558 config
= yaml
.load(datacenter
['config'])
5559 if 'sdn-controller' in config
:
5560 controller_id
= config
['sdn-controller']
5561 sdn_controller
= sdn_controller_list(mydb
, tenant_id
, controller_id
)
5562 result
["sdn-controller"] = controller_id
5563 result
["dpid"] = sdn_controller
["dpid"]
5565 if result
["sdn-controller"] == None:
5566 raise NfvoException("SDN controller is not defined for datacenter {}".format(datacenter_id
), httperrors
.Bad_Request
)
5567 if result
["dpid"] == None:
5568 raise NfvoException("It was not possible to determine DPID for SDN controller {}".format(result
["sdn-controller"]),
5569 httperrors
.Internal_Server_Error
)
5574 ports_correspondence_dict
= dict()
5576 if result
["sdn-controller"] != link
["ofc_id"]:
5577 raise NfvoException("The sdn-controller specified for different port mappings differ", httperrors
.Internal_Server_Error
)
5578 if result
["dpid"] != link
["switch_dpid"]:
5579 raise NfvoException("The dpid specified for different port mappings differ", httperrors
.Internal_Server_Error
)
5581 element
["pci"] = link
["pci"]
5582 if link
["switch_port"]:
5583 element
["switch_port"] = link
["switch_port"]
5584 if link
["switch_mac"]:
5585 element
["switch_mac"] = link
["switch_mac"]
5587 if not link
["compute_node"] in ports_correspondence_dict
:
5589 content
["compute_node"] = link
["compute_node"]
5590 content
["ports"] = list()
5591 ports_correspondence_dict
[link
["compute_node"]] = content
5593 ports_correspondence_dict
[link
["compute_node"]]["ports"].append(element
)
5595 for key
in sorted(ports_correspondence_dict
):
5596 result
["ports_mapping"].append(ports_correspondence_dict
[key
])
5600 def datacenter_sdn_port_mapping_delete(mydb
, tenant_id
, datacenter_id
):
5601 return ovim
.clear_of_port_mapping(db_filter
={"region":datacenter_id
})
5603 def create_RO_keypair(tenant_id
):
5605 Creates a public / private keys for a RO tenant and returns their values
5607 tenant_id: ID of the tenant
5609 public_key: Public key for the RO tenant
5610 private_key: Encrypted private key for RO tenant
5614 key
= RSA
.generate(bits
)
5616 public_key
= key
.publickey().exportKey('OpenSSH')
5617 if isinstance(public_key
, ValueError):
5618 raise NfvoException("Unable to create public key: {}".format(public_key
), httperrors
.Internal_Server_Error
)
5619 private_key
= key
.exportKey(passphrase
=tenant_id
, pkcs
=8)
5620 except (ValueError, NameError) as e
:
5621 raise NfvoException("Unable to create private key: {}".format(e
), httperrors
.Internal_Server_Error
)
5622 return public_key
, private_key
5624 def decrypt_key (key
, tenant_id
):
5626 Decrypts an encrypted RSA key
5628 key: Private key to be decrypted
5629 tenant_id: ID of the tenant
5631 unencrypted_key: Unencrypted private key for RO tenant
5634 key
= RSA
.importKey(key
,tenant_id
)
5635 unencrypted_key
= key
.exportKey('PEM')
5636 if isinstance(unencrypted_key
, ValueError):
5637 raise NfvoException("Unable to decrypt the private key: {}".format(unencrypted_key
), httperrors
.Internal_Server_Error
)
5638 except ValueError as e
:
5639 raise NfvoException("Unable to decrypt the private key: {}".format(e
), httperrors
.Internal_Server_Error
)
5640 return unencrypted_key